ci: add CI/CD pipeline via OpsTools #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI/CD Pipeline - Node.js API to AWS ECS | ||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
| - develop | ||
| pull_request: | ||
| branches: | ||
| - main | ||
| - develop | ||
| env: | ||
| AWS_REGION: us-east-1 | ||
| ECR_REPOSITORY: node-api | ||
| ECS_SERVICE: node-api-service | ||
| ECS_CLUSTER: node-api-cluster | ||
| ECS_TASK_DEFINITION: node-api-task | ||
| permissions: | ||
| contents: read | ||
| id-token: write | ||
| jobs: | ||
| lint-and-test: | ||
| runs-on: ubuntu-22.04 | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4.1.1 | ||
| - name: Setup Node.js | ||
| uses: actions/setup-node@v4.0.2 | ||
| with: | ||
| node-version: '18.x' | ||
| cache: 'npm' | ||
| - name: Install dependencies | ||
| run: npm ci | ||
| - name: Run linter | ||
| run: npm run lint | ||
| - name: Run tests | ||
| run: npm run test | ||
| - name: Generate coverage report | ||
| run: npm run test:coverage | ||
| continue-on-error: true | ||
| - name: Upload coverage to Codecov | ||
| uses: codecov/codecov-action@v3.1.5 | ||
| with: | ||
| files: ./coverage/coverage-final.json | ||
| flags: unittests | ||
| fail_ci_if_error: false | ||
| build-and-push: | ||
| needs: lint-and-test | ||
| runs-on: ubuntu-22.04 | ||
| if: github.event_name == 'push' | ||
| outputs: | ||
| image-uri: ${{ steps.image.outputs.image-uri }} | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4.1.1 | ||
| - name: Configure AWS credentials | ||
| uses: aws-actions/configure-aws-credentials@v4.0.2 | ||
| with: | ||
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | ||
| aws-region: ${{ env.AWS_REGION }} | ||
| - name: Login to Amazon ECR | ||
| id: login-ecr | ||
| uses: aws-actions/amazon-ecr-login@v2.0.1 | ||
| - name: Build Docker image | ||
| id: docker-build | ||
| env: | ||
| REGISTRY: ${{ steps.login-ecr.outputs.registry }} | ||
| IMAGE_TAG: ${{ github.sha }} | ||
| run: | | ||
| docker build -t $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG . | ||
| docker tag $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $REGISTRY/$ECR_REPOSITORY:latest | ||
| - name: Push image to Amazon ECR | ||
| id: image | ||
| env: | ||
| REGISTRY: ${{ steps.login-ecr.outputs.registry }} | ||
| IMAGE_TAG: ${{ github.sha }} | ||
| run: | | ||
| docker push $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG | ||
| docker push $REGISTRY/$ECR_REPOSITORY:latest | ||
| echo "image-uri=$REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT | ||
| - name: Create image definitions JSON | ||
| env: | ||
| REGISTRY: ${{ steps.login-ecr.outputs.registry }} | ||
| IMAGE_TAG: ${{ github.sha }} | ||
| run: | | ||
| printf '[{"name":"%s","imageUri":"%s"}]' $ECS_TASK_DEFINITION $REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG > image-definitions.json | ||
| - name: Upload image definitions | ||
| uses: actions/upload-artifact@v4.3.1 | ||
| with: | ||
| name: image-definitions | ||
| path: image-definitions.json | ||
| retention-days: 1 | ||
| deploy-staging: | ||
| needs: build-and-push | ||
| runs-on: ubuntu-22.04 | ||
| if: github.ref == 'refs/heads/develop' && github.event_name == 'push' | ||
| environment: | ||
| name: staging | ||
| url: https://staging-api.example.com | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4.1.1 | ||
| - name: Download image definitions | ||
| uses: actions/download-artifact@v4.1.0 | ||
| with: | ||
| name: image-definitions | ||
| - name: Configure AWS credentials | ||
| uses: aws-actions/configure-aws-credentials@v4.0.2 | ||
| with: | ||
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | ||
| aws-region: ${{ env.AWS_REGION }} | ||
| - name: Get current task definition | ||
| run: | | ||
| aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION --query taskDefinition > task-definition.json | ||
| - name: Update ECS task definition | ||
| id: task-def | ||
| uses: aws-actions/amazon-ecs-render-task-definition@v1.2.0 | ||
| with: | ||
| task-definition: task-definition.json | ||
| container-name: ${{ env.ECS_TASK_DEFINITION }} | ||
| image: ${{ needs.build-and-push.outputs.image-uri }} | ||
| - name: Register new task definition | ||
| uses: aws-actions/amazon-ecs-register-task-definition@v1.3.0 | ||
| with: | ||
| task-definition: ${{ steps.task-def.outputs.task-definition }} | ||
| - name: Deploy to ECS (Staging) | ||
| uses: aws-actions/amazon-ecs-deploy-task-definition@v1.4.11 | ||
| with: | ||
| service: ${{ env.ECS_SERVICE }}-staging | ||
| cluster: ${{ env.ECS_CLUSTER }}-staging | ||
| task-definition: ${{ steps.task-def.outputs.task-definition }} | ||
| wait-for-service-stability: true | ||
| deploy-production: | ||
| needs: build-and-push | ||
| runs-on: ubuntu-22.04 | ||
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | ||
| environment: | ||
| name: production | ||
| url: https://api.example.com | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4.1.1 | ||
| - name: Download image definitions | ||
| uses: actions/download-artifact@v4.1.0 | ||
| with: | ||
| name: image-definitions | ||
| - name: Configure AWS credentials | ||
| uses: aws-actions/configure-aws-credentials@v4.0.2 | ||
| with: | ||
| role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} | ||
| aws-region: ${{ env.AWS_REGION }} | ||
| - name: Get current task definition | ||
| run: | | ||
| aws ecs describe-task-definition --task-definition $ECS_TASK_DEFINITION --query taskDefinition > task-definition.json | ||
| - name: Update ECS task definition | ||
| id: task-def | ||
| uses: aws-actions/amazon-ecs-render-task-definition@v1.2.0 | ||
| with: | ||
| task-definition: task-definition.json | ||
| container-name: ${{ env.ECS_TASK_DEFINITION }} | ||
| image: ${{ needs.build-and-push.outputs.image-uri }} | ||
| - name: Register new task definition | ||
| uses: aws-actions/amazon-ecs-register-task-definition@v1.3.0 | ||
| with: | ||
| task-definition: ${{ steps.task-def.outputs.task-definition }} | ||
| - name: Deploy to ECS (Production) | ||
| uses: aws-actions/amazon-ecs-deploy-task-definition@v1.4.11 | ||
| with: | ||
| service: ${{ env.ECS_SERVICE }} | ||
| cluster: ${{ env.ECS_CLUSTER }} | ||
| task-definition: ${{ steps.task-def.outputs.task-definition }} | ||
| wait-for-service-stability: true | ||
| terraform-plan: | ||
| runs-on: ubuntu-22.04 | ||
| if: github.event_name == 'pull_request' | ||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4.1.1 | ||
| - name: Configure AWS credentials | ||
| uses: aws-actions/configure-aws-credentials@v4.0.2 | ||
| with: | ||
| role-to-assume: ${{ secrets.AWS_ROLE | ||