1- name : Deploy to AWS Lambda
1+ name : Build and Deploy to Lambda
22
33on :
4- workflow_call :
5- inputs :
6- environment :
7- description : ' Environment to deploy to'
8- required : true
9- type : string
10- default : ' staging'
11- aws-region :
12- description : ' AWS region'
13- required : false
14- type : string
15- default : ' us-east-1'
16- expire-days :
17- description : ' Days before pastes expire'
18- required : false
19- type : number
20- default : 7
21- secrets :
22- AWS_ACCESS_KEY_ID :
23- required : true
24- AWS_SECRET_ACCESS_KEY :
25- required : true
26- AWS_ACCOUNT_ID :
27- required : true
28- outputs :
29- api_url :
30- description : " Deployed API URL"
31- value : ${{ jobs.deploy.outputs.api_url }}
32- function_name :
33- description : " Lambda function name"
34- value : ${{ jobs.deploy.outputs.function_name }}
35-
364 workflow_dispatch :
375 inputs :
38- environment :
39- description : ' Environment to deploy to'
40- required : true
41- type : choice
42- options :
43- - staging
44- - production
45- default : ' staging'
46- aws-region :
47- description : ' AWS region'
48- required : false
49- type : string
50- default : ' us-east-1'
51- expire-days :
52- description : ' Days before pastes expire'
6+ function_name :
7+ description : " Override Lambda function name (optional). If empty, uses LAMBDA_FUNCTION_NAME environment variable."
538 required : false
54- type : number
55- default : 7
56-
9+ default : " "
5710 push :
5811 branches :
5912 - ' deploy/lambda'
6013
61- permissions :
62- contents : read
63- id-token : write
64-
6514jobs :
66- security :
67- name : Security Scan
15+ deploy-lambda :
6816 runs-on : ubuntu-latest
17+ permissions :
18+ contents : read
19+ env :
20+ GOOS : linux
21+ GOARCH : arm64
22+ CGO_ENABLED : 0
6923 steps :
70- - name : Checkout code
71- uses : actions/checkout@v4
72-
73- - name : Run Trivy vulnerability scanner
74- uses : aquasecurity/trivy-action@master
75- with :
76- scan-type : ' fs'
77- scan-ref : ' .'
78- format : ' sarif'
79- output : ' trivy-results.sarif'
80-
81- - name : Upload Trivy scan results to GitHub Security tab
82- uses : github/codeql-action/upload-sarif@v3
83- if : always()
84- with :
85- sarif_file : ' trivy-results.sarif'
86-
87- build :
88- name : Build Lambda Package
89- runs-on : ubuntu-latest
90- needs : security
91- steps :
92- - name : Checkout code
24+ - name : Checkout
9325 uses : actions/checkout@v4
9426
9527 - name : Set up Go
9628 uses : actions/setup-go@v5
9729 with :
9830 go-version-file : ' go.mod'
99- cache : true
10031
101- - name : Build Lambda binary
102- run : |
103- # Build for AWS Lambda AL2023 runtime
104- GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build \
105- -ldflags="-s -w" \
106- -o dist/bootstrap \
107- .
32+ - name : Download deps
33+ run : go mod download
10834
109- - name : Create deployment package
35+ - name : Build Lambda bootstrap
11036 run : |
111- cd dist
112- zip lambda.zip bootstrap
113- rm bootstrap
114-
115- - name : Upload Lambda package
116- uses : actions/upload-artifact@v4
117- with :
118- name : lambda-package
119- path : dist/lambda.zip
120- retention-days : 1
37+ go build \
38+ -ldflags "-X main.buildTime=$(date --utc +%Y-%m-%dT%H:%M:%SZ) -X main.commitHash=${{ github.sha }} -X main.version=${{ github.ref_name }}" \
39+ -tags netgo -trimpath \
40+ -o ./bootstrap ./...
12141
122- deploy :
123- name : Deploy to AWS Lambda
124- runs-on : ubuntu-latest
125- needs : [security, build]
126- environment : ${{ inputs.environment }}
127- outputs :
128- api_url : ${{ steps.outputs.outputs.api_url }}
129- function_name : ${{ steps.outputs.outputs.function_name }}
130- stack_name : ${{ steps.outputs.outputs.stack_name }}
131- steps :
132- - name : Checkout code
133- uses : actions/checkout@v4
42+ - name : Prepare code artifacts
43+ run : |
44+ mkdir -p lambda-artifacts
45+ mv -f bootstrap lambda-artifacts/bootstrap
46+ cp -r static lambda-artifacts/static
47+ ls -l lambda-artifacts
13448
13549 - name : Configure AWS credentials
13650 uses : aws-actions/configure-aws-credentials@v4
13751 with :
138- aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }}
139- aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }}
140- aws-region : ${{ inputs.aws-region }}
141-
142- - name : Install SAM CLI
143- uses : aws-actions/setup-sam@v2
144- with :
145- use-installer : true
146-
147- - name : Download Lambda package
148- uses : actions/download-artifact@v4
149- with :
150- name : lambda-package
151- path : dist/
152-
153- - name : Deploy with SAM
154- env :
155- AWS_DEFAULT_REGION : ${{ inputs.aws-region }}
52+ aws-region : ${{ secrets.AWS_REGION }}
53+ audience : ${{ secrets.AWS_AUDIENCE }}
54+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
55+ # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_DEPLOY_LAMBDA }}
56+ # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_DEPLOY_LAMBDA }}
57+
58+ - name : Resolve Lambda function name
59+ id : resolve-fn
15660 run : |
157- cd deploy/aws
158-
159- # Deploy with SAM CLI using the CloudFormation template
160- sam deploy \
161- --template-file template.yml \
162- --stack-name "nclip-${{ inputs.environment }}" \
163- --region "${{ inputs.aws-region }}" \
164- --capabilities CAPABILITY_IAM \
165- --parameter-overrides \
166- Environment="${{ inputs.environment }}" \
167- ExpireDays="${{ inputs.expire-days }}" \
168- --no-fail-on-empty-changeset \
169- --tags \
170- Environment="${{ inputs.environment }}" \
171- Repository="${{ github.repository }}" \
172- Commit="${{ github.sha }}"
173-
174- - name : Get deployment outputs
175- id : outputs
176- run : |
177- STACK_NAME="nclip-${{ inputs.environment }}"
178-
179- # Get API URL from CloudFormation outputs
180- API_URL=$(aws cloudformation describe-stacks \
181- --stack-name "$STACK_NAME" \
182- --region "${{ inputs.aws-region }}" \
183- --query "Stacks[0].Outputs[?OutputKey=='ApiUrl'].OutputValue" \
184- --output text)
185-
186- # Get Function Name
187- FUNCTION_NAME=$(aws cloudformation describe-stacks \
188- --stack-name "$STACK_NAME" \
189- --region "${{ inputs.aws-region }}" \
190- --query "Stacks[0].Outputs[?OutputKey=='FunctionName'].OutputValue" \
191- --output text)
192-
193- echo "api_url=$API_URL" >> $GITHUB_OUTPUT
194- echo "function_name=$FUNCTION_NAME" >> $GITHUB_OUTPUT
195- echo "stack_name=$STACK_NAME" >> $GITHUB_OUTPUT
196-
197- - name : Test deployment
198- env :
199- API_URL : ${{ steps.outputs.outputs.api_url }}
200- run : |
201- # Wait for API to be ready
202- sleep 30
203-
204- # Test health endpoint
205- echo "Testing health endpoint..."
206- if curl -f -s "${API_URL}/health" > /dev/null; then
207- echo "✅ Health check passed"
208- else
209- echo "❌ Health check failed"
210- exit 1
61+ FN_IN="${{ inputs.function_name }}"
62+ if [ -n "${FN_IN}" ]; then
63+ echo "Using function name from manual input: ${FN_IN}"
64+ echo "name=${FN_IN}" >> "$GITHUB_OUTPUT"
65+ exit 0
21166 fi
212-
213- # Test paste creation and retrieval
214- echo "Testing paste functionality..."
215- TEST_DATA="Integration test from GitHub Actions $(date)"
216-
217- # Create paste
218- PASTE_RESPONSE=$(curl -s -X POST "${API_URL}" -d "$TEST_DATA")
219- PASTE_ID=$(echo "$PASTE_RESPONSE" | jq -r '.id // empty')
220-
221- if [[ -n "$PASTE_ID" ]]; then
222- echo "✅ Paste created with ID: $PASTE_ID"
223-
224- # Retrieve paste
225- RETRIEVED_DATA=$(curl -s "${API_URL}/${PASTE_ID}")
226-
227- if [[ "$RETRIEVED_DATA" == "$TEST_DATA" ]]; then
228- echo "✅ Paste retrieval test passed"
229- else
230- echo "❌ Paste retrieval test failed"
231- echo "Expected: $TEST_DATA"
232- echo "Got: $RETRIEVED_DATA"
233- exit 1
234- fi
235- else
236- echo "❌ Paste creation failed"
237- echo "Response: $PASTE_RESPONSE"
67+ if [ -z "${{ vars.LAMBDA_FUNCTION_NAME }}" ]; then
68+ echo "LAMBDA_FUNCTION_NAME variable is required when no manual input is provided" >&2
23869 exit 1
23970 fi
71+ echo "Using function name from secret"
72+ echo "name=${{ vars.LAMBDA_FUNCTION_NAME }}" >> "$GITHUB_OUTPUT"
24073
241- notify :
242- name : Notify Deployment
243- runs-on : ubuntu-latest
244- needs : deploy
245- if : always()
246- steps :
247- - name : Deployment Summary
74+ - name : Deploy Lambda Function
75+ id : lambda-deploy
76+ uses : aws-actions/aws-lambda-deploy@v1
77+ with :
78+ function-name : ${{ steps.resolve-fn.outputs.name }}
79+ code-artifacts-dir : lambda-artifacts
80+ architectures : amd64
81+ runtime : provided.al2023
82+ handler : bootstrap
83+ publish : true
84+ role : ${{ secrets.LAMBDA_EXECUTION_ROLE }}
85+ # s3-bucket: "${{ vars.BUCKET }}"
86+ environment : ' {"NCLIP_DYNAMODB_TABLE":"${{ vars.NCLIP_DYNAMODB_TABLE }}","GIN_MODE":"release"}'
87+
88+ - name : Post-deploy info
24889 run : |
249- echo "## 🚀 AWS Lambda Deployment Summary" >> $GITHUB_STEP_SUMMARY
250- echo "" >> $GITHUB_STEP_SUMMARY
251- echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
252- echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
253- echo "| Environment | ${{ inputs.environment }} |" >> $GITHUB_STEP_SUMMARY
254- echo "| Region | ${{ inputs.aws-region }} |" >> $GITHUB_STEP_SUMMARY
255- echo "| Status | ${{ needs.deploy.result == 'success' && '✅ Success' || '❌ Failed' }} |" >> $GITHUB_STEP_SUMMARY
256-
257- if [[ "${{ needs.deploy.result }}" == "success" ]]; then
258- echo "| API URL | ${{ needs.deploy.outputs.api_url }} |" >> $GITHUB_STEP_SUMMARY
259- echo "| Function | ${{ needs.deploy.outputs.function_name }} |" >> $GITHUB_STEP_SUMMARY
260- echo "| Stack | ${{ needs.deploy.outputs.stack_name }} |" >> $GITHUB_STEP_SUMMARY
261- echo "" >> $GITHUB_STEP_SUMMARY
262- echo "### 🧪 Test the deployment:" >> $GITHUB_STEP_SUMMARY
263- echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
264- echo "# Create a paste" >> $GITHUB_STEP_SUMMARY
265- echo "curl -X POST ${{ needs.deploy.outputs.api_url }} -d 'Hello from AWS Lambda!'" >> $GITHUB_STEP_SUMMARY
266- echo "" >> $GITHUB_STEP_SUMMARY
267- echo "# Retrieve a paste" >> $GITHUB_STEP_SUMMARY
268- echo "curl ${{ needs.deploy.outputs.api_url }}/\$(echo 'test' | curl -s -X POST ${{ needs.deploy.outputs.api_url }} -d @-)" >> $GITHUB_STEP_SUMMARY
269- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
270- fi
90+ echo "Function ARN: ${{ steps.lambda-deploy.outputs.function-arn }}"
91+ echo "Version: ${{ steps.lambda-deploy.outputs.version }}"
0 commit comments