fix(deps): address 27 client and webshot dependency vulnerabilities (… #1319
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 | |
| on: | |
| workflow_dispatch: | |
| push: | |
| paths: | |
| - "api/**" | |
| - "client/**" | |
| - ".github/workflows/*" | |
| jobs: | |
| build-and-test: | |
| name: Build and Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check out the repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build and run tests | |
| run: docker compose up --build --exit-code-from test test | |
| - name: Clean up | |
| run: docker compose down | |
| # BUILD AND DEPLOY | |
| set_environment: | |
| name: Set Deployment Environment | |
| needs: [build-and-test] | |
| runs-on: ubuntu-latest | |
| if: ${{ github.event_name == 'workflow_dispatch' || github.ref_name == 'develop' || github.ref_name == 'staging' || github.ref_name == 'main' }} | |
| outputs: | |
| env_name: ${{ steps.set_env.outputs.env_name }} | |
| steps: | |
| - id: set_env | |
| run: echo "env_name=${{ github.ref_name == 'main' && 'production' || github.ref_name }}" >> $GITHUB_OUTPUT | |
| build_api: | |
| name: build-api | |
| needs: [set_environment] | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: ${{ needs.set_environment.outputs.env_name }} | |
| steps: | |
| - name: Debug env_name | |
| run: | | |
| echo "Environment name is: ${{ needs.set_environment.outputs.env_name }}" | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| aws-access-key-id: ${{ vars.TF_PIPELINE_USER_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.TF_PIPELINE_USER_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.TF_AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| with: | |
| mask-password: "true" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Build, tag, and push Client image to Amazon ECR | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: api | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| file: ./api/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_API_REPOSITORY_NAME }}:${{ github.sha }} | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_API_REPOSITORY_NAME }}:${{ needs.set_environment.outputs.env_name }} | |
| build_client: | |
| name: build-client | |
| needs: [set_environment] | |
| environment: | |
| name: ${{ needs.set_environment.outputs.env_name }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| aws-access-key-id: ${{ vars.TF_PIPELINE_USER_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.TF_PIPELINE_USER_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.TF_AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| with: | |
| mask-password: "true" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Use Latest Corepack | |
| run: | | |
| echo "Before: corepack version => $(corepack --version || echo 'not installed')" | |
| npm install -g corepack@latest | |
| echo "After : corepack version => $(corepack --version)" | |
| corepack enable | |
| pnpm --version | |
| - name: Build, tag, and push Client image to Amazon ECR | |
| uses: docker/build-push-action@v5 | |
| with: | |
| build-args: | | |
| NEXT_PUBLIC_URL=${{ vars.TF_CLIENT_NEXT_PUBLIC_URL}} | |
| NEXT_PUBLIC_API_URL=${{ vars.TF_CLIENT_NEXT_PUBLIC_API_URL }} | |
| NEXT_PUBLIC_ARCGIS_API_KEY=${{ secrets.TF_CLIENT_NEXT_PUBLIC_ARCGIS_API_KEY }} | |
| NEXT_PUBLIC_API_KEY=${{ secrets.TF_CLIENT_NEXT_PUBLIC_API_KEY }} | |
| NEXT_PUBLIC_WEBSHOT_URL=${{ vars.TF_CLIENT_NEXT_PUBLIC_WEBSHOT_URL }} | |
| BASIC_AUTH_ENABLED=${{ vars.TF_CLIENT_BASIC_AUTH_ENABLED }} | |
| BASIC_AUTH_USER=${{ secrets.TF_CLIENT_BASIC_AUTH_USER }} | |
| BASIC_AUTH_PASSWORD=${{ secrets.TF_CLIENT_BASIC_AUTH_PASSWORD }} | |
| PAYLOAD_SECRET=${{ secrets.TF_CLIENT_PAYLOAD_SECRET }} | |
| DATABASE_URL=${{ vars.TF_DATABASE_URL }} | |
| DATABASE_PASSWORD=${{ secrets.TF_DATABASE_PASSWORD }} | |
| APP_KEY=${{ secrets.TF_CLIENT_APP_KEY }} | |
| AUTH_SECRET=${{ secrets.TF_CLIENT_AUTH_SECRET }} | |
| AUTH_URL=${{ vars.TF_CLIENT_NEXT_PUBLIC_URL }} | |
| AWS_SES_IAM_USER_ACCESS_KEY_ID=${{ vars.TF_AWS_SES_IAM_USER_ACCESS_KEY_ID }} | |
| AWS_SES_IAM_USER_SECRET_ACCESS_KEY=${{ secrets.TF_AWS_SES_IAM_USER_SECRET_ACCESS_KEY }} | |
| AWS_SES_REGION=${{ vars.TF_AWS_SES_REGION }} | |
| context: client | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| file: ./client/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_CLIENT_REPOSITORY_NAME }}:${{ github.sha }} | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_CLIENT_REPOSITORY_NAME }}:${{ needs.set_environment.outputs.env_name }} | |
| build_webshot: | |
| name: build-webshot | |
| needs: [set_environment] | |
| environment: | |
| name: ${{ needs.set_environment.outputs.env_name }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| aws-access-key-id: ${{ vars.TF_PIPELINE_USER_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.TF_PIPELINE_USER_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.TF_AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| with: | |
| mask-password: "true" | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Use Latest Corepack | |
| run: | | |
| echo "Before: corepack version => $(corepack --version || echo 'not installed')" | |
| npm install -g corepack@latest | |
| echo "After : corepack version => $(corepack --version)" | |
| corepack enable | |
| pnpm --version | |
| - name: Build, tag, and push Webshot image to Amazon ECR | |
| uses: docker/build-push-action@v5 | |
| with: | |
| context: webshot | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| file: ./webshot/Dockerfile | |
| push: true | |
| tags: | | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_WEBSHOT_REPOSITORY_NAME }}:${{ github.sha }} | |
| ${{ steps.login-ecr.outputs.registry }}/${{ vars.TF_WEBSHOT_REPOSITORY_NAME }}:${{ needs.set_environment.outputs.env_name }} | |
| deploy: | |
| name: deploy | |
| needs: [set_environment, build_api, build_client, build_webshot] | |
| runs-on: ubuntu-latest | |
| environment: | |
| name: ${{ needs.set_environment.outputs.env_name }} | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v3 | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@v5 | |
| with: | |
| aws-access-key-id: ${{ vars.TF_PIPELINE_USER_ACCESS_KEY_ID }} | |
| aws-secret-access-key: ${{ secrets.TF_PIPELINE_USER_SECRET_ACCESS_KEY }} | |
| aws-region: ${{ vars.TF_AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: login-ecr | |
| uses: aws-actions/amazon-ecr-login@v2 | |
| - name: Escape variables | |
| shell: bash | |
| run: | | |
| app_basic_auth_password='${{ secrets.TF_CLIENT_BASIC_AUTH_PASSWORD }}' | |
| app_basic_auth_password_escaped="${app_basic_auth_password//$/\$\$}" # $ -> $$ | |
| echo "::add-mask::$app_basic_auth_password_escaped" # mask the escaped value in runner output | |
| printf 'APP_BASIC_AUTH_PASSWORD_ESCAPED=%s\n' "$app_basic_auth_password_escaped" >> $GITHUB_ENV | |
| id: escape_variables | |
| - name: Promote grid data to s3 of next environment | |
| shell: bash | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ vars.TF_S3_SYNCS_USER_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.TF_S3_SYNCS_USER_SECRET_ACCESS_KEY }} | |
| AWS_REGION: ${{ vars.TF_AWS_REGION }} | |
| # DEBT: Bucket names are hardcoded | |
| run: | | |
| set -e | |
| if [ "${{ github.ref_name }}" = "staging" ]; then | |
| SRC_BUCKET="amazonia360-develop-bucket" | |
| DEST_BUCKET="amazonia360-staging-bucket" | |
| echo "Promoting data from DEV → STAGING" | |
| elif [ "${{ github.ref_name }}" = "main" ]; then | |
| SRC_BUCKET="amazonia360-staging-bucket" | |
| DEST_BUCKET="amazonia360-production-bucket" | |
| echo "Promoting data from STAGING → PRODUCTION" | |
| else | |
| echo "No S3 promotion for branch ${{ github.ref_name }}" | |
| exit 0 | |
| fi | |
| aws s3 sync s3://$SRC_BUCKET s3://$DEST_BUCKET \ | |
| --delete \ | |
| --exact-timestamps | |
| - name: Generate docker compose file | |
| working-directory: infrastructure/source_bundle | |
| env: | |
| ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} | |
| ECR_REPOSITORY_API: ${{ vars.TF_API_REPOSITORY_NAME }} | |
| ECR_REPOSITORY_CLIENT: ${{ vars.TF_CLIENT_REPOSITORY_NAME }} | |
| ECR_REPOSITORY_WEBSHOT: ${{ vars.TF_WEBSHOT_REPOSITORY_NAME }} | |
| IMAGE_TAG: ${{ needs.set_environment.outputs.env_name }} | |
| AWS_DEFAULT_REGION: ${{ vars.TF_AWS_REGION }} | |
| API_AUTH_TOKEN: ${{ secrets.TF_API_AUTH_TOKEN }} | |
| API_GRID_TILES_PATH: ${{ vars.TF_API_GRID_TILES_PATH }} | |
| OPENAI_TOKEN: ${{ secrets.TF_API_OPENAI_TOKEN }} | |
| DATABASE_PASSWORD: ${{ secrets.TF_DATABASE_PASSWORD }} | |
| AWS_SES_REGION: ${{ vars.TF_AWS_SES_REGION }} | |
| AWS_SES_IAM_USER_ACCESS_KEY_ID: ${{ vars.TF_AWS_SES_IAM_USER_ACCESS_KEY_ID }} | |
| AWS_SES_IAM_USER_SECRET_ACCESS_KEY: ${{ secrets.TF_AWS_SES_IAM_USER_SECRET_ACCESS_KEY }} | |
| run: | | |
| cat <<EOF >> docker-compose.yml | |
| version: '3.9' | |
| services: | |
| api: | |
| image: $ECR_REGISTRY/$ECR_REPOSITORY_API:$IMAGE_TAG | |
| ports: | |
| - "8000:8000" | |
| volumes: | |
| - /var/app/data/api:/opt/api/data:ro | |
| networks: | |
| - amazonia360-network | |
| environment: | |
| - AUTH_TOKEN=${API_AUTH_TOKEN} | |
| - GRID_TILES_PATH=${API_GRID_TILES_PATH} | |
| - OPENAI_TOKEN=${OPENAI_TOKEN} | |
| - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} | |
| restart: always | |
| client: | |
| image: $ECR_REGISTRY/$ECR_REPOSITORY_CLIENT:$IMAGE_TAG | |
| networks: | |
| - amazonia360-network | |
| ports: | |
| - 3000:3000 | |
| environment: | |
| - NODE_ENV=production | |
| - AWS_SES_REGION=${AWS_SES_REGION} | |
| - AWS_SES_IAM_USER_ACCESS_KEY_ID=${AWS_SES_IAM_USER_ACCESS_KEY_ID} | |
| - AWS_SES_IAM_USER_SECRET_ACCESS_KEY=${AWS_SES_IAM_USER_SECRET_ACCESS_KEY} | |
| - DATABASE_PASSWORD=${DATABASE_PASSWORD} | |
| restart: always | |
| webshot: | |
| image: $ECR_REGISTRY/$ECR_REPOSITORY_WEBSHOT:$IMAGE_TAG | |
| networks: | |
| - amazonia360-network | |
| ports: | |
| - 3003:3003 | |
| environment: | |
| PORT: 3003 | |
| APP_BASE_URL: http://client:3000 | |
| APP_BASIC_AUTH_USER: ${{ secrets.TF_CLIENT_BASIC_AUTH_USER }} | |
| APP_BASIC_AUTH_PASSWORD: ${APP_BASIC_AUTH_PASSWORD_ESCAPED} | |
| restart: always | |
| nginx: | |
| image: nginx | |
| restart: always | |
| networks: | |
| - amazonia360-network | |
| volumes: | |
| - ./proxy/conf.d:/etc/nginx/conf.d | |
| - "\${EB_LOG_BASE_DIR}/nginx:/var/log/nginx" | |
| ports: | |
| - 80:80 | |
| depends_on: | |
| - api | |
| - client | |
| networks: | |
| amazonia360-network: | |
| driver: bridge | |
| EOF | |
| - name: Generate zip file | |
| working-directory: infrastructure/source_bundle | |
| run: | | |
| zip -r deploy.zip * .[^.]* | |
| - name: Deploy to Amazon EB | |
| uses: einaregilsson/beanstalk-deploy@v21 | |
| with: | |
| aws_access_key: ${{ vars.TF_PIPELINE_USER_ACCESS_KEY_ID }} | |
| aws_secret_key: ${{ secrets.TF_PIPELINE_USER_SECRET_ACCESS_KEY }} | |
| application_name: ${{ vars.TF_PROJECT_NAME }}-${{ needs.set_environment.outputs.env_name }} | |
| environment_name: ${{ vars.TF_PROJECT_NAME }}-${{ needs.set_environment.outputs.env_name }}-environment | |
| region: ${{ vars.TF_AWS_REGION }} | |
| version_label: ${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }} | |
| deployment_package: infrastructure/source_bundle/deploy.zip | |
| wait_for_deployment: true |