Skip to content

feat(#2095): add verified/unchecked variable fields to review findings schema #4194

feat(#2095): add verified/unchecked variable fields to review findings schema

feat(#2095): add verified/unchecked variable fields to review findings schema #4194

Workflow file for this run

name: E2E Tests
# PR-triggered e2e uses pull_request_target so fork PRs receive secrets.
# Authorization runs in a separate gate job (base checkout only) before the e2e
# job checks out the PR head — see gate/e2e job comments for why this is split.
permissions: {}
on:
push:
branches: [main]
# SYNC-WITH: grep regex in "Check for e2e-relevant changes" step in the e2e job
paths:
- '**/*.go'
- 'go.mod'
- 'go.sum'
- 'e2e/**'
- 'internal/scaffold/fullsend-repo/**'
- 'internal/security/hooks/**'
- 'internal/dispatch/gcf/mintsrc/**'
- 'internal/sentencetoken/english.json'
- 'Makefile'
- '.github/workflows/e2e.yml'
- '.github/actions/check-e2e-authorization/**'
- 'scripts/check-e2e-authorization.sh'
pull_request_target:
types: [opened, synchronize, reopened, labeled]
merge_group:
workflow_dispatch:
concurrency:
group: >-
${{ github.event_name == 'pull_request_target'
&& format('e2e-{0}', github.event.pull_request.number)
|| format('{0}-{1}', github.workflow, github.ref) }}
cancel-in-progress: >-
${{ github.event_name == 'pull_request_target'
|| github.ref != 'refs/heads/main' }}
jobs:
gate:
# Separate job (not steps in e2e) so pull-requests: write stays out of the
# job that checks out fork head and runs make e2e-test with secrets.
# Never checkout github.event.pull_request.head.sha here.
if: >-
github.event_name == 'pull_request_target' &&
(github.event.action != 'labeled' || github.event.label.name == 'ok-to-test')
runs-on: ubuntu-24.04
timeout-minutes: 5
permissions:
contents: read
pull-requests: write
outputs:
authorized: ${{ steps.auth.outputs.authorized }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.sha }} # Base branch only — never checkout PR head in gate
- name: Check PR authorization
id: auth
uses: ./.github/actions/check-e2e-authorization
with:
pr_number: ${{ github.event.pull_request.number }}
repository: ${{ github.repository }}
pr_updated_at: ${{ github.event.pull_request.updated_at }}
event_action: ${{ github.event.action }}
pr_author_association: ${{ github.event.pull_request.author_association }}
pr_author_login: ${{ github.event.pull_request.user.login }}
e2e:
# For pull_request_target, runs only when gate sets authorized=true.
# Do not treat a skipped gate as authorized (e.g. labeled events for non-ok-to-test labels).
# This job checks out untrusted PR head code — no pull-requests: write here.
needs: gate
if: >-
!cancelled() &&
(github.event_name != 'pull_request_target' || needs.gate.outputs.authorized == 'true')
runs-on: ubuntu-24.04
timeout-minutes: 30
permissions:
contents: read
id-token: write
steps:
- name: Check for e2e-relevant changes
id: changes
if: github.event_name == 'pull_request_target' || github.event_name == 'merge_group'
env:
GH_TOKEN: ${{ github.token }}
EVENT_NAME: ${{ github.event_name }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
MERGE_GROUP_BASE: ${{ github.event.merge_group.base_sha }}
MERGE_GROUP_HEAD: ${{ github.event.merge_group.head_sha }}
# SYNC-WITH: push.paths filter above
run: |
if [ "$EVENT_NAME" = "merge_group" ]; then
FILES=$(gh api "repos/${REPO}/compare/${MERGE_GROUP_BASE}...${MERGE_GROUP_HEAD}" --jq '.files[].filename') || {
echo "::warning::Failed to fetch merge group files — running e2e tests as a precaution"
echo "relevant=true" >> "$GITHUB_OUTPUT"
exit 0
}
FILE_COUNT=$(echo "$FILES" | wc -l)
if [ "$FILE_COUNT" -ge 300 ]; then
echo "::warning::Compare API returned $FILE_COUNT files (possible truncation at 300) — running e2e tests as a precaution"
echo "relevant=true" >> "$GITHUB_OUTPUT"
exit 0
fi
else
FILES=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}/files" --paginate --jq '.[].filename') || {
echo "::warning::Failed to fetch PR files — running e2e tests as a precaution"
echo "relevant=true" >> "$GITHUB_OUTPUT"
exit 0
}
fi
if echo "$FILES" | grep -qE '\.go$|^go\.(mod|sum)$|^e2e/|^internal/scaffold/fullsend-repo/|^internal/security/hooks/|^internal/dispatch/gcf/mintsrc/|^internal/sentencetoken/english\.json$|^Makefile$|^\.github/workflows/e2e\.yml$|^\.github/actions/check-e2e-authorization/|^scripts/check-e2e-authorization\.sh$'; then
echo "relevant=true" >> "$GITHUB_OUTPUT"
else
echo "::notice::No e2e-relevant files changed — skipping tests"
echo "relevant=false" >> "$GITHUB_OUTPUT"
fi
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
if: steps.changes.outputs.relevant != 'false'
with:
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
# checkout@v7 blocks fork PR head checkouts on pull_request_target by default.
# Safe here: gate job authorizes before this job runs; no pull-requests: write.
allow-unsafe-pr-checkout: ${{ github.event_name == 'pull_request_target' }}
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
if: steps.changes.outputs.relevant != 'false'
with:
go-version-file: go.mod
- name: Install Playwright system dependencies
if: steps.changes.outputs.relevant != 'false'
run: npx playwright install-deps chromium
- name: Check for secrets
if: steps.changes.outputs.relevant != 'false'
id: secrets-check
run: |
if [ -z "$E2E_GITHUB_SESSION_B64" ]; then
echo "::warning::E2E secrets are not configured. Skipping e2e tests."
echo "available=false" >> "$GITHUB_OUTPUT"
else
echo "available=true" >> "$GITHUB_OUTPUT"
fi
env:
E2E_GITHUB_SESSION_B64: ${{ secrets.E2E_GITHUB_SESSION }}
- name: Decode session
if: steps.changes.outputs.relevant != 'false' && steps.secrets-check.outputs.available == 'true'
run: |
SESSION_FILE="${RUNNER_TEMP}/github-session.json"
printf '%s' "$E2E_GITHUB_SESSION_B64" | base64 -d > "$SESSION_FILE"
echo "E2E_GITHUB_SESSION_FILE=${SESSION_FILE}" >> "$GITHUB_ENV"
env:
E2E_GITHUB_SESSION_B64: ${{ secrets.E2E_GITHUB_SESSION }}
- name: Authenticate to GCP
if: steps.changes.outputs.relevant != 'false' && steps.secrets-check.outputs.available == 'true'
uses: google-github-actions/auth@7c6bc770dae815cd3e89ee6cdf493a5fab2cc093 # v3.0.0
with:
workload_identity_provider: ${{ secrets.E2E_GCP_WIF_PROVIDER }}
service_account: ${{ secrets.E2E_GCP_SERVICE_ACCOUNT }}
- name: Run e2e tests
if: steps.changes.outputs.relevant != 'false' && steps.secrets-check.outputs.available == 'true'
run: make e2e-test
env:
E2E_SCREENSHOT_DIR: ${{ runner.temp }}/e2e-screenshots
E2E_GITHUB_PASSWORD: ${{ secrets.E2E_GITHUB_PASSWORD }}
E2E_GITHUB_TOTP_SECRET: ${{ secrets.E2E_GITHUB_TOTP_SECRET }}
E2E_MINT_URL: ${{ secrets.E2E_MINT_URL }}
E2E_GCP_PROJECT_ID: ${{ secrets.E2E_GCP_PROJECT_ID }}
- name: Upload debug screenshots
if: always() && steps.changes.outputs.relevant != 'false' && steps.secrets-check.outputs.available == 'true'
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: e2e-screenshots-${{ github.event_name == 'pull_request_target' && github.event.pull_request.number || github.run_id }}
path: ${{ runner.temp }}/e2e-screenshots/
if-no-files-found: ignore
retention-days: 5