From de674f27634131acc8ce6adb9c6a7a1315f2ffb2 Mon Sep 17 00:00:00 2001 From: Eric He Date: Mon, 27 Jul 2026 16:35:36 -0400 Subject: [PATCH 1/2] ci: wire shared composite actions --- .github/workflows/canary.yml | 14 +++---- .github/workflows/e2e-tests-full.yml | 27 ++++++++----- .github/workflows/e2e-tests.yml | 41 ++++++++++++++----- .github/workflows/pr-ai-review.yml | 60 +++++++++++----------------- .github/workflows/pr-tarball.yml | 18 ++++++++- 5 files changed, 94 insertions(+), 66 deletions(-) diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 941662eac..a90a73488 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -56,20 +56,20 @@ jobs: git config --global user.email "ci@amazon.com" git config --global user.name "CI" - uses: astral-sh/setup-uv@v7 + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + repo: E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ secrets.E2E_AWS_ROLE_ARN }} + role-to-assume: ${{ env.E2E_AWS_ROLE_ARN }} aws-region: ${{ inputs.aws_region || 'us-east-1' }} + unset-current-credentials: true - name: Get AWS Account ID id: aws run: echo "account_id=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_OUTPUT" - - name: Get API keys from Secrets Manager - uses: aws-actions/aws-secretsmanager-get-secrets@v3 - with: - secret-ids: | - E2E,${{ secrets.E2E_SECRET_ARN }} - parse-json-secrets: true - run: npm ci diff --git a/.github/workflows/e2e-tests-full.yml b/.github/workflows/e2e-tests-full.yml index cced4cd71..e1173a8a0 100644 --- a/.github/workflows/e2e-tests-full.yml +++ b/.github/workflows/e2e-tests-full.yml @@ -46,27 +46,28 @@ jobs: git config --global user.email "ci@amazon.com" git config --global user.name "CI" - uses: astral-sh/setup-uv@v7 + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + shared: CDK_REPO_NAME + repo: E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ secrets.E2E_AWS_ROLE_ARN }} + role-to-assume: ${{ env.E2E_AWS_ROLE_ARN }} aws-region: ${{ inputs.aws_region || 'us-east-1' }} + unset-current-credentials: true - name: Get AWS Account ID id: aws run: echo "account_id=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_OUTPUT" - - name: Get API keys from Secrets Manager - uses: aws-actions/aws-secretsmanager-get-secrets@v3 - with: - secret-ids: | - E2E,${{ secrets.E2E_SECRET_ARN }} - parse-json-secrets: true - run: npm ci - name: Build CLI run: npm run build - name: Resolve private CDK repository id: cdk-repo env: - CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + CDK_REPO: ${{ env.CDK_REPO_NAME }} run: | owner="${CDK_REPO%%/*}" repository="${CDK_REPO#*/}" @@ -105,7 +106,7 @@ jobs: git -C /tmp/cdk-repo remote remove origin env: CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} - CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + CDK_REPO: ${{ env.CDK_REPO_NAME }} - name: Revoke GitHub App token if: always() && steps.app-token.outputs.token != '' env: @@ -169,11 +170,17 @@ jobs: git config --global user.email "ci@amazon.com" git config --global user.name "CI" - uses: astral-sh/setup-uv@v7 + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + repo: E2E_AWS_ROLE_ARN - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ secrets.E2E_AWS_ROLE_ARN }} + role-to-assume: ${{ env.E2E_AWS_ROLE_ARN }} aws-region: ${{ inputs.aws_region || 'us-east-1' }} + unset-current-credentials: true - name: Get AWS Account ID id: aws run: echo "account_id=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 3d4f849ba..89303466f 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -41,14 +41,32 @@ jobs: authorize: runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} if: github.event_name == 'workflow_dispatch' || github.event_name == 'pull_request_target' + permissions: + id-token: write + contents: read outputs: is_authorized: ${{ steps.check.outputs.is_authorized }} steps: + # Manual workflow_dispatch is always authorized and never consults the + # allowlist, so only fetch AUTHORIZED_USERS / run the gate for PR events. + - name: Fetch secrets from Secrets Manager + if: github.event_name == 'pull_request_target' + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + repo: AUTHORIZED_USERS - name: Check authorization + id: authz + if: github.event_name == 'pull_request_target' + uses: aws/agentcore-devx-devtools/.github/actions/check-authorized-user@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + subject: ${{ github.event.pull_request.user.login }} + authorized-users: ${{ env.AUTHORIZED_USERS }} + - name: Determine authorization id: check env: EVENT_NAME: ${{ github.event_name }} - AUTHORIZED_USERS: ${{ secrets.AUTHORIZED_USERS }} + IS_AUTHORIZED: ${{ steps.authz.outputs.is-authorized }} # Gate on the PR AUTHOR (whose code this is), NOT github.actor (who triggered the run). # On pull_request_target a trusted actor (e.g. a maintainer pushing to a fork PR) triggering # a run must NOT cause an untrusted author's fork code to execute with our AWS role/secrets. @@ -59,7 +77,7 @@ jobs: echo "is_authorized=true" >> "$GITHUB_OUTPUT" exit 0 fi - if [[ ",$AUTHORIZED_USERS," == *",${PR_AUTHOR},"* ]]; then + if [[ "$IS_AUTHORIZED" == "true" ]]; then echo "✅ PR author ${PR_AUTHOR} is authorized" echo "is_authorized=true" >> "$GITHUB_OUTPUT" else @@ -104,25 +122,26 @@ jobs: git config --global user.email "ci@amazon.com" git config --global user.name "CI" - uses: astral-sh/setup-uv@v7 + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + shared: CDK_REPO_NAME + repo: E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ secrets.E2E_AWS_ROLE_ARN }} + role-to-assume: ${{ env.E2E_AWS_ROLE_ARN }} aws-region: ${{ inputs.aws_region || 'us-east-1' }} + unset-current-credentials: true - name: Get AWS Account ID id: aws run: echo "account_id=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_OUTPUT" - - name: Get API keys from Secrets Manager - uses: aws-actions/aws-secretsmanager-get-secrets@v3 - with: - secret-ids: | - E2E,${{ secrets.E2E_SECRET_ARN }} - parse-json-secrets: true - name: Resolve private CDK repository id: cdk-repo env: - CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + CDK_REPO: ${{ env.CDK_REPO_NAME }} run: | owner="${CDK_REPO%%/*}" repository="${CDK_REPO#*/}" @@ -152,7 +171,7 @@ jobs: env: INPUT_CDK_BRANCH: ${{ inputs.cdk_branch }} CDK_REPO_TOKEN: ${{ steps.app-token.outputs.token }} - CDK_REPO: ${{ secrets.CDK_REPO_NAME }} + CDK_REPO: ${{ env.CDK_REPO_NAME }} - name: Revoke GitHub App token if: always() && steps.app-token.outputs.token != '' env: diff --git a/.github/workflows/pr-ai-review.yml b/.github/workflows/pr-ai-review.yml index 11466364f..604e01811 100644 --- a/.github/workflows/pr-ai-review.yml +++ b/.github/workflows/pr-ai-review.yml @@ -25,43 +25,24 @@ jobs: outputs: authorized: ${{ steps.auth.outputs.authorized }} steps: + # Team membership (agentcore-cli-devs) is checked first, then falls back to + # repo write access — same two-tier logic as before, now via the shared + # composite. With the default GITHUB_TOKEN the team check falls through to + # the collaborator-permission check, matching the previous behavior. - name: Check authorization - id: auth + id: authz if: github.event_name == 'pull_request_target' - uses: actions/github-script@v9 + uses: aws/agentcore-devx-devtools/.github/actions/check-collaborator@31aa3b031a86664e29861d68956e44b07cf21a74 with: - script: | - const user = context.payload.pull_request.user.login; - try { - // Try team membership first (works for org repos) - await github.rest.teams.getMembershipForUserInOrg({ - org: context.repo.owner, - team_slug: 'agentcore-cli-devs', - username: user, - }); - console.log(`${user} is a member of agentcore-cli-devs`); - core.setOutput('authorized', 'true'); - } catch (teamError) { - // Fall back to collaborator write access (works for personal repos) - try { - const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ - owner: context.repo.owner, - repo: context.repo.repo, - username: user, - }); - const hasWriteAccess = ['write', 'admin'].includes(data.permission); - if (hasWriteAccess) { - console.log(`${user} has write access (${data.permission})`); - core.setOutput('authorized', 'true'); - } else { - console.log(`${user} does not have write access (${data.permission}) — skipping review`); - core.setOutput('authorized', 'false'); - } - } catch (collabError) { - console.log(`${user} authorization check failed (${collabError.status}) — skipping review`); - core.setOutput('authorized', 'false'); - } - } + subject: ${{ github.event.pull_request.user.login }} + required-permission: write + team-slug: agentcore-cli-devs + - name: Map authorization result + id: auth + if: github.event_name == 'pull_request_target' + env: + IS_AUTHORIZED: ${{ steps.authz.outputs.is-authorized }} + run: echo "authorized=$IS_AUTHORIZED" >> "$GITHUB_OUTPUT" - name: Auto-authorize workflow_dispatch id: dispatch-auth @@ -128,11 +109,18 @@ jobs: - name: Checkout uses: actions/checkout@v7 + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + repo: HARNESS_AWS_ROLE_ARN, HARNESS_ARN + - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: - role-to-assume: ${{ secrets.HARNESS_AWS_ROLE_ARN }} + role-to-assume: ${{ env.HARNESS_AWS_ROLE_ARN }} aws-region: us-east-1 + unset-current-credentials: true - name: Set up Python 3.12 uses: actions/setup-python@v7 @@ -148,7 +136,7 @@ jobs: - name: Run AI review env: PR_URL: ${{ steps.pr-url.outputs.url }} - HARNESS_ARN: ${{ secrets.HARNESS_ARN }} + HARNESS_ARN: ${{ env.HARNESS_ARN }} run: python .github/harness/harness_review.py - name: Remove agentcore-harness-reviewing label diff --git a/.github/workflows/pr-tarball.yml b/.github/workflows/pr-tarball.yml index e629ba452..db1ae13cf 100644 --- a/.github/workflows/pr-tarball.yml +++ b/.github/workflows/pr-tarball.yml @@ -10,19 +10,33 @@ permissions: jobs: authorize: runs-on: codebuild-agentcore-e2e-${{ github.run_id }}-${{ github.run_attempt }} + permissions: + id-token: write + contents: read outputs: is_authorized: ${{ steps.check.outputs.is_authorized }} steps: + - name: Fetch secrets from Secrets Manager + uses: aws/agentcore-devx-devtools/.github/actions/fetch-secrets@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} + repo: AUTHORIZED_USERS - name: Check authorization + id: authz + uses: aws/agentcore-devx-devtools/.github/actions/check-authorized-user@31aa3b031a86664e29861d68956e44b07cf21a74 + with: + subject: ${{ github.event.pull_request.user.login }} + authorized-users: ${{ env.AUTHORIZED_USERS }} + - name: Determine authorization id: check env: - AUTHORIZED_USERS: ${{ secrets.AUTHORIZED_USERS }} + IS_AUTHORIZED: ${{ steps.authz.outputs.is-authorized }} # Gate on the PR AUTHOR (whose code this npm build runs), NOT github.actor (who triggered the # run). Otherwise a trusted actor pushing to a fork PR would run untrusted fork npm scripts # with the contents:write GITHUB_TOKEN + App token in this job. PR_AUTHOR: ${{ github.event.pull_request.user.login }} run: | - if [[ ",$AUTHORIZED_USERS," == *",${PR_AUTHOR},"* ]]; then + if [[ "$IS_AUTHORIZED" == "true" ]]; then echo "✅ PR author ${PR_AUTHOR} is authorized" echo "is_authorized=true" >> "$GITHUB_OUTPUT" else From e3ee9019ea5903921a517783938a30d57fb1ef77 Mon Sep 17 00:00:00 2001 From: Eric He Date: Mon, 27 Jul 2026 17:38:38 -0400 Subject: [PATCH 2/2] style: format e2e workflows --- .github/workflows/e2e-tests-full.yml | 5 ++++- .github/workflows/e2e-tests.yml | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-tests-full.yml b/.github/workflows/e2e-tests-full.yml index e1173a8a0..9d7ad0689 100644 --- a/.github/workflows/e2e-tests-full.yml +++ b/.github/workflows/e2e-tests-full.yml @@ -51,7 +51,10 @@ jobs: with: role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} shared: CDK_REPO_NAME - repo: E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET + repo: + E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, + E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, + E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 89303466f..1125c8bd1 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -127,7 +127,10 @@ jobs: with: role-arn: ${{ secrets.WORKFLOW_SECRETS_READER_ROLE_ARN }} shared: CDK_REPO_NAME - repo: E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET + repo: + E2E_AWS_ROLE_ARN, E2E_ANTHROPIC_API_KEY, E2E_OPENAI_API_KEY, E2E_GEMINI_API_KEY, E2E_EFS_ACCESS_POINT_ARN, + E2E_S3_ACCESS_POINT_ARN, E2E_FILESYSTEM_SUBNET_ID, E2E_FILESYSTEM_SECURITY_GROUP_ID, E2E_CDP_API_KEY_ID, + E2E_CDP_API_KEY_SECRET, E2E_CDP_WALLET_SECRET - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v6 with: