Skip to content

Commit a8914c2

Browse files
authored
Merge branch 'main' into merge-back/2.239.0
2 parents e83bb46 + 62d40f8 commit a8914c2

File tree

14 files changed

+945
-52
lines changed

14 files changed

+945
-52
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
name: Integration Test deployment (Auto)
2+
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.
5+
#
6+
# SHADOW MODE: This workflow is in shadow mode - failures don't block PR merges.
7+
# Once validated, this will replace the label-based workflow (integration-test-deployment.yml).
8+
9+
on:
10+
pull_request_review:
11+
types: [submitted]
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
15+
cancel-in-progress: true
16+
17+
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+
runs-on: ubuntu-latest
22+
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
27+
steps:
28+
- name: Checkout for path filtering
29+
uses: actions/checkout@v6
30+
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
41+
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 }}
50+
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+
58+
- name: Check if approver is CDK team member
59+
id: check_team
60+
if: steps.check_snapshots.outputs.has_snapshots == 'true'
61+
env:
62+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
63+
APPROVER: ${{ github.event.review.user.login }}
64+
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
67+
if gh api "orgs/aws/teams/aws-cdk-team/memberships/${APPROVER}" --jq '.state' 2>/dev/null | grep -q "active"; then
68+
echo "${APPROVER} is an active CDK team member"
69+
echo "is_member=true" >> $GITHUB_OUTPUT
70+
else
71+
echo "${APPROVER} is not a CDK team member or membership is not active"
72+
echo "is_member=false" >> $GITHUB_OUTPUT
73+
fi
74+
75+
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'
79+
runs-on: codebuild-aws-cdk-github-actions-deployment-integ-runner-${{ github.run_id }}-${{ github.run_attempt }}
80+
# No environment - runs automatically without manual approval
81+
# Shadow mode: workflow reports success even if tests fail
82+
continue-on-error: true
83+
name: 'Deploy integration test snapshots (Auto)'
84+
85+
# Job-level permissions for least privilege
86+
permissions:
87+
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
90+
91+
env:
92+
PR_BUILD: true
93+
94+
steps:
95+
- name: Checkout HEAD
96+
uses: actions/checkout@v6
97+
with:
98+
ref: ${{ github.event.pull_request.head.sha }}
99+
fetch-depth: 0
100+
101+
- name: Setup Node.js
102+
uses: actions/setup-node@v6
103+
with:
104+
node-version: "lts/*"
105+
cache: "yarn"
106+
cache-dependency-path: |
107+
yarn.lock
108+
109+
- name: Set up Docker
110+
uses: docker/setup-buildx-action@v3
111+
112+
- name: Load Docker images
113+
id: docker-cache
114+
uses: actions/cache/restore@v5
115+
with:
116+
path: |
117+
~/.docker-images.tar
118+
key: docker-cache-${{ runner.os }}
119+
120+
- name: Restore Docker images
121+
if: ${{ steps.docker-cache.outputs.cache-hit }}
122+
run: docker image load --input ~/.docker-images.tar
123+
124+
- name: Cache build artifacts
125+
uses: actions/cache@v5
126+
with:
127+
path: |
128+
~/.s3buildcache
129+
key: s3buildcache-${{ runner.os }}
130+
131+
- name: Configure system settings
132+
run: |
133+
(command -v sysctl || sudo apt-get update && sudo apt-get install -y procps) && \
134+
sudo sysctl -w vm.max_map_count=2251954
135+
136+
- name: Install dependencies for Integration Tests
137+
run: yarn install --frozen-lockfile
138+
139+
- name: Build deployment-integ
140+
run: yarn --cwd tools/@aws-cdk/integration-test-deployment build
141+
142+
- name: Build Integration Test packages
143+
run: npx lerna run build --scope="{@aws-cdk/*,@aws-cdk-testing/framework-integ}"
144+
145+
- name: Run integration tests
146+
run: yarn run atmosphere-integ-test
147+
env:
148+
CDK_ATMOSPHERE_ENDPOINT: ${{ vars.CDK_ATMOSPHERE_ENDPOINT }}
149+
CDK_ATMOSPHERE_POOL: ${{ vars.CDK_ATMOSPHERE_POOL }}
150+
CDK_ATMOSPHERE_OIDC_ROLE: ${{ vars.CDK_ATMOSPHERE_OIDC_ROLE }}
151+
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)
155+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
156+
GITHUB_REPOSITORY: ${{ github.repository }}
157+
PR_NUMBER: ${{ github.event.pull_request.number }}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './cfn-props-mixins.generated';
2+
export * from './logs-delivery-mixins.generated';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './bucket';
22
export * from './bucket-policy';
33
export * from './cfn-props-mixins.generated';
4+
export * from './logs-delivery-mixins.generated';

packages/@aws-cdk/mixins-preview/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@
663663
"@aws-cdk/integ-runner": "^2.195.0",
664664
"@aws-cdk/integ-tests-alpha": "0.0.0",
665665
"@aws-cdk/pkglint": "0.0.0",
666-
"@aws-cdk/service-spec-types": "^0.0.218",
666+
"@aws-cdk/service-spec-types": "^0.0.219",
667667
"@aws-cdk/spec2cdk": "0.0.0",
668668
"@cdklabs/tskb": "^0.0.4",
669669
"@cdklabs/typewriter": "^0.0.15",

packages/aws-cdk-lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
},
135135
"devDependencies": {
136136
"@aws-cdk/lambda-layer-kubectl-v31": "^2.1.0",
137-
"@aws-cdk/aws-service-spec": "^0.1.152",
137+
"@aws-cdk/aws-service-spec": "^0.1.153",
138138
"@aws-cdk/cdk-build-tools": "0.0.0",
139139
"@aws-cdk/custom-resource-handlers": "0.0.0",
140140
"@aws-cdk/pkglint": "0.0.0",

tools/@aws-cdk/integration-test-deployment/README.md

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ A tool for running AWS CDK integration tests against changed snapshots using AWS
66

77
This tool automatically detects changed integration test snapshots in the CDK repository and runs them against real AWS environments managed by Atmosphere. It ensures that CDK changes don't break existing functionality by testing them in isolated AWS accounts.
88

9-
This tool is used by the [Integration Test Deployment workflow](../../../.github/workflows/codebuild-pr-deployment-integ.yml).
9+
This tool is used by two workflows:
10+
- [Integration Test Deployment](../../../.github/workflows/integration-test-deployment.yml) - Label-triggered with manual approval
11+
- [Integration Test Deployment (Auto)](../../../.github/workflows/integration-test-deployment-auto.yml) - Auto-triggered on CDK team approval (shadow mode)
1012

1113
## Features
1214

1315
- **Automatic Change Detection**: Filters through the changed files to detect the integration tests
16+
- **Preflight Check**: Validates that the PR is approved by a CDK team member before running tests
1417
- **AWS Environment Management**: Integrates with AWS Atmosphere for temporary AWS account allocation
1518
- **Isolated Testing**: Each test run gets its own AWS environment with proper credentials
1619
- **Cleanup**: Automatically releases AWS resources after test completion
@@ -21,10 +24,26 @@ Authenticating to assume atmosphere role through OIDC token.
2124

2225
## Environment Variables
2326

24-
| Variable | Description
25-
|----------|-------------
26-
| `CDK_ATMOSPHERE_ENDPOINT` | AWS Atmosphere service endpoint
27-
| `CDK_ATMOSPHERE_POOL` | AWS account pool name for allocation
27+
| Variable | Description |
28+
|----------|-------------|
29+
| `CDK_ATMOSPHERE_ENDPOINT` | AWS Atmosphere service endpoint |
30+
| `CDK_ATMOSPHERE_POOL` | AWS account pool name for allocation |
31+
| `CDK_ATMOSPHERE_OIDC_ROLE` | IAM role ARN for OIDC authentication |
32+
| `CDK_ATMOSPHERE_BATCH_SIZE` | (Optional) Number of tests to run in parallel |
33+
| `TARGET_BRANCH_COMMIT` | Base branch commit SHA for diff |
34+
| `SOURCE_BRANCH_COMMIT` | PR head commit SHA for diff |
35+
| `GITHUB_TOKEN` | (Optional) GitHub token for preflight check |
36+
| `GITHUB_REPOSITORY` | (Optional) Repository in format `owner/repo` |
37+
| `PR_NUMBER` | (Optional) Pull request number |
38+
39+
## Preflight Check
40+
41+
When GitHub context is provided (`GITHUB_TOKEN`, `GITHUB_REPOSITORY`, `PR_NUMBER`), the tool performs a preflight check before running integration tests:
42+
43+
1. **Snapshot Changes**: Verifies the PR contains `.snapshot` file changes
44+
2. **Authorization**: Checks if the PR is approved by a CDK team member (`@aws/aws-cdk-team`)
45+
46+
If the preflight check fails, the tool exits gracefully without running tests. This prevents unnecessary test runs on PRs that haven't been reviewed by the CDK team yet.
2847

2948
## Development
3049

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
11
#!/usr/bin/env node
2-
import { deployIntegTests } from '../lib/integration-test-runner';
3-
4-
const endpoint = process.env.CDK_ATMOSPHERE_ENDPOINT;
5-
const pool = process.env.CDK_ATMOSPHERE_POOL;
6-
const atmosphereRoleArn = process.env.CDK_ATMOSPHERE_OIDC_ROLE;
7-
const batchSize = process.env.CDK_ATMOSPHERE_BATCH_SIZE !== undefined ? Number.parseInt(process.env.CDK_ATMOSPHERE_BATCH_SIZE) : undefined;
8-
9-
if (!endpoint) {
10-
throw new Error('CDK_ATMOSPHERE_ENDPOINT environment variable is required');
11-
}
12-
13-
if (!pool) {
14-
throw new Error('CDK_ATMOSPHERE_POOL environment variable is required');
15-
}
16-
17-
if (!atmosphereRoleArn) {
18-
throw new Error('CDK_ATMOSPHERE_OIDC_ROLE environment variable is required');
19-
}
20-
21-
deployIntegTests({ atmosphereRoleArn, endpoint, pool, batchSize }).catch((e) => {
2+
import { main } from '../lib/main';
3+
4+
main({
5+
endpoint: process.env.CDK_ATMOSPHERE_ENDPOINT,
6+
pool: process.env.CDK_ATMOSPHERE_POOL,
7+
atmosphereRoleArn: process.env.CDK_ATMOSPHERE_OIDC_ROLE,
8+
batchSize: process.env.CDK_ATMOSPHERE_BATCH_SIZE !== undefined ? Number.parseInt(process.env.CDK_ATMOSPHERE_BATCH_SIZE) : undefined,
9+
githubToken: process.env.GITHUB_TOKEN,
10+
githubRepository: process.env.GITHUB_REPOSITORY,
11+
prNumber: process.env.PR_NUMBER,
12+
}).catch((e) => {
2213
console.error(e);
2314
process.exitCode = 1;
2415
});
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { deployIntegTests } from './integration-test-runner';
2+
import { shouldRunIntegTests } from './preflight';
3+
4+
export interface MainConfig {
5+
endpoint?: string;
6+
pool?: string;
7+
atmosphereRoleArn?: string;
8+
batchSize?: number;
9+
githubToken?: string;
10+
githubRepository?: string;
11+
prNumber?: string;
12+
}
13+
14+
/**
15+
* Main entry point for integration test deployment.
16+
* Extracted for testability.
17+
*/
18+
export async function main(config: MainConfig): Promise<void> {
19+
const { endpoint, pool, atmosphereRoleArn, batchSize, githubToken, githubRepository, prNumber } = config;
20+
21+
// Run preflight check if GitHub context is available
22+
if (githubToken && githubRepository && prNumber) {
23+
// Validate repository format
24+
const repoParts = githubRepository.split('/');
25+
if (repoParts.length !== 2 || !repoParts[0] || !repoParts[1]) {
26+
throw new Error(`Invalid GITHUB_REPOSITORY format: "${githubRepository}". Expected format: owner/repo`);
27+
}
28+
const [owner, repo] = repoParts;
29+
30+
// Validate PR number
31+
const parsedPrNumber = parseInt(prNumber, 10);
32+
if (isNaN(parsedPrNumber) || parsedPrNumber <= 0) {
33+
throw new Error(`Invalid PR number: "${prNumber}". Expected a positive integer.`);
34+
}
35+
36+
console.log(`Running preflight check for PR #${parsedPrNumber}...`);
37+
38+
const preflight = await shouldRunIntegTests({
39+
githubToken,
40+
owner,
41+
repo,
42+
prNumber: parsedPrNumber,
43+
});
44+
45+
console.log(`Preflight result: ${preflight.reason}`);
46+
47+
if (!preflight.shouldRun) {
48+
console.log('Skipping integration test deployment.');
49+
return;
50+
}
51+
} else {
52+
console.log('GitHub context not available, skipping preflight check (manual run or workflow_dispatch)');
53+
}
54+
55+
// Validate required environment variables for deployment
56+
if (!endpoint) {
57+
throw new Error('CDK_ATMOSPHERE_ENDPOINT environment variable is required');
58+
}
59+
60+
if (!pool) {
61+
throw new Error('CDK_ATMOSPHERE_POOL environment variable is required');
62+
}
63+
64+
if (!atmosphereRoleArn) {
65+
throw new Error('CDK_ATMOSPHERE_OIDC_ROLE environment variable is required');
66+
}
67+
68+
await deployIntegTests({ atmosphereRoleArn, endpoint, pool, batchSize });
69+
}

0 commit comments

Comments
 (0)