From ccd3d929d807b61df94c8637e2bb5ca5dc57e75a Mon Sep 17 00:00:00 2001 From: McNaBry Date: Mon, 4 Nov 2024 00:39:54 +0800 Subject: [PATCH] Create GitHub Actions for auto deployment to AWS (#66) * Create github workflow to deploy frontend and backend to AWS * Add conditional trigger for backend workflow * The build is triggered for a specific service only if its files have been changes * Update frontend workflow * Remove trigger on pull request * Add conditional trigger based on frontend directory * Add cloudfront cache invalidation to frontend workflow Co-authored-by: samuelim01 <61283948+samuelim01@users.noreply.github.com> * Include collab in backend workflow * Add workflow scripts that can only be triggered manually for frontend and backend * Rename frontend force workflow * Change frontend and backend workflows to trigger only on production branch --------- Co-authored-by: samuelim01 <61283948+samuelim01@users.noreply.github.com> Co-authored-by: Samuel Lim --- .github/workflows/backend.yml | 64 ++++++++++++++++++++++++++++++++++ .github/workflows/frontend.yml | 44 +++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 .github/workflows/backend.yml create mode 100644 .github/workflows/frontend.yml diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml new file mode 100644 index 0000000000..703022bdea --- /dev/null +++ b/.github/workflows/backend.yml @@ -0,0 +1,64 @@ +name: Deploy Backend Services + +on: + push: + branches: [ 'production' ] + + workflow_dispatch: + +permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout + +env: + AWS_REGION: ap-southeast-1 + ECS_CLUSTER: backend-cluster + +jobs: + deploy: + name: Deploy Backend Service + runs-on: ubuntu-latest + environment: production + + strategy: + matrix: + service: [ 'question', 'user', 'match', 'collaboration' ] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Configure AWS credentials + id: aws-configure + uses: aws-actions/configure-aws-credentials@v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_BACKEND_ROLE }} + role-session-name: GitHub_to_AWS_via_FederatedOIDC + aws-region: ${{ env.AWS_REGION }} + + - name: Login to AWS ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2.0.1 + + - name: Build and push ${{ matrix.service }} image to AWS ECR + id: build-image + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + ECR_REPOSITORY: ${{ matrix.service }} + IMAGE_TAG: latest + run: | + echo "Building $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" + docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG ./services/${{ matrix.service }} + docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG + + - name: Update AWS Service (${{ matrix.service }}) # Trigger re-deployment with latest image + id: update-service + env: + ECS_SERVICE: ${{ matrix.service }}-service + run: | + echo "Updating $ECS_SERVICE for $ECS_CLUSTER" + aws ecs update-service \ + --cluster $ECS_CLUSTER \ + --service $ECS_SERVICE \ + --force-new-deployment \ + --region $AWS_REGION diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml new file mode 100644 index 0000000000..53adae7092 --- /dev/null +++ b/.github/workflows/frontend.yml @@ -0,0 +1,44 @@ +name: Deploy Frontend + +on: + push: + branches: [ 'production' ] + + workflow_dispatch: + +permissions: + id-token: write # This is required for requesting the JWT + contents: read # This is required for actions/checkout + +env: + AWS_REGION: ap-southeast-1 + S3_BUCKET_NAME: app.peerprep.org + +jobs: + deploy: + name: Deploy Frontend + runs-on: ubuntu-latest + environment: production + + steps: + - uses: actions/checkout@v4 + + - name: Configure AWS credentials + id: aws-configure + uses: aws-actions/configure-aws-credentials@v4.0.2 + with: + role-to-assume: ${{ secrets.AWS_FRONTEND_ROLE }} + role-session-name: GitHub_to_AWS_via_FederatedOIDC + aws-region: ${{ env.AWS_REGION }} + + - name: Build frontend distribution + working-directory: frontend + run: npm ci && npm run build + + - name: Sync distribution to S3 + run: | + aws s3 sync ./frontend/dist/frontend/browser/ s3://$S3_BUCKET_NAME --delete + + - name: Invalidate Cloudfront Cache + run: | + aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CLOUDFRONT_ID }} --paths "/*"