feat: enhance appendEventToGoogleSheets to prevent value duplication … #39723
Workflow file for this run
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: App Deploy | |
| on: | |
| push: | |
| branches: [main, stage] | |
| pull_request: | |
| branches: [main, feature/*] | |
| merge_group: | |
| branches: [main] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} | |
| cancel-in-progress: true | |
| jobs: | |
| affected: | |
| runs-on: blacksmith-2vcpu-ubuntu-2204 | |
| strategy: | |
| matrix: | |
| node-version: [22] | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| run_install: false | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - uses: nrwl/nx-set-shas@v4 | |
| - id: set-matrix | |
| name: set matrix app to affected array | |
| run: | | |
| matrix=$(pnpm -s exec ts-node tools/scripts/deploy-apps.ts --projects "apps/*" --exclude "apps/arclight") | |
| echo "matrix=${matrix}" >> "$GITHUB_OUTPUT" | |
| cat "$GITHUB_OUTPUT" | |
| deploy-preview: | |
| name: Deploy Preview | |
| needs: affected | |
| # if branch is not main or is a pull request | |
| if: | | |
| needs.affected.outputs.matrix != '[]' && | |
| needs.affected.outputs.matrix != '' && | |
| github.event_name != 'merge_group' && ( | |
| github.ref != 'refs/heads/main' || github.event_name == 'pull_request' | |
| ) | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| app: ${{fromJson(needs.affected.outputs.matrix)}} | |
| github-ref-name: ['${{ github.ref_name }}'] | |
| github-event-name: ['${{ github.event_name }}'] | |
| node-version: [22] | |
| exclude: | |
| # handled by production job below | |
| - app: journeys | |
| github-ref-name: stage | |
| github-event-name: push | |
| # handled by production job below | |
| - app: short-links | |
| github-ref-name: stage | |
| github-event-name: push | |
| # handled by ecs-frontend-deploy-stage | |
| - app: journeys-admin | |
| github-ref-name: stage | |
| github-event-name: push | |
| runs-on: blacksmith-2vcpu-ubuntu-2204 | |
| env: | |
| NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} | |
| outputs: | |
| url: ${{ steps.deployment-url.outputs.deployment-url }} | |
| permissions: | |
| pull-requests: write | |
| deployments: write | |
| contents: write | |
| steps: | |
| - name: start deployment | |
| uses: chrnorm/deployment-action@v2 | |
| id: deployment | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| environment: Preview - ${{ matrix.app }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| run_install: false | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - uses: nrwl/nx-set-shas@v4 | |
| - name: vercel deployment | |
| env: | |
| VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} | |
| VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
| ARCLIGHT_VERCEL_PROJECT_ID: ${{ secrets.ARCLIGHT_VERCEL_PROJECT_ID }} | |
| DOCS_VERCEL_PROJECT_ID: ${{ secrets.DOCS_VERCEL_PROJECT_ID }} | |
| JOURNEYS_VERCEL_PROJECT_ID: ${{ secrets.JOURNEYS_STAGE_VERCEL_PROJECT_ID }} | |
| JOURNEYS_ADMIN_VERCEL_PROJECT_ID: ${{ secrets.JOURNEYS_ADMIN_VERCEL_PROJECT_ID }} | |
| PLAYER_VERCEL_PROJECT_ID: ${{ secrets.PLAYER_VERCEL_PROJECT_ID }} | |
| SHORT_LINKS_VERCEL_PROJECT_ID: ${{ secrets.SHORT_LINKS_STAGE_VERCEL_PROJECT_ID }} | |
| VIDEOS_ADMIN_VERCEL_PROJECT_ID: ${{ secrets.VIDEOS_ADMIN_VERCEL_PROJECT_ID }} | |
| WATCH_VERCEL_PROJECT_ID: ${{ secrets.WATCH_VERCEL_PROJECT_ID }} | |
| WATCH_MODERN_VERCEL_PROJECT_ID: ${{ secrets.WATCH_MODERN_VERCEL_PROJECT_ID }} | |
| RESOURCES_VERCEL_PROJECT_ID: ${{ secrets.RESOURCES_VERCEL_PROJECT_ID }} | |
| NEXT_PUBLIC_VERCEL_ENV: ${{ github.event_name == 'push' && github.ref == 'refs/heads/stage' && 'stage' || 'preview' }} | |
| NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: ${{ github.sha }} | |
| # use run-namy to avoid case where deploy command doesn't exist for a project | |
| run: pnpm exec nx run-many --target=deploy --projects=${{ matrix.app }} | |
| - name: upload sourcemaps to datadog | |
| env: | |
| GIT_COMMIT_SHA: ${{ github.sha }} | |
| DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} | |
| run: pnpm exec nx run-many --target=upload-sourcemaps --projects=${{ matrix.app }} | |
| - name: vercel set alias | |
| if: ${{ github.event_name == 'pull_request' }} | |
| env: | |
| VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
| PR_NUMBER: ${{ github.event.number }} | |
| # use run-namy to avoid case where deploy command doesn't exist for a project | |
| run: pnpm exec nx run-many --target=vercel-alias --projects=${{ matrix.app }} | |
| - name: Generate GitHub deployment comment | |
| id: deployment-url | |
| env: | |
| APP: ${{ matrix.app }} | |
| run: ./tools/scripts/generate-deployment-comment.sh | |
| - id: get-comment-body | |
| run: | | |
| body="$(cat .github/deployment_comment.md)" | |
| delimiter="$(openssl rand -hex 8)" | |
| echo "body<<$delimiter" >> $GITHUB_OUTPUT | |
| echo "$body" >> $GITHUB_OUTPUT | |
| echo "$delimiter" >> $GITHUB_OUTPUT | |
| - uses: mshick/add-pr-comment@v2 | |
| if: ${{ github.event_name == 'pull_request' }} | |
| name: add deployment comment to pull request | |
| with: | |
| message: ${{ steps.get-comment-body.outputs.body }} | |
| message-id: ${{ matrix.app }} | |
| - name: add deployment comment to commit | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: peter-evans/commit-comment@v3 | |
| with: | |
| body: ${{ steps.get-comment-body.outputs.body }} | |
| - name: update deployment status | |
| uses: chrnorm/deployment-status@v2 | |
| if: always() | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| state: ${{ job.status }} | |
| environment-url: ${{ steps.deployment-url.outputs.deployment-url }} | |
| deployment-id: ${{ steps.deployment.outputs.deployment_id }} | |
| - name: Prepare E2E input file | |
| run: | | |
| mkdir -p e2e-input | |
| echo "${{ steps.deployment-url.outputs.deployment-url }}" > e2e-input/${{ matrix.app }}.txt | |
| - name: Upload E2E input artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: e2e-input-${{ matrix.app }} | |
| path: e2e-input/${{ matrix.app }}.txt | |
| if-no-files-found: ignore | |
| overwrite: true | |
| retention-days: 2 | |
| deploy-status: | |
| runs-on: blacksmith-2vcpu-ubuntu-2204 | |
| needs: [affected, deploy-preview] | |
| if: ${{ always() && github.event_name == 'pull_request' }} | |
| steps: | |
| - name: Successful deploy | |
| if: ${{ !(contains(needs.*.result, 'failure')) }} | |
| run: exit 0 | |
| - name: Failing deploy | |
| if: ${{ contains(needs.*.result, 'failure') }} | |
| run: exit 1 | |
| build-e2e-matrix: | |
| name: Build E2E Matrix | |
| needs: [affected, deploy-preview] | |
| if: ${{ github.event_name != 'merge_group' && needs.deploy-preview.result == 'success' && !(github.event_name == 'push' && github.ref == 'refs/heads/stage') && (github.event_name != 'pull_request' || !github.event.pull_request.draft) }} | |
| permissions: | |
| actions: read | |
| contents: read | |
| runs-on: blacksmith-2vcpu-ubuntu-2204 | |
| outputs: | |
| include: ${{ steps.build.outputs.include }} | |
| apps: ${{ steps.build.outputs.apps }} | |
| steps: | |
| - name: Download all E2E input artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: e2e-input | |
| pattern: e2e-input-* | |
| merge-multiple: true | |
| - name: Build matrix from deployments | |
| id: build | |
| run: | | |
| set -euo pipefail | |
| include='[]' | |
| if [ ! -d e2e-input ]; then | |
| echo "include=${include}" >> $GITHUB_OUTPUT | |
| echo "apps=[]" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| shopt -s nullglob | |
| files=(e2e-input/*.txt) | |
| echo "E2E input files found: ${files[*]:-none}" | |
| if [ ${#files[@]} -eq 0 ]; then | |
| echo "include=${include}" >> $GITHUB_OUTPUT | |
| echo "apps=[]" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| for f in "${files[@]}"; do | |
| app=$(basename "${f}" .txt) | |
| url=$(cat "${f}") | |
| echo "Adding app=${app} url=${url}" | |
| if [ -n "${url}" ]; then | |
| include=$(jq -c --arg app "${app}" --arg url "${url}" '. + [{app:$app, url:$url}]' <<<"${include}") | |
| fi | |
| done | |
| apps=$(jq -c '[.[] | .app]' <<<"${include}") | |
| echo "Final E2E include: ${include}" | |
| echo "include=${include}" >> $GITHUB_OUTPUT | |
| echo "apps=${apps}" >> $GITHUB_OUTPUT | |
| e2e: | |
| name: Playwright E2E (${{ matrix.app }}) | |
| needs: [build-e2e-matrix] | |
| # Only run if ALL deploy-preview matrix entries succeeded and we have URLs | |
| if: ${{ github.event_name != 'merge_group' && needs.build-e2e-matrix.result == 'success' && needs.build-e2e-matrix.outputs.apps != '[]' && needs.build-e2e-matrix.outputs.apps != '' && !(github.event_name == 'push' && github.ref == 'refs/heads/stage') && (github.event_name != 'pull_request' || !github.event.pull_request.draft) }} | |
| permissions: | |
| contents: read | |
| runs-on: blacksmith-4vcpu-ubuntu-2204 | |
| env: | |
| NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| app: ${{ fromJson(needs.build-e2e-matrix.outputs.apps) }} | |
| node-version: [22] | |
| include: ${{ fromJson(needs.build-e2e-matrix.outputs.include) }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| run_install: false | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - name: Cache Playwright browsers | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.cache/ms-playwright | |
| key: ${{ runner.os }}-node-${{ matrix.node-version }}-playwright-${{ hashFiles('pnpm-lock.yaml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-node-${{ matrix.node-version }}-playwright- | |
| - name: Install Playwright Browsers | |
| run: pnpm exec playwright install --with-deps | |
| - name: Run Playwright tests | |
| run: pnpm exec nx run ${{ matrix.app }}-e2e:e2e | |
| env: | |
| DEPLOYMENT_URL: ${{ matrix.url }} | |
| PLAYWRIGHT_USER: ${{ secrets.PLAYWRIGHT_USER }} | |
| PLAYWRIGHT_TEAM_NAME: ${{ secrets.PLAYWRIGHT_TEAM_NAME }} | |
| EXAMPLE_EMAIL_TOKEN: ${{ secrets.EXAMPLE_EMAIL_TOKEN }} | |
| PLAYWRIGHT_EMAIL: ${{ secrets.PLAYWRIGHT_EMAIL }} | |
| PLAYWRIGHT_PASSWORD: ${{ secrets.PLAYWRIGHT_PASSWORD }} | |
| PLAYWRIGHT_EMAIL2: ${{ secrets.PLAYWRIGHT_EMAIL2 }} | |
| PLAYWRIGHT_PASSWORD2: ${{ secrets.PLAYWRIGHT_PASSWORD2 }} | |
| PLAYWRIGHT_EMAIL3: ${{ secrets.PLAYWRIGHT_EMAIL3 }} | |
| PLAYWRIGHT_PASSWORD3: ${{ secrets.PLAYWRIGHT_PASSWORD3 }} | |
| PLAYWRIGHT_EMAIL4: ${{ secrets.PLAYWRIGHT_EMAIL4 }} | |
| PLAYWRIGHT_PASSWORD4: ${{ secrets.PLAYWRIGHT_PASSWORD4 }} | |
| PLAYWRIGHT_EMAIL5: ${{ secrets.PLAYWRIGHT_EMAIL5 }} | |
| PLAYWRIGHT_PASSWORD5: ${{ secrets.PLAYWRIGHT_PASSWORD5 }} | |
| - uses: actions/upload-artifact@v4 | |
| if: always() | |
| with: | |
| name: ${{ matrix.app }}-playwright-report | |
| path: | | |
| playwright-report/ | |
| retention-days: 30 | |
| deploy-production: | |
| name: Deploy Production | |
| # if push to main or stage | |
| if: | | |
| needs.affected.outputs.matrix != '[]' && | |
| needs.affected.outputs.matrix != '' && | |
| github.event_name == 'push' && | |
| (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/stage') | |
| needs: affected | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| app: ${{fromJson(needs.affected.outputs.matrix)}} | |
| github-ref-name: ['${{ github.ref_name }}'] | |
| node-version: [22] | |
| exclude: | |
| # handled by ecs-frontend-deploy-prod | |
| - app: journeys-admin | |
| # handled by deploy-preview job above | |
| - github-ref-name: stage | |
| include: | |
| - app: journeys | |
| github-ref-name: stage | |
| - app: short-links | |
| github-ref-name: stage | |
| runs-on: blacksmith-2vcpu-ubuntu-2204 | |
| permissions: | |
| deployments: write | |
| contents: write | |
| outputs: | |
| url: ${{ steps.deployment-url.outputs.deployment-url }} | |
| steps: | |
| - name: start deployment | |
| uses: chrnorm/deployment-action@v2 | |
| id: deployment | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| environment: Production - ${{ matrix.app }} | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup pnpm | |
| uses: pnpm/action-setup@v4 | |
| with: | |
| run_install: false | |
| - uses: actions/setup-node@v5 | |
| with: | |
| node-version: ${{ matrix.node-version }} | |
| cache: 'pnpm' | |
| - name: Install dependencies | |
| run: pnpm install --frozen-lockfile | |
| - uses: nrwl/nx-set-shas@v4 | |
| - name: vercel deployment | |
| env: | |
| VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }} | |
| VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} | |
| ARCLIGHT_VERCEL_PROJECT_ID: ${{ secrets.ARCLIGHT_VERCEL_PROJECT_ID }} | |
| DOCS_VERCEL_PROJECT_ID: ${{ secrets.DOCS_VERCEL_PROJECT_ID }} | |
| JOURNEYS_VERCEL_PROJECT_ID: ${{ github.ref == 'refs/heads/stage' && secrets.JOURNEYS_STAGE_VERCEL_PROJECT_ID || secrets.JOURNEYS_VERCEL_PROJECT_ID }} | |
| JOURNEYS_ADMIN_VERCEL_PROJECT_ID: ${{ secrets.JOURNEYS_ADMIN_VERCEL_PROJECT_ID }} | |
| PLAYER_VERCEL_PROJECT_ID: ${{ secrets.PLAYER_VERCEL_PROJECT_ID }} | |
| SHORT_LINKS_VERCEL_PROJECT_ID: ${{ github.ref == 'refs/heads/stage' && secrets.SHORT_LINKS_STAGE_VERCEL_PROJECT_ID || secrets.SHORT_LINKS_VERCEL_PROJECT_ID }} | |
| VIDEOS_ADMIN_VERCEL_PROJECT_ID: ${{ secrets.VIDEOS_ADMIN_VERCEL_PROJECT_ID }} | |
| WATCH_VERCEL_PROJECT_ID: ${{ secrets.WATCH_VERCEL_PROJECT_ID }} | |
| WATCH_MODERN_VERCEL_PROJECT_ID: ${{ secrets.WATCH_MODERN_VERCEL_PROJECT_ID }} | |
| RESOURCES_VERCEL_PROJECT_ID: ${{ secrets.RESOURCES_VERCEL_PROJECT_ID }} | |
| NEXT_PUBLIC_VERCEL_ENV: prod | |
| NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA: ${{ github.sha }} | |
| # use run-namy to avoid case where deploy command doesn't exist for a project | |
| run: pnpm exec nx run-many --target=deploy --projects=${{ matrix.app }} --prod | |
| - name: upload sourcemaps to datadog | |
| env: | |
| GIT_COMMIT_SHA: ${{ github.sha }} | |
| DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }} | |
| run: pnpm exec nx run-many --target=upload-sourcemaps --projects=${{ matrix.app }} | |
| - name: Generate GitHub comment | |
| id: deployment-url | |
| env: | |
| APP: ${{ matrix.app }} | |
| run: ./tools/scripts/generate-deployment-comment.sh | |
| - id: get-comment-body | |
| run: | | |
| body="$(cat .github/deployment_comment.md)" | |
| delimiter="$(openssl rand -hex 8)" | |
| echo "body<<$delimiter" >> $GITHUB_OUTPUT | |
| echo "$body" >> $GITHUB_OUTPUT | |
| echo "$delimiter" >> $GITHUB_OUTPUT | |
| - name: add deployment comment to commit | |
| if: ${{ github.event_name != 'pull_request' }} | |
| uses: peter-evans/commit-comment@v3 | |
| with: | |
| body: ${{ steps.get-comment-body.outputs.body }} | |
| - name: update deployment status | |
| uses: chrnorm/deployment-status@v2 | |
| if: always() | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| state: ${{ job.status }} | |
| environment-url: ${{ steps.deployment-url.outputs.deployment-url }} | |
| deployment-id: ${{ steps.deployment.outputs.deployment_id }} |