Skip to content

Commit 49066b8

Browse files
committed
ci(integ-tests): Refactor auto integ test to workflow_run pattern
The pull_request_review trigger has no access to repository secrets for fork PRs, breaking team membership checks and OIDC auth. Split into two-stage workflow_run pattern (matching pr-linter): - Stage 1 (trigger): Unprivileged pull_request_review saves PR metadata and snapshot check result as artifacts - Stage 2 (deployment): Privileged workflow_run downloads artifacts, validates team membership with secrets, runs integ tests
1 parent 08b9280 commit 49066b8

2 files changed

Lines changed: 113 additions & 56 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Unprivileged workflow that runs in the context of the PR when a review is submitted.
2+
# Saves PR metadata and snapshot check result as artifacts for the privileged
3+
# integration-test-deployment-auto.yml workflow (triggered via workflow_run).
4+
#
5+
# This two-stage pattern is required because pull_request_review has no access to
6+
# repository secrets for fork PRs. See pr-linter-review-trigger.yml for precedent.
7+
name: Integration Test Auto Trigger
8+
9+
on:
10+
pull_request_review:
11+
types: [submitted]
12+
13+
permissions:
14+
contents: read
15+
16+
jobs:
17+
save-pr-info:
18+
if: github.event.review.state == 'approved'
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v6
23+
with:
24+
ref: ${{ github.event.pull_request.head.sha }}
25+
fetch-depth: 0
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v6
29+
with:
30+
node-version: "lts/*"
31+
32+
- name: Install dependencies
33+
run: yarn install --frozen-lockfile
34+
35+
- name: Build deployment-integ
36+
run: yarn --cwd tools/@aws-cdk/integration-test-deployment build
37+
38+
- name: Check for snapshot changes
39+
id: check_snapshots
40+
env:
41+
TARGET_BRANCH_COMMIT: ${{ github.event.pull_request.base.sha }}
42+
SOURCE_BRANCH_COMMIT: ${{ github.event.pull_request.head.sha }}
43+
run: |
44+
if yarn --cwd tools/@aws-cdk/integration-test-deployment check-snapshots; then
45+
echo "has_snapshots=true" >> $GITHUB_OUTPUT
46+
else
47+
echo "has_snapshots=false" >> $GITHUB_OUTPUT
48+
fi
49+
50+
- name: Save PR info
51+
env:
52+
PR_NUMBER: ${{ github.event.pull_request.number }}
53+
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
54+
BASE_SHA: ${{ github.event.pull_request.base.sha }}
55+
REVIEWER: ${{ github.event.review.user.login }}
56+
HAS_SNAPSHOTS: ${{ steps.check_snapshots.outputs.has_snapshots }}
57+
run: |
58+
mkdir -p ./pr
59+
echo "$PR_NUMBER" > ./pr/pr_number
60+
echo "$HEAD_SHA" > ./pr/head_sha
61+
echo "$BASE_SHA" > ./pr/base_sha
62+
echo "$REVIEWER" > ./pr/reviewer
63+
echo "$HAS_SNAPSHOTS" > ./pr/has_snapshots
64+
65+
- uses: actions/upload-artifact@v7
66+
with:
67+
name: integ_test_pr_info
68+
path: pr/
Lines changed: 45 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,63 @@
11
name: Integration Test deployment (Auto)
22

3-
# This workflow automatically runs integration tests when a PR with snapshot changes
4-
# is approved by a CDK team member. No manual approval required.
3+
# Privileged workflow that runs integration tests when triggered by the
4+
# "Integration Test Auto Trigger" workflow. Uses workflow_run to run in the
5+
# base repo context with access to secrets, vars, and OIDC.
56
#
6-
# SHADOW MODE: This workflow is in shadow mode - failures don't block PR merges.
7+
# SHADOW MODE: Failures don't block PR merges.
78
# Once validated, this will replace the label-based workflow (integration-test-deployment.yml).
89

910
on:
10-
pull_request_review:
11-
types: [submitted]
11+
workflow_run:
12+
workflows: ["Integration Test Auto Trigger"]
13+
types:
14+
- completed
1215

1316
concurrency:
14-
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
17+
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch }}
1518
cancel-in-progress: true
1619

1720
jobs:
18-
# Early validation: Check if approver is a CDK team member and PR has snapshot changes
19-
validate_approver:
20-
if: github.event.review.state == 'approved'
21+
download-pr-info:
22+
if: github.event.workflow_run.conclusion == 'success'
2123
runs-on: ubuntu-latest
2224
outputs:
23-
should_run: ${{ steps.check_team.outputs.is_member == 'true' && steps.check_snapshots.outputs.has_snapshots == 'true' }}
24-
permissions:
25-
contents: read
26-
pull-requests: read
25+
pr_number: ${{ steps.pr_output.outputs.pr_number }}
26+
head_sha: ${{ steps.pr_output.outputs.head_sha }}
27+
base_sha: ${{ steps.pr_output.outputs.base_sha }}
28+
reviewer: ${{ steps.pr_output.outputs.reviewer }}
29+
has_snapshots: ${{ steps.pr_output.outputs.has_snapshots }}
2730
steps:
28-
- name: Checkout for path filtering
29-
uses: actions/checkout@v6
31+
- name: Download artifact
32+
uses: dawidd6/action-download-artifact@v19
3033
with:
31-
ref: ${{ github.event.pull_request.head.sha }}
32-
fetch-depth: 0
33-
34-
- name: Setup Node.js
35-
uses: actions/setup-node@v6
36-
with:
37-
node-version: "lts/*"
38-
39-
- name: Install dependencies
40-
run: yarn install --frozen-lockfile
34+
run_id: ${{ github.event.workflow_run.id }}
35+
name: integ_test_pr_info
36+
path: pr/
37+
search_artifacts: true
4138

42-
- name: Build deployment-integ
43-
run: yarn --cwd tools/@aws-cdk/integration-test-deployment build
44-
45-
- name: Check for snapshot changes
46-
id: check_snapshots
47-
env:
48-
TARGET_BRANCH_COMMIT: ${{ github.event.pull_request.base.sha }}
49-
SOURCE_BRANCH_COMMIT: ${{ github.event.pull_request.head.sha }}
39+
- name: Read PR info
40+
id: pr_output
5041
run: |
51-
# Reuses getChangedSnapshots() from utils.ts — single source of truth
52-
if yarn --cwd tools/@aws-cdk/integration-test-deployment check-snapshots; then
53-
echo "has_snapshots=true" >> $GITHUB_OUTPUT
54-
else
55-
echo "has_snapshots=false" >> $GITHUB_OUTPUT
56-
fi
57-
42+
echo "pr_number=$(cat pr/pr_number)" >> "$GITHUB_OUTPUT"
43+
echo "head_sha=$(cat pr/head_sha)" >> "$GITHUB_OUTPUT"
44+
echo "base_sha=$(cat pr/base_sha)" >> "$GITHUB_OUTPUT"
45+
echo "reviewer=$(cat pr/reviewer)" >> "$GITHUB_OUTPUT"
46+
echo "has_snapshots=$(cat pr/has_snapshots)" >> "$GITHUB_OUTPUT"
47+
48+
validate-approver:
49+
needs: download-pr-info
50+
if: needs.download-pr-info.outputs.has_snapshots == 'true'
51+
runs-on: ubuntu-latest
52+
outputs:
53+
is_member: ${{ steps.check_team.outputs.is_member }}
54+
steps:
5855
- name: Check if approver is CDK team member
5956
id: check_team
60-
if: steps.check_snapshots.outputs.has_snapshots == 'true'
6157
env:
6258
GITHUB_TOKEN: ${{ secrets.PROJEN_GITHUB_TOKEN }}
63-
APPROVER: ${{ github.event.review.user.login }}
59+
APPROVER: ${{ needs.download-pr-info.outputs.reviewer }}
6460
run: |
65-
# Use gh CLI to check team membership (pre-installed in GitHub Actions runners)
66-
# https://docs.github.com/en/rest/teams/members#get-team-membership-for-a-user
6761
if gh api "orgs/aws/teams/aws-cdk-team/memberships/${APPROVER}" --jq '.state' 2>/dev/null | grep -q "active"; then
6862
echo "${APPROVER} is an active CDK team member"
6963
echo "is_member=true" >> $GITHUB_OUTPUT
@@ -73,20 +67,16 @@ jobs:
7367
fi
7468
7569
integration_test_deployment_auto:
76-
needs: validate_approver
77-
# Only run if approver is a CDK team member AND PR has snapshot changes
78-
if: needs.validate_approver.outputs.should_run == 'true'
70+
needs: [download-pr-info, validate-approver]
71+
if: needs.validate-approver.outputs.is_member == 'true'
7972
runs-on: codebuild-aws-cdk-github-actions-deployment-integ-runner-${{ github.run_id }}-${{ github.run_attempt }}
80-
# No environment - runs automatically without manual approval
8173
# Shadow mode: workflow reports success even if tests fail
8274
continue-on-error: true
8375
name: 'Deploy integration test snapshots (Auto)'
8476

85-
# Job-level permissions for least privilege
8677
permissions:
8778
id-token: write # Required for OIDC authentication with AWS Atmosphere
88-
pull-requests: read # Required to check PR reviews and labels
89-
contents: read # Required to checkout code
79+
contents: read
9080

9181
env:
9282
PR_BUILD: true
@@ -95,7 +85,7 @@ jobs:
9585
- name: Checkout HEAD
9686
uses: actions/checkout@v6
9787
with:
98-
ref: ${{ github.event.pull_request.head.sha }}
88+
ref: ${{ needs.download-pr-info.outputs.head_sha }}
9989
fetch-depth: 0
10090

10191
- name: Setup Node.js
@@ -149,9 +139,8 @@ jobs:
149139
CDK_ATMOSPHERE_POOL: ${{ vars.CDK_ATMOSPHERE_POOL }}
150140
CDK_ATMOSPHERE_OIDC_ROLE: ${{ vars.CDK_ATMOSPHERE_OIDC_ROLE }}
151141
CDK_ATMOSPHERE_BATCH_SIZE: ${{ vars.CDK_ATMOSPHERE_BATCH_SIZE }}
152-
TARGET_BRANCH_COMMIT: ${{ github.event.pull_request.base.sha }}
153-
SOURCE_BRANCH_COMMIT: ${{ github.event.pull_request.head.sha }}
154-
# GitHub context for preflight check (validates CDK team membership)
142+
TARGET_BRANCH_COMMIT: ${{ needs.download-pr-info.outputs.base_sha }}
143+
SOURCE_BRANCH_COMMIT: ${{ needs.download-pr-info.outputs.head_sha }}
155144
GITHUB_TOKEN: ${{ secrets.PROJEN_GITHUB_TOKEN }}
156145
GITHUB_REPOSITORY: ${{ github.repository }}
157-
PR_NUMBER: ${{ github.event.pull_request.number }}
146+
PR_NUMBER: ${{ needs.download-pr-info.outputs.pr_number }}

0 commit comments

Comments
 (0)