1+ name : CI/CD Pipeline - Node.js API to AWS ECS
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+ - develop
8+ pull_request :
9+ branches :
10+ - main
11+ - develop
12+
13+ env :
14+ AWS_REGION : us-east-1
15+ ECR_REPOSITORY : node-api
16+ ECS_SERVICE : node-api-service
17+ ECS_CLUSTER : node-api-cluster
18+ ECS_TASK_DEFINITION : node-api-task
19+
20+ permissions :
21+ contents : read
22+ id-token : write
23+
24+ jobs :
25+ lint-and-test :
26+ runs-on : ubuntu-22.04
27+ steps :
28+ - name : Checkout code
29+ uses : actions/checkout@v4.1.1
30+
31+ - name : Setup Node.js
32+ uses : actions/setup-node@v4.0.2
33+ with :
34+ node-version : ' 18.x'
35+ cache : ' npm'
36+
37+ - name : Install dependencies
38+ run : npm ci
39+
40+ - name : Run linter
41+ run : npm run lint
42+
43+ - name : Run tests
44+ run : npm run test
45+
46+ - name : Generate coverage report
47+ run : npm run test:coverage
48+ continue-on-error : true
49+
50+ - name : Upload coverage to Codecov
51+ uses : codecov/codecov-action@v3.1.5
52+ with :
53+ files : ./coverage/coverage-final.json
54+ flags : unittests
55+ fail_ci_if_error : false
56+
57+ build-and-push :
58+ needs : lint-and-test
59+ runs-on : ubuntu-22.04
60+ if : github.event_name == 'push'
61+ outputs :
62+ image-uri : ${{ steps.image.outputs.image-uri }}
63+ steps :
64+ - name : Checkout code
65+ uses : actions/checkout@v4.1.1
66+
67+ - name : Configure AWS credentials
68+ uses : aws-actions/configure-aws-credentials@v4.0.2
69+ with :
70+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
71+ aws-region : ${{ env.AWS_REGION }}
72+
73+ - name : Login to Amazon ECR
74+ id : login-ecr
75+ uses : aws-actions/amazon-ecr-login@v2.0.1
76+
77+ - name : Build Docker image
78+ id : docker-build
79+ env :
80+ REGISTRY : ${{ steps.login-ecr.outputs.registry }}
81+ IMAGE_TAG : ${{ github.sha }}
82+ run : |
83+ docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
84+ docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $REGISTRY/$ECR_REPOSITORY:latest
85+
86+ - name : Push image to Amazon ECR
87+ id : image
88+ env :
89+ REGISTRY : ${{ steps.login-ecr.outputs.registry }}
90+ IMAGE_TAG : ${{ github.sha }}
91+ run : |
92+ docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
93+ docker push $REGISTRY/$ECR_REPOSITORY:latest
94+ echo "image-uri=$REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
95+
96+ - name : Create image definitions JSON
97+ env :
98+ REGISTRY : ${{ steps.login-ecr.outputs.registry }}
99+ IMAGE_TAG : ${{ github.sha }}
100+ run : |
101+ printf '[{"name":"%s","imageUri":"%s"}]' $ECS_TASK_DEFINITION $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG > image-definitions.json
102+
103+ - name : Upload image definitions
104+ uses : actions/upload-artifact@v4.3.1
105+ with :
106+ name : image-definitions
107+ path : image-definitions.json
108+ retention-days : 1
109+
110+ deploy-staging :
111+ needs : build-and-push
112+ runs-on : ubuntu-22.04
113+ if : github.ref == 'refs/heads/develop' && github.event_name == 'push'
114+ environment :
115+ name : staging
116+ url : https://staging-api.example.com
117+ steps :
118+ - name : Checkout code
119+ uses : actions/checkout@v4.1.1
120+
121+ - name : Download image definitions
122+ uses : actions/download-artifact@v4.1.0
123+ with :
124+ name : image-definitions
125+
126+ - name : Configure AWS credentials
127+ uses : aws-actions/configure-aws-credentials@v4.0.2
128+ with :
129+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
130+ aws-region : ${{ env.AWS_REGION }}
131+
132+ - name : Get current task definition
133+ run : |
134+ aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION --query taskDefinition > task-definition.json
135+
136+ - name : Update ECS task definition
137+ id : task-def
138+ uses : aws-actions/amazon-ecs-render-task-definition@v1.2.0
139+ with :
140+ task-definition : task-definition.json
141+ container-name : ${{ env.ECS_TASK_DEFINITION }}
142+ image : ${{ needs.build-and-push.outputs.image-uri }}
143+
144+ - name : Register new task definition
145+ uses : aws-actions/amazon-ecs-register-task-definition@v1.3.0
146+ with :
147+ task-definition : ${{ steps.task-def.outputs.task-definition }}
148+
149+ - name : Deploy to ECS (Staging)
150+ uses : aws-actions/amazon-ecs-deploy-task-definition@v1.4.11
151+ with :
152+ service : ${{ env.ECS_SERVICE }}-staging
153+ cluster : ${{ env.ECS_CLUSTER }}-staging
154+ task-definition : ${{ steps.task-def.outputs.task-definition }}
155+ wait-for-service-stability : true
156+
157+ deploy-production :
158+ needs : build-and-push
159+ runs-on : ubuntu-22.04
160+ if : github.ref == 'refs/heads/main' && github.event_name == 'push'
161+ environment :
162+ name : production
163+ url : https://api.example.com
164+ steps :
165+ - name : Checkout code
166+ uses : actions/checkout@v4.1.1
167+
168+ - name : Download image definitions
169+ uses : actions/download-artifact@v4.1.0
170+ with :
171+ name : image-definitions
172+
173+ - name : Configure AWS credentials
174+ uses : aws-actions/configure-aws-credentials@v4.0.2
175+ with :
176+ role-to-assume : ${{ secrets.AWS_ROLE_TO_ASSUME }}
177+ aws-region : ${{ env.AWS_REGION }}
178+
179+ - name : Get current task definition
180+ run : |
181+ aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION --query taskDefinition > task-definition.json
182+
183+ - name : Update ECS task definition
184+ id : task-def
185+ uses : aws-actions/amazon-ecs-render-task-definition@v1.2.0
186+ with :
187+ task-definition : task-definition.json
188+ container-name : ${{ env.ECS_TASK_DEFINITION }}
189+ image : ${{ needs.build-and-push.outputs.image-uri }}
190+
191+ - name : Register new task definition
192+ uses : aws-actions/amazon-ecs-register-task-definition@v1.3.0
193+ with :
194+ task-definition : ${{ steps.task-def.outputs.task-definition }}
195+
196+ - name : Deploy to ECS (Production)
197+ uses : aws-actions/amazon-ecs-deploy-task-definition@v1.4.11
198+ with :
199+ service : ${{ env.ECS_SERVICE }}
200+ cluster : ${{ env.ECS_CLUSTER }}
201+ task-definition : ${{ steps.task-def.outputs.task-definition }}
202+ wait-for-service-stability : true
203+
204+ terraform-plan :
205+ runs-on : ubuntu-22.04
206+ if : github.event_name == 'pull_request'
207+ steps :
208+ - name : Checkout code
209+ uses : actions/checkout@v4.1.1
210+
211+ - name : Configure AWS credentials
212+ uses : aws-actions/configure-aws-credentials@v4.0.2
213+ with :
214+ role-to-assume : ${{ secrets.AWS_ROLE
0 commit comments