Skip to content
Latchkey

Staging Deployment (AWS App Runner) workflow (ansari-project/ansari-backend)

The Staging Deployment (AWS App Runner) workflow from ansari-project/ansari-backend, explained and optimized by Latchkey.

C

CI health: C - fair

Point runs-on at Latchkey and get run de-duplication, job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: ansari-project/ansari-backend.github/workflows/deploy-staging.ymlLicense MITView source

What it does

This is the Staging Deployment (AWS App Runner) workflow from the ansari-project/ansari-backend repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Staging Deployment (AWS App Runner)

on:
  push:
    branches:
      - develop
  workflow_dispatch:

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    environment: staging-aws

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: Configure AWS credentials
        id: aws-credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ansari-backend
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"

      - name: Deploy to App Runner
        id: deploy-apprunner
        uses: awslabs/amazon-app-runner-deploy@main
        env:
          DEPLOYMENT_TYPE: staging
          LOGGING_LEVEL: DEBUG
          FRONTEND_URL: ${{ format('{0}{1}', secrets.SSM_ROOT, 'frontend-url') }}
          MONGO_URL: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mongo-url') }}
          MONGO_DB_NAME: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mongo-db-name') }}
          SECRET_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'secret-key') }}
          ORIGINS:  ${{ format('{0}{1}', secrets.SSM_ROOT, 'origins') }}

          OPENAI_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'openai-api-key') }}
          SENDGRID_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sendgrid-api-key') }}
          MAILCHIMP_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-api-key') }}
          MAILCHIMP_SERVER_PREFIX: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-server-prefix') }}
          MAILCHIMP_LIST_ID: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-list-id') }}
          ANTHROPIC_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'anthropic-api-key') }}
          KALEMAT_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'kalemat-api-key') }}
          SUNNAH_TOKEN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sunnah-token') }}
          VECTARA_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'vectara-api-key') }}
          QURAN_DOT_COM_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'quran-dot-com-api-key') }}
          USUL_API_TOKEN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'usul-api-token') }}
          SENTRY_DSN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sentry-dsn') }}

          WHATSAPP_SERVICE_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-service-api-key') }}
          WHATSAPP_ACCESS_TOKEN_FROM_SYS_USER: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-access-token-from-sys-user') }}
          WHATSAPP_BUSINESS_PHONE_NUMBER_ID: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-business-phone-number-id') }}
          WHATSAPP_VERIFY_TOKEN_FOR_WEBHOOK: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-verify-token-for-webhook') }}
          WHATSAPP_ENABLED: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-enabled') }}
          WHATSAPP_API_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-api-version') }}
          WHATSAPP_CHAT_RETENTION_HOURS: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-chat-retention-hours') }}

          MAINTENANCE_MODE: ${{ format('{0}{1}', secrets.SSM_ROOT, 'maintenance-mode') }}
          IOS_MINIMUM_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'ios-minimum-build-version') }}
          IOS_LATEST_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'ios-latest-build-version') }}
          ANDROID_MINIMUM_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'android-minimum-build-version') }}
          ANDROID_LATEST_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'android-latest-build-version') }}
        with:
          service: ansari-staging-backend
          image: ${{ steps.build-image.outputs.image }}
          access-role-arn: ${{ secrets.SERVICE_ROLE_ARN }}
          region: ${{ secrets.AWS_REGION }}
          cpu : 1
          memory : 2
          port: 8000
          wait-for-service-stability-seconds: 1200
          copy-env-vars: |
            DEPLOYMENT_TYPE
            LOGGING_LEVEL
          copy-secret-env-vars: |
            FRONTEND_URL
            MONGO_URL
            MONGO_DB_NAME
            SECRET_KEY
            ORIGINS

            OPENAI_API_KEY
            SENDGRID_API_KEY
            MAILCHIMP_API_KEY
            MAILCHIMP_SERVER_PREFIX
            MAILCHIMP_LIST_ID
            ANTHROPIC_API_KEY
            KALEMAT_API_KEY
            SUNNAH_TOKEN
            VECTARA_API_KEY
            QURAN_DOT_COM_API_KEY
            USUL_API_TOKEN
            SENTRY_DSN

            WHATSAPP_SERVICE_API_KEY
            WHATSAPP_ACCESS_TOKEN_FROM_SYS_USER
            WHATSAPP_BUSINESS_PHONE_NUMBER_ID
            WHATSAPP_VERIFY_TOKEN_FOR_WEBHOOK
            WHATSAPP_API_VERSION
            WHATSAPP_ENABLED
            WHATSAPP_CHAT_RETENTION_HOURS

            MAINTENANCE_MODE
            IOS_MINIMUM_BUILD_VERSION
            IOS_LATEST_BUILD_VERSION
            ANDROID_MINIMUM_BUILD_VERSION
            ANDROID_LATEST_BUILD_VERSION
          instance-role-arn: ${{ secrets.INSTANCE_ROLE_ARN }}

      - name: App Runner URL
        run: echo "App runner URL ${{ steps.deploy-apprunner.outputs.service-url }}"

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Staging Deployment (AWS App Runner)
 
on:
  push:
    branches:
      - develop
  workflow_dispatch:
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  build-and-deploy:
    timeout-minutes: 30
    runs-on: latchkey-small
    environment: staging-aws
 
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          persist-credentials: false
 
      - name: Configure AWS credentials
        id: aws-credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ secrets.AWS_REGION }}
 
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
 
      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ansari-backend
          IMAGE_TAG: ${{ github.sha }}
        run: |
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
 
      - name: Deploy to App Runner
        id: deploy-apprunner
        uses: awslabs/amazon-app-runner-deploy@main
        env:
          DEPLOYMENT_TYPE: staging
          LOGGING_LEVEL: DEBUG
          FRONTEND_URL: ${{ format('{0}{1}', secrets.SSM_ROOT, 'frontend-url') }}
          MONGO_URL: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mongo-url') }}
          MONGO_DB_NAME: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mongo-db-name') }}
          SECRET_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'secret-key') }}
          ORIGINS:  ${{ format('{0}{1}', secrets.SSM_ROOT, 'origins') }}
 
          OPENAI_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'openai-api-key') }}
          SENDGRID_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sendgrid-api-key') }}
          MAILCHIMP_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-api-key') }}
          MAILCHIMP_SERVER_PREFIX: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-server-prefix') }}
          MAILCHIMP_LIST_ID: ${{ format('{0}{1}', secrets.SSM_ROOT, 'mailchimp-list-id') }}
          ANTHROPIC_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'anthropic-api-key') }}
          KALEMAT_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'kalemat-api-key') }}
          SUNNAH_TOKEN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sunnah-token') }}
          VECTARA_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'vectara-api-key') }}
          QURAN_DOT_COM_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'quran-dot-com-api-key') }}
          USUL_API_TOKEN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'usul-api-token') }}
          SENTRY_DSN: ${{ format('{0}{1}', secrets.SSM_ROOT, 'sentry-dsn') }}
 
          WHATSAPP_SERVICE_API_KEY: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-service-api-key') }}
          WHATSAPP_ACCESS_TOKEN_FROM_SYS_USER: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-access-token-from-sys-user') }}
          WHATSAPP_BUSINESS_PHONE_NUMBER_ID: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-business-phone-number-id') }}
          WHATSAPP_VERIFY_TOKEN_FOR_WEBHOOK: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-verify-token-for-webhook') }}
          WHATSAPP_ENABLED: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-enabled') }}
          WHATSAPP_API_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-api-version') }}
          WHATSAPP_CHAT_RETENTION_HOURS: ${{ format('{0}{1}', secrets.SSM_ROOT, 'whatsapp-chat-retention-hours') }}
 
          MAINTENANCE_MODE: ${{ format('{0}{1}', secrets.SSM_ROOT, 'maintenance-mode') }}
          IOS_MINIMUM_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'ios-minimum-build-version') }}
          IOS_LATEST_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'ios-latest-build-version') }}
          ANDROID_MINIMUM_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'android-minimum-build-version') }}
          ANDROID_LATEST_BUILD_VERSION: ${{ format('{0}{1}', secrets.SSM_ROOT, 'android-latest-build-version') }}
        with:
          service: ansari-staging-backend
          image: ${{ steps.build-image.outputs.image }}
          access-role-arn: ${{ secrets.SERVICE_ROLE_ARN }}
          region: ${{ secrets.AWS_REGION }}
          cpu : 1
          memory : 2
          port: 8000
          wait-for-service-stability-seconds: 1200
          copy-env-vars: |
            DEPLOYMENT_TYPE
            LOGGING_LEVEL
          copy-secret-env-vars: |
            FRONTEND_URL
            MONGO_URL
            MONGO_DB_NAME
            SECRET_KEY
            ORIGINS
 
            OPENAI_API_KEY
            SENDGRID_API_KEY
            MAILCHIMP_API_KEY
            MAILCHIMP_SERVER_PREFIX
            MAILCHIMP_LIST_ID
            ANTHROPIC_API_KEY
            KALEMAT_API_KEY
            SUNNAH_TOKEN
            VECTARA_API_KEY
            QURAN_DOT_COM_API_KEY
            USUL_API_TOKEN
            SENTRY_DSN
 
            WHATSAPP_SERVICE_API_KEY
            WHATSAPP_ACCESS_TOKEN_FROM_SYS_USER
            WHATSAPP_BUSINESS_PHONE_NUMBER_ID
            WHATSAPP_VERIFY_TOKEN_FOR_WEBHOOK
            WHATSAPP_API_VERSION
            WHATSAPP_ENABLED
            WHATSAPP_CHAT_RETENTION_HOURS
 
            MAINTENANCE_MODE
            IOS_MINIMUM_BUILD_VERSION
            IOS_LATEST_BUILD_VERSION
            ANDROID_MINIMUM_BUILD_VERSION
            ANDROID_LATEST_BUILD_VERSION
          instance-role-arn: ${{ secrets.INSTANCE_ROLE_ARN }}
 
      - name: App Runner URL
        run: echo "App runner URL ${{ steps.deploy-apprunner.outputs.service-url }}"
 

What changed

3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow