From 146922f74846b607e9548f59fe4a70b407774e3c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 08:11:38 +0000 Subject: [PATCH 1/4] Initial plan From 9ca91a877077eee25463ba07af239498aaa86e5c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 08:16:13 +0000 Subject: [PATCH 2/4] Plan immutable action-mode references Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .github/aw/actions-lock.json | 5 - .github/workflows/release.lock.yml | 168 ++++++++++++++++++--------- pkg/actionpins/data/action_pins.json | 5 + pkg/workflow/data/action_pins.json | 5 + 4 files changed, 126 insertions(+), 57 deletions(-) diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index e3570afd932..fb07dc07b0f 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -148,11 +148,6 @@ "version": "v4.38.0", "sha": "b96794f015dfd88f77b49b1c93e0fa7110f94c63" }, - "github/gh-aw-actions/setup@v0.89.1": { - "repo": "github/gh-aw-actions/setup", - "version": "v0.89.1", - "sha": "4537e5924c9abb366dcbece06750e498e0218fae" - }, "github/stale-repos@v9.0.17": { "repo": "github/stale-repos", "version": "v9.0.17", diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 27179f394a9..cb2991f6ba7 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -1,6 +1,6 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"07bd4044f0ed6481733339f7b9ec8d095249a608f80b15f991bf336c049c84b9","body_hash":"646353d7bb4e5523bc85349c2cce38188190095a303f83cc95961ff145a47043","compiler_version":"v0.89.1","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.83"}} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"anchore/sbom-action","sha":"3ad7283483fc7af8ff2b4ea19663c2d5ca935e26","version":"v0.24.2"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/login-action","sha":"dbcb813823bdd20940b903addbd779551569679f","version":"v4.6.0"},{"repo":"docker/metadata-action","sha":"dc802804100637a589fabce1cb79ff13a1411302","version":"v6.2.0"},{"repo":"docker/setup-buildx-action","sha":"37fe631027851001ddb9b187196cc803df7f5f0e","version":"v4.3.0"},{"repo":"github/gh-aw-actions/setup","sha":"4537e5924c9abb366dcbece06750e498e0218fae","version":"v0.89.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.14","digest":"sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14","digest":"sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.14","digest":"sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.20","digest":"sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.20@sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23"},{"image":"ghcr.io/github/github-mcp-server:v1.12.1","digest":"sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560","pinned_image":"ghcr.io/github/github-mcp-server:v1.12.1@sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["missing_data","missing_tool","noop","update_release"]}]} -# This file was automatically generated by gh-aw (v0.89.1). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"07bd4044f0ed6481733339f7b9ec8d095249a608f80b15f991bf336c049c84b9","body_hash":"646353d7bb4e5523bc85349c2cce38188190095a303f83cc95961ff145a47043","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.83"}} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"anchore/sbom-action","sha":"3ad7283483fc7af8ff2b4ea19663c2d5ca935e26","version":"v0.24.2"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/login-action","sha":"dbcb813823bdd20940b903addbd779551569679f","version":"v4.6.0"},{"repo":"docker/metadata-action","sha":"dc802804100637a589fabce1cb79ff13a1411302","version":"v6.2.0"},{"repo":"docker/setup-buildx-action","sha":"37fe631027851001ddb9b187196cc803df7f5f0e","version":"v4.3.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.15","digest":"sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.15@sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15","digest":"sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15@sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.15","digest":"sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.15@sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.20","digest":"sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.20@sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23","pinned_image":"ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23"},{"image":"ghcr.io/github/github-mcp-server:v1.12.1","digest":"sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560","pinned_image":"ghcr.io/github/github-mcp-server:v1.12.1@sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560"}],"mcp_servers":[{"name":"github","tools":["get_commit","get_file_contents","get_latest_release","get_me","get_pull_request","get_pull_request_comments","get_pull_request_diff","get_pull_request_files","get_pull_request_review_comments","get_pull_request_reviews","get_pull_request_status","get_release_by_tag","get_tag","issue_read","list_branches","list_commits","list_issue_types","list_issues","list_pull_requests","list_releases","list_starred_repositories","list_tags","pull_request_read","search_code","search_issues","search_pull_requests","search_repositories"]},{"name":"safeoutputs","tools":["missing_data","missing_tool","noop","update_release"]}]} +# This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # # ___ _ _ # / _ \ | | (_) @@ -55,12 +55,11 @@ # - docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 # - docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0 # - docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 -# - github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5 -# - ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5 +# - ghcr.io/github/gh-aw-firewall/agent:0.28.15@sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15@sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c +# - ghcr.io/github/gh-aw-firewall/squid:0.28.15@sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161 # - ghcr.io/github/gh-aw-mcpg:v0.4.20@sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684 # - ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23 # - ghcr.io/github/github-mcp-server:v1.12.1@sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560 @@ -111,7 +110,6 @@ jobs: permissions: actions: read contents: read - issues: write env: GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }} GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} @@ -132,9 +130,17 @@ jobs: setup-trace-id: ${{ steps.setup.outputs.trace-id }} stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -145,7 +151,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" @@ -157,14 +163,13 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'auto' }} GH_AW_INFO_VERSION: "1.0.83" GH_AW_INFO_AGENT_VERSION: "1.0.83" - GH_AW_INFO_CLI_VERSION: "v0.89.1" GH_AW_INFO_WORKFLOW_NAME: "Release" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["*.grafana.net","*.sentry.io","defaults","github.github.com","node"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_INFO_AGENT_RUNTIME: "cloud-hypervisor" @@ -246,6 +251,7 @@ jobs: sparse-checkout: | .github .agents + actions/setup .claude .codex .gemini @@ -272,20 +278,6 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'check_workflow_timestamp_api.cjs')); await main(); - - name: Check compile-agentic version - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 - env: - GH_AW_COMPILED_VERSION: "v0.89.1" - GH_AW_BLOCKED_VERSION_REPORT_AS_ISSUE: "true" - GH_AW_WORKFLOW_NAME: "Release" - with: - script: | - const path = require('path'); - const actionsDir = path.join(process.env.RUNNER_TEMP, 'gh-aw', 'actions'); - const { setupGlobals } = require(path.join(actionsDir, 'setup_globals.cjs')); - setupGlobals(core, github, context, exec, io, getOctokit); - const { main } = require(path.join(actionsDir, 'check_version_updates.cjs')); - await main(); - name: Log runtime features if: ${{ contains(toJSON(vars), '"GH_AW_RUNTIME_FEATURES":') }} run: bash "${RUNNER_TEMP}/gh-aw/actions/log_runtime_features_summary.sh" @@ -434,8 +426,8 @@ jobs: outputs: agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }} ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }} - aic: ${{ steps.parse-mcp-gateway.outputs.aic }} - ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }} + aic: ${{ steps.parse-token-usage.outputs.aic }} + ambient_context: ${{ steps.parse-token-usage.outputs.ambient_context }} checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }} has_patch: ${{ steps.collect_output.outputs.has_patch }} @@ -456,9 +448,17 @@ jobs: shell_expansion_guard_rejected: ${{ steps.detect-agent-errors.outputs.shell_expansion_guard_rejected || 'false' }} unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -468,13 +468,13 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths env: GH_AW_RUNNER_TOOL_CACHE: ${{ runner.tool_cache }} - run: | + run: | # zizmor: ignore[github-env] - runner.tool_cache is set by GitHub Actions, not user input. if [ -z "${RUNNER_TOOL_CACHE:-}" ]; then echo "RUNNER_TOOL_CACHE=${GH_AW_RUNNER_TOOL_CACHE}" >> "$GITHUB_ENV" fi @@ -538,7 +538,7 @@ jobs: run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - GH_AW_COMPILED_VERSION: v0.89.1 + GH_AW_COMPILED_VERSION: dev - name: Grant runner access to KVM run: bash "${RUNNER_TEMP}/gh-aw/actions/cloud_hypervisor_kvm_access.sh" - name: Check host eligibility for cloud-hypervisor @@ -546,10 +546,10 @@ jobs: - name: Download and verify cloud-hypervisor bundle id: cloud-hypervisor-bundle env: - GH_AW_AWF_VERSION: v0.28.14 + GH_AW_AWF_VERSION: v0.28.15 run: bash "${RUNNER_TEMP}/gh-aw/actions/cloud_hypervisor_setup_bundle.sh" - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.14 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.15 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -578,7 +578,7 @@ jobs: GH_AW_SKILL_DIR: ".github/skills" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh" - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5 ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5 ghcr.io/github/gh-aw-mcpg:v0.4.20@sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684 ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23 ghcr.io/github/github-mcp-server:v1.12.1@sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.15@sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15@sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c ghcr.io/github/gh-aw-firewall/squid:0.28.15@sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161 ghcr.io/github/gh-aw-mcpg:v0.4.20@sha256:980ea7aa4fb07e444f0e2c6e3af5aff8b45e4e415d617667b8ba064a1768b684 ghcr.io/github/gh-aw-node@sha256:0daa8971fa4732b647150cb6524a6b0804b68d5d24f6f58b5dd1af23bd63fb23 ghcr.io/github/github-mcp-server:v1.12.1@sha256:0ba840c46a237879c8300e7fddb0b6347f20e029ccb9cbe2ce4a943daa1ff560 - name: Prepare Safe Outputs Directories run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" @@ -924,7 +924,7 @@ jobs: if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then GH_AW_MAX_AI_CREDITS="1000" fi - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.14/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.grafana.net\",\"*.sentry.io\",\"api.npms.io\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"bun.sh\",\"cdn.jsdelivr.net\",\"crl.geotrust.com\",\"crl.globalsign.com\",\"crl.identrust.com\",\"crl.sectigo.com\",\"crl.thawte.com\",\"crl.usertrust.com\",\"crl.verisign.com\",\"crl3.digicert.com\",\"crl4.digicert.com\",\"crls.ssl.com\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"github.github.com\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"json-schema.org\",\"json.schemastore.org\",\"jsr.io\",\"keyserver.ubuntu.com\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"ocsp.digicert.com\",\"ocsp.geotrust.com\",\"ocsp.globalsign.com\",\"ocsp.identrust.com\",\"ocsp.sectigo.com\",\"ocsp.ssl.com\",\"ocsp.thawte.com\",\"ocsp.usertrust.com\",\"ocsp.verisign.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"ppa.launchpad.net\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"],\"isolation\":true,\"topologyAttach\":[\"awmg-mcpg\"]},\"filesystem\":{\"allowWrite\":[\"/tmp/gh-aw/agent\",\"/tmp/gh-aw/sandbox/agent/logs\",\"/workspace\",\"/workspace/.awf-home\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.14,squid=sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5,agent=sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98,api-proxy=sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5,cli-proxy=sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34\",\"agentTimeout\":20},\"cloudHypervisor\":{\"previewEnabled\":true,\"mountPolicy\":\"workspace-and-tool-cache\",\"vcpuCount\":2,\"memoryMib\":4096},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.15/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.grafana.net\",\"*.sentry.io\",\"api.npms.io\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"bun.sh\",\"cdn.jsdelivr.net\",\"crl.geotrust.com\",\"crl.globalsign.com\",\"crl.identrust.com\",\"crl.sectigo.com\",\"crl.thawte.com\",\"crl.usertrust.com\",\"crl.verisign.com\",\"crl3.digicert.com\",\"crl4.digicert.com\",\"crls.ssl.com\",\"deb.nodesource.com\",\"deno.land\",\"esm.sh\",\"get.pnpm.io\",\"github.github.com\",\"googleapis.deno.dev\",\"googlechromelabs.github.io\",\"json-schema.org\",\"json.schemastore.org\",\"jsr.io\",\"keyserver.ubuntu.com\",\"nodejs.org\",\"npm.pkg.github.com\",\"npmjs.com\",\"npmjs.org\",\"ocsp.digicert.com\",\"ocsp.geotrust.com\",\"ocsp.globalsign.com\",\"ocsp.identrust.com\",\"ocsp.sectigo.com\",\"ocsp.ssl.com\",\"ocsp.thawte.com\",\"ocsp.usertrust.com\",\"ocsp.verisign.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"ppa.launchpad.net\",\"registry.bower.io\",\"registry.npmjs.com\",\"registry.npmjs.org\",\"registry.yarnpkg.com\",\"repo.yarnpkg.com\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"skimdb.npmjs.com\",\"storage.googleapis.com\",\"telemetry.vercel.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\",\"www.npmjs.com\",\"www.npmjs.org\",\"yarnpkg.com\"],\"isolation\":true,\"topologyAttach\":[\"awmg-mcpg\"]},\"filesystem\":{\"allowWrite\":[\"/tmp/gh-aw/agent\",\"/tmp/gh-aw/sandbox/agent/logs\",\"/workspace\",\"/workspace/.awf-home\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.15,squid=sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161,agent=sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d,api-proxy=sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c,cli-proxy=sha256:0f7c2e2b61c7241b16c61a778a22115d17fc6bff777fb55c88c787579ee1bcea\",\"agentTimeout\":20},\"cloudHypervisor\":{\"previewEnabled\":true,\"mountPolicy\":\"workspace-and-tool-cache\",\"vcpuCount\":2,\"memoryMib\":4096},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -956,7 +956,7 @@ jobs: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.89.1 + GH_AW_VERSION: dev GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1085,6 +1085,7 @@ jobs: run: bash "${RUNNER_TEMP}/gh-aw/actions/print_firewall_logs.sh" - name: Parse token usage for step summary if: always() + id: parse-token-usage continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 with: @@ -1148,6 +1149,7 @@ jobs: /tmp/gh-aw/redacted-urls.log /tmp/gh-aw/mcp-logs/ /tmp/gh-aw/agent_usage.json + /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/agent-stdio.log /tmp/gh-aw/pre-agent-audit.txt /tmp/gh-aw/github_rate_limits.jsonl @@ -1350,9 +1352,17 @@ jobs: tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} total_count: ${{ steps.missing_tool.outputs.total_count }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1362,7 +1372,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -2030,9 +2040,17 @@ jobs: outputs: aic: ${{ steps.parse-mcp-gateway.outputs.aic }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2042,7 +2060,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -2067,7 +2085,7 @@ jobs: rm -rf /tmp/gh-aw/sandbox/firewall/logs rm -rf /tmp/gh-aw/sandbox/firewall/audit - name: Download container images - run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.14@sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98 ghcr.io/github/gh-aw-firewall/api-proxy:0.28.14@sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5 ghcr.io/github/gh-aw-firewall/squid:0.28.14@sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5 + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.28.15@sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d ghcr.io/github/gh-aw-firewall/api-proxy:0.28.15@sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c ghcr.io/github/gh-aw-firewall/squid:0.28.15@sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161 - name: Prepare evals files run: | mkdir -p /tmp/gh-aw/evals @@ -2102,9 +2120,9 @@ jobs: run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" env: GH_HOST: github.com - GH_AW_COMPILED_VERSION: v0.89.1 + GH_AW_COMPILED_VERSION: dev - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.14 --rootless + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.28.15 --rootless - name: Execute GitHub Copilot CLI if: always() continue-on-error: true @@ -2139,7 +2157,7 @@ jobs: if [[ ! "$GH_AW_MAX_AI_CREDITS" =~ ^[0-9]+$ ]]; then GH_AW_MAX_AI_CREDITS="400" fi - printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.14/awf-config.schema.json\",\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.14,squid=sha256:2ce8df3abf3e9b76e9c0cf5863da41f1ab3f89b20ad14b988806ab89e7bf2cd5,agent=sha256:f7df036c86575527b61f3f7df91c4412349a12b2a74988d929eafa2999230c98,api-proxy=sha256:6f95e2234dd9bd6333a8ff28ccea7ecf0204acd4a09108723844dbd2bf6268c5,cli-proxy=sha256:3a379c5e96e29499c815e9dd2a71334d01c326a9b73991c76544fda9cae35c34\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.28.15/awf-config.schema.json\",\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-6\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"detection\":[\"small\"],\"evals\":[\"small\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-3.7-flash\":[\"copilot/gemini-3.7*flash*\",\"google/gemini-3.7*flash*\",\"gemini/gemini-3.7*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"gpt-6\":[\"copilot/gpt-6*\",\"openai/gpt-6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-6\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.28.15,squid=sha256:0006cecbfcc0363afb00a306e30e8991b02cc1a52b77be2f6616000c01cb9161,agent=sha256:9f13ae19ceac89554ad7b2d07b68135f40664721f811cb4df05b0eb372af3a5d,api-proxy=sha256:0410a07cd39dfd086ad2f4f1a22c36fff293696a4675c7e2e46a90754131122c,cli-proxy=sha256:0f7c2e2b61c7241b16c61a778a22115d17fc6bff777fb55c88c787579ee1bcea\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json" GH_AW_DOCKER_HOST="" @@ -2176,7 +2194,7 @@ jobs: GH_AW_PHASE: evals GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_TIMEOUT_MINUTES: 20 - GH_AW_VERSION: v0.89.1 + GH_AW_VERSION: dev GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -2251,9 +2269,21 @@ jobs: name: evals path: /tmp/gh-aw/evals.jsonl if-no-files-found: ignore + - name: Restore actions folder + if: always() + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions/setup + sparse-checkout-cone-mode: true + clean: false + persist-credentials: false pre_activation: runs-on: ubuntu-slim + permissions: + contents: read env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} outputs: @@ -2263,9 +2293,17 @@ jobs: setup-span-id: ${{ steps.setup.outputs.span-id }} setup-trace-id: ${{ steps.setup.outputs.trace-id }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2273,7 +2311,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -2301,9 +2339,17 @@ jobs: env: GH_AW_RUNTIME_FEATURES: ${{ vars.GH_AW_RUNTIME_FEATURES }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2313,7 +2359,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Checkout repository uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 @@ -2353,6 +2399,16 @@ jobs: setupGlobals(core, github, context, exec, io, getOctokit); const { main } = require(path.join(actionsDir, 'push_experiment_state.cjs')); await main(); + - name: Restore actions folder + if: always() + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions/setup + sparse-checkout-cone-mode: true + clean: false + persist-credentials: false push_tag: needs: @@ -2674,9 +2730,17 @@ jobs: process_safe_outputs_status: ${{ steps.process_safe_outputs.outputs.status }} process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} steps: + - name: Checkout actions folder + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: github/gh-aw + sparse-checkout: | + actions + clean: false + persist-credentials: false - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@4537e5924c9abb366dcbece06750e498e0218fae # v0.89.1 + uses: ./actions/setup with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2686,7 +2750,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Release" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/release.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.83" - GH_AW_INFO_AWF_VERSION: "v0.28.14" + GH_AW_INFO_AWF_VERSION: "v0.28.15" GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" diff --git a/pkg/actionpins/data/action_pins.json b/pkg/actionpins/data/action_pins.json index fb07dc07b0f..e3570afd932 100644 --- a/pkg/actionpins/data/action_pins.json +++ b/pkg/actionpins/data/action_pins.json @@ -148,6 +148,11 @@ "version": "v4.38.0", "sha": "b96794f015dfd88f77b49b1c93e0fa7110f94c63" }, + "github/gh-aw-actions/setup@v0.89.1": { + "repo": "github/gh-aw-actions/setup", + "version": "v0.89.1", + "sha": "4537e5924c9abb366dcbece06750e498e0218fae" + }, "github/stale-repos@v9.0.17": { "repo": "github/stale-repos", "version": "v9.0.17", diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index fb07dc07b0f..e3570afd932 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -148,6 +148,11 @@ "version": "v4.38.0", "sha": "b96794f015dfd88f77b49b1c93e0fa7110f94c63" }, + "github/gh-aw-actions/setup@v0.89.1": { + "repo": "github/gh-aw-actions/setup", + "version": "v0.89.1", + "sha": "4537e5924c9abb366dcbece06750e498e0218fae" + }, "github/stale-repos@v9.0.17": { "repo": "github/stale-repos", "version": "v9.0.17", From d0a6a17d1af27307f3c33d97ba1b4c7b073e9f07 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 08:30:48 +0000 Subject: [PATCH 3/4] Require immutable action-mode refs Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- pkg/actionpins/data/action_pins.json | 5 - pkg/workflow/action_reference.go | 98 +++++++++++++++----- pkg/workflow/action_reference_test.go | 75 ++++++++++----- pkg/workflow/compiler_custom_actions_test.go | 43 +++++---- pkg/workflow/compiler_yaml_test.go | 2 +- pkg/workflow/data/action_pins.json | 5 - 6 files changed, 157 insertions(+), 71 deletions(-) diff --git a/pkg/actionpins/data/action_pins.json b/pkg/actionpins/data/action_pins.json index e3570afd932..fb07dc07b0f 100644 --- a/pkg/actionpins/data/action_pins.json +++ b/pkg/actionpins/data/action_pins.json @@ -148,11 +148,6 @@ "version": "v4.38.0", "sha": "b96794f015dfd88f77b49b1c93e0fa7110f94c63" }, - "github/gh-aw-actions/setup@v0.89.1": { - "repo": "github/gh-aw-actions/setup", - "version": "v0.89.1", - "sha": "4537e5924c9abb366dcbece06750e498e0218fae" - }, "github/stale-repos@v9.0.17": { "repo": "github/stale-repos", "version": "v9.0.17", diff --git a/pkg/workflow/action_reference.go b/pkg/workflow/action_reference.go index 9d771838380..8e656d574fd 100644 --- a/pkg/workflow/action_reference.go +++ b/pkg/workflow/action_reference.go @@ -3,8 +3,10 @@ package workflow import ( "context" "fmt" + "path" "strings" + "github.com/github/gh-aw/pkg/gitutil" "github.com/github/gh-aw/pkg/logger" ) @@ -32,8 +34,8 @@ const ( // - For dev mode: "./actions/setup" (local path) // - For release mode with resolver: "github/gh-aw/actions/setup@ # " (SHA-pinned) // - For release mode without resolver: "github/gh-aw/actions/setup@" (tag-based, SHA resolved later) -// - For action mode with resolver: "github/gh-aw-actions/setup@ # " (SHA-pinned) -// - For action mode without resolver: "github/gh-aw-actions/setup@" (tag-based, SHA resolved later) +// - For action mode with resolver or embedded pin: "github/gh-aw-actions/setup@ # " (SHA-pinned) +// - For action mode without a resolved pin: "" (fail closed rather than emitting a mutable reference) // - Falls back to local path if version is invalid in release/action mode func ResolveSetupActionReference(ctx context.Context, actionMode ActionMode, version string, actionTag string, resolver SHAResolver) string { return resolveSetupActionRef(ctx, actionMode, version, actionTag, resolver, "") @@ -68,14 +70,14 @@ func resolveSetupActionModeRef(ctx context.Context, actionTag string, version st if !ok { return localPath } - actionRepo := actionsOrgRepo + "/setup" + actionRepo := path.Join(actionsOrgRepo, "setup") remoteRef := fmt.Sprintf("%s@%s", actionRepo, tag) - ref := tryResolveSetupSHA(ctx, resolver, actionRepo, tag, remoteRef, "Action mode") + ref := resolveRequiredActionModePin(ctx, resolver, actionRepo, tag, remoteRef) if ref != "" { return ref } - actionRefLog.Printf("Action mode: using tag-based external actions repo reference: %s (SHA will be resolved later)", remoteRef) - return remoteRef + actionRefLog.Printf("Action mode: refusing to emit mutable external actions repo reference: %s", remoteRef) + return "" } func resolveSetupReleaseModeRef(ctx context.Context, actionTag string, version string, resolver SHAResolver, localPath string) string { @@ -84,7 +86,7 @@ func resolveSetupReleaseModeRef(ctx context.Context, actionTag string, version s return localPath } actionPath := strings.TrimPrefix(localPath, "./") - actionRepo := fmt.Sprintf("%s/%s", GitHubOrgRepo, actionPath) + actionRepo := path.Join(GitHubOrgRepo, actionPath) remoteRef := fmt.Sprintf("%s@%s", actionRepo, tag) ref := tryResolveSetupSHA(ctx, resolver, actionRepo, tag, remoteRef, "Release mode") if ref != "" { @@ -112,6 +114,10 @@ func tryResolveSetupSHA(ctx context.Context, resolver SHAResolver, actionRepo, t } sha, err := resolver.ResolveSHA(ctx, actionRepo, tag) if err == nil && sha != "" { + if !gitutil.IsValidFullSHA(sha) { + actionRefLog.Printf("Failed to resolve full SHA for %s@%s: resolver returned %q", actionRepo, tag, sha) + return "" + } pinnedRef := formatActionReference(actionRepo, sha, tag) actionRefLog.Printf("%s: resolved %s to SHA-pinned reference: %s", modeLabel, remoteRef, pinnedRef) return pinnedRef @@ -122,13 +128,47 @@ func tryResolveSetupSHA(ctx context.Context, resolver SHAResolver, actionRepo, t return "" } +func resolveRequiredActionModePin(ctx context.Context, resolver SHAResolver, actionRepo, tag, remoteRef string) string { + if ref := tryResolveSetupSHA(ctx, resolver, actionRepo, tag, remoteRef, "Action mode"); ref != "" { + return ref + } + ref, err := getActionPinWithData(actionRepo, tag, actionModePinData(&WorkflowData{Ctx: ctx})) + if err != nil { + actionRefLog.Printf("Action mode: failed to pin action %s@%s: %v", actionRepo, tag, err) + return "" + } + if isFullSHAPinnedActionRef(ref) { + actionRefLog.Printf("Action mode: resolved %s to SHA-pinned reference: %s", remoteRef, ref) + return ref + } + if ref != "" { + actionRefLog.Printf("Action mode: refusing non-full-SHA action reference: %s", ref) + } + return "" +} + +func isFullSHAPinnedActionRef(ref string) bool { + _, after, ok := strings.Cut(ref, "@") + if !ok { + return false + } + actionRef := strings.TrimSpace(after) + if before, _, ok := strings.Cut(actionRef, " "); ok { + actionRef = before + } + if before, _, ok := strings.Cut(actionRef, "#"); ok { + actionRef = before + } + return gitutil.IsValidFullSHA(actionRef) +} + // resolveActionReference converts a local action path to the appropriate reference // based on the current action mode (dev vs release vs action). // If action-tag is specified in features, it overrides the mode check and enables action mode behavior // (using the github/gh-aw-actions external repository). // For dev mode: returns the local path as-is (e.g., "./actions/create-issue") // For release mode: converts to SHA-pinned remote reference (e.g., "github/gh-aw/actions/create-issue@SHA # tag") -// For action mode: converts to SHA-pinned reference in external repo if possible (e.g., "github/gh-aw-actions/create-issue@SHA # version") +// For action mode: converts to SHA-pinned reference in external repo, or "" when no full SHA is available func (c *Compiler) resolveActionReference(localActionPath string, data *WorkflowData) string { hasActionTag, frontmatterActionTag := getFrontmatterActionTag(data) @@ -260,8 +300,7 @@ func (c *Compiler) convertToRemoteActionRef(localPath string, data *WorkflowData // in the external github/gh-aw-actions repository. // Example: "./actions/create-issue" -> "github/gh-aw-actions/create-issue@ # v1.0.0" // -// If SHA resolution fails (no resolver or pin not available), falls back to version-tagged reference: -// Example: "./actions/create-issue" -> "github/gh-aw-actions/create-issue@v1.0.0" +// If SHA resolution fails (no resolver or pin not available), returns "" rather than a mutable tag reference. func (c *Compiler) convertToExternalActionsRef(localPath string, data *WorkflowData) string { // Strip the leading "./" prefix actionPath := strings.TrimPrefix(localPath, "./") @@ -290,22 +329,35 @@ func (c *Compiler) convertToExternalActionsRef(localPath string, data *WorkflowD } // Construct the external actions reference: /action-name@tag - actionRepo := fmt.Sprintf("%s/%s", c.effectiveActionsRepo(), actionName) + actionRepo := path.Join(c.effectiveActionsRepo(), actionName) remoteRef := fmt.Sprintf("%s@%s", actionRepo, tag) // Try to resolve the SHA using action pins - if data != nil { - pinnedRef, err := getActionPinWithData(actionRepo, tag, data) - if err != nil { - // Log and fall through to tag-based reference (action mode is not strict) - actionRefLog.Printf("Failed to pin action %s@%s: %v, falling back to tag-based reference", actionRepo, tag, err) - } else if pinnedRef != "" { - actionRefLog.Printf("Action mode: resolved %s to SHA-pinned reference: %s", remoteRef, pinnedRef) - return pinnedRef - } + pinData := actionModePinData(data) + if pinData.Ctx == nil { + pinData.Ctx = c.ctx + } + pinnedRef, err := getActionPinWithData(actionRepo, tag, pinData) + if err != nil { + actionRefLog.Printf("Action mode: failed to pin action %s@%s: %v", actionRepo, tag, err) + return "" } + if isFullSHAPinnedActionRef(pinnedRef) { + actionRefLog.Printf("Action mode: resolved %s to SHA-pinned reference: %s", remoteRef, pinnedRef) + return pinnedRef + } + if pinnedRef != "" { + actionRefLog.Printf("Action mode: refusing non-full-SHA action reference: %s", pinnedRef) + } + actionRefLog.Printf("Action mode: refusing to emit mutable external actions repo reference: %s", remoteRef) + return "" +} - // If SHA resolution unavailable or pin not found, return tag-based reference - actionRefLog.Printf("Action mode: using tag-based external actions repo reference: %s (SHA will be resolved later)", remoteRef) - return remoteRef +func actionModePinData(data *WorkflowData) *WorkflowData { + if data == nil { + return &WorkflowData{StrictMode: true} + } + pinData := *data + pinData.StrictMode = true + return &pinData } diff --git a/pkg/workflow/action_reference_test.go b/pkg/workflow/action_reference_test.go index ea44eb945f1..20814ef76f0 100644 --- a/pkg/workflow/action_reference_test.go +++ b/pkg/workflow/action_reference_test.go @@ -9,6 +9,15 @@ import ( "github.com/stretchr/testify/assert" ) +type staticSHAResolver struct { + sha string + err error +} + +func (r staticSHAResolver) ResolveSHA(context.Context, string, string) (string, error) { + return r.sha, r.err +} + func TestConvertToRemoteActionRef(t *testing.T) { tests := []struct { name string @@ -148,31 +157,31 @@ func TestResolveActionReference(t *testing.T) { description: "Release mode with 'dev' version should return empty", }, { - name: "release mode with action-tag overrides version", - actionMode: ActionModeRelease, - localPath: "./actions/setup", - version: "v1.0.0", - actionTag: "latest", - expectedRef: "github/gh-aw-actions/setup@latest", - description: "Frontmatter action-tag should use action mode (gh-aw-actions) regardless of compiler mode", + name: "release mode with unresolved action-tag fails closed", + actionMode: ActionModeRelease, + localPath: "./actions/setup", + version: "v1.0.0", + actionTag: "latest", + shouldBeEmpty: true, + description: "Frontmatter action-tag should use strict action mode and fail closed when unresolved", }, { - name: "release mode with action-tag using SHA", - actionMode: ActionModeRelease, - localPath: "./actions/setup", - version: "v1.0.0", - actionTag: "abc123def456789", - expectedRef: "github/gh-aw-actions/setup@abc123def456789", - description: "Frontmatter action-tag SHA should use action mode (gh-aw-actions)", + name: "release mode with short action-tag SHA fails closed", + actionMode: ActionModeRelease, + localPath: "./actions/setup", + version: "v1.0.0", + actionTag: "abc123def456789", + shouldBeEmpty: true, + description: "Frontmatter action-tag SHA must be a full immutable commit SHA", }, { - name: "dev mode with action-tag uses external actions repo", - actionMode: ActionModeDev, - localPath: "./actions/setup", - version: "v1.0.0", - actionTag: "latest", - expectedRef: "github/gh-aw-actions/setup@latest", - description: "Dev mode with frontmatter action-tag should use action mode (gh-aw-actions)", + name: "dev mode with unresolved action-tag fails closed", + actionMode: ActionModeDev, + localPath: "./actions/setup", + version: "v1.0.0", + actionTag: "latest", + shouldBeEmpty: true, + description: "Dev mode with frontmatter action-tag should use strict action mode and fail closed when unresolved", }, } @@ -364,3 +373,27 @@ func TestResolveSetupActionReferenceWithData(t *testing.T) { assert.Equal(t, "github/gh-aw/actions/setup@v1.0.0", ref, "should return tag-based reference when no resolver provided") }) } + +func TestResolveSetupActionReferenceActionModeRequiresFullSHA(t *testing.T) { + const sha = "0123456789abcdef0123456789abcdef01234567" + + t.Run("resolver full SHA is accepted", func(t *testing.T) { + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "", staticSHAResolver{sha: sha}) + assert.Equal(t, "github/gh-aw-actions/setup@"+sha+" # v1.0.0", ref) + }) + + t.Run("resolver short SHA is rejected", func(t *testing.T) { + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "", staticSHAResolver{sha: "abc123"}) + assert.Empty(t, ref) + }) + + t.Run("nil resolver unresolved version is rejected", func(t *testing.T) { + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "", nil) + assert.Empty(t, ref) + }) + + t.Run("full SHA tag is accepted without resolver", func(t *testing.T) { + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, sha, "", nil) + assert.Equal(t, "github/gh-aw-actions/setup@"+sha+" # "+sha, ref) + }) +} diff --git a/pkg/workflow/compiler_custom_actions_test.go b/pkg/workflow/compiler_custom_actions_test.go index 0126b4d7386..224d1b13d7d 100644 --- a/pkg/workflow/compiler_custom_actions_test.go +++ b/pkg/workflow/compiler_custom_actions_test.go @@ -398,17 +398,21 @@ func TestCheckoutActionsFolderDevModeAlwaysEmitsCheckout(t *testing.T) { // TestResolveSetupActionReferenceActionMode tests that action mode resolves to the external gh-aw-actions repo func TestResolveSetupActionReferenceActionMode(t *testing.T) { - ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.2.3", "", nil) - if ref != "github/gh-aw-actions/setup@v1.2.3" { - t.Errorf("Action mode should resolve to 'github/gh-aw-actions/setup@v1.2.3', got %q", ref) + const sha = "0123456789abcdef0123456789abcdef01234567" + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, sha, "", nil) + expected := "github/gh-aw-actions/setup@" + sha + " # " + sha + if ref != expected { + t.Errorf("Action mode should resolve to %q, got %q", expected, ref) } } // TestResolveSetupActionReferenceActionModeWithTag tests action mode with an explicit action tag func TestResolveSetupActionReferenceActionModeWithTag(t *testing.T) { - ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "v2.0.0", nil) - if ref != "github/gh-aw-actions/setup@v2.0.0" { - t.Errorf("Action mode with tag should resolve to 'github/gh-aw-actions/setup@v2.0.0', got %q", ref) + const sha = "0123456789abcdef0123456789abcdef01234567" + ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", sha, nil) + expected := "github/gh-aw-actions/setup@" + sha + " # " + sha + if ref != expected { + t.Errorf("Action mode with tag should resolve to %q, got %q", expected, ref) } } @@ -451,9 +455,12 @@ Test workflow with action mode. t.Fatalf("Failed to write test workflow: %v", err) } + const sha = "0123456789abcdef0123456789abcdef01234567" compiler := NewCompiler(WithVersion("v1.2.3")) compiler.SetActionMode(ActionModeAction) compiler.SetNoEmit(false) + cache := compiler.GetSharedActionCache() + cache.Set("github/gh-aw-actions/setup", "v1.2.3", sha) if err := compiler.CompileWorkflow(workflowPath); err != nil { t.Fatalf("Compilation failed: %v", err) @@ -468,8 +475,12 @@ Test workflow with action mode. lockStr := string(lockContent) // Verify it uses the external gh-aw-actions/setup action - if !strings.Contains(lockStr, "github/gh-aw-actions/setup@v1.2.3") { - t.Errorf("Action mode should use 'github/gh-aw-actions/setup@v1.2.3', lock file:\n%s", lockStr) + expected := "github/gh-aw-actions/setup@" + sha + " # v1.2.3" + if !strings.Contains(lockStr, expected) { + t.Errorf("Action mode should use %q, lock file:\n%s", expected, lockStr) + } + if strings.Contains(lockStr, "github/gh-aw-actions/setup@v1.2.3") { + t.Errorf("Action mode should not emit mutable gh-aw-actions setup reference, lock file:\n%s", lockStr) } // Verify it does NOT use the internal gh-aw/actions/setup path @@ -490,20 +501,20 @@ func TestResolveSetupActionReferenceActionModeWithResolver(t *testing.T) { cache := NewActionCache("") resolver := NewActionResolver(cache) - // The resolver will fail to resolve github/gh-aw-actions/setup@v1.0.0 - // since it's not a real tag, but it should fall back gracefully to tag-based reference + const sha = "0123456789abcdef0123456789abcdef01234567" + cache.Set("github/gh-aw-actions/setup", "v1.0.0", sha) ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "", resolver) - // Without a valid pin or successful resolution, should return tag-based reference - if ref != "github/gh-aw-actions/setup@v1.0.0" { - t.Errorf("expected 'github/gh-aw-actions/setup@v1.0.0', got %q", ref) + expected := "github/gh-aw-actions/setup@" + sha + " # v1.0.0" + if ref != expected { + t.Errorf("expected %q, got %q", expected, ref) } }) - t.Run("action mode with nil resolver returns tag-based reference", func(t *testing.T) { + t.Run("action mode with nil resolver fails closed when unresolved", func(t *testing.T) { ref := ResolveSetupActionReference(context.Background(), ActionModeAction, "v1.0.0", "", nil) - if ref != "github/gh-aw-actions/setup@v1.0.0" { - t.Errorf("expected 'github/gh-aw-actions/setup@v1.0.0', got %q", ref) + if ref != "" { + t.Errorf("expected empty ref, got %q", ref) } }) } diff --git a/pkg/workflow/compiler_yaml_test.go b/pkg/workflow/compiler_yaml_test.go index 0a9aae68876..7fb807a9704 100644 --- a/pkg/workflow/compiler_yaml_test.go +++ b/pkg/workflow/compiler_yaml_test.go @@ -1616,7 +1616,7 @@ func TestLockMetadataVersionInReleaseBuilds(t *testing.T) { { name: "release build should include version", isRelease: true, - version: "v0.1.2", + version: "0123456789abcdef0123456789abcdef01234567", actionTag: "", expectVersion: true, }, diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index e3570afd932..fb07dc07b0f 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -148,11 +148,6 @@ "version": "v4.38.0", "sha": "b96794f015dfd88f77b49b1c93e0fa7110f94c63" }, - "github/gh-aw-actions/setup@v0.89.1": { - "repo": "github/gh-aw-actions/setup", - "version": "v0.89.1", - "sha": "4537e5924c9abb366dcbece06750e498e0218fae" - }, "github/stale-repos@v9.0.17": { "repo": "github/stale-repos", "version": "v9.0.17", From 451d02126187d77de205c0a0e717f90323627e76 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 11 Sep 2026 08:39:12 +0000 Subject: [PATCH 4/4] Tighten action-mode pin helpers Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- pkg/workflow/action_pins.go | 9 +++++++++ pkg/workflow/action_reference.go | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/pkg/workflow/action_pins.go b/pkg/workflow/action_pins.go index 7b0f0117053..a02eb20500f 100644 --- a/pkg/workflow/action_pins.go +++ b/pkg/workflow/action_pins.go @@ -1,6 +1,7 @@ package workflow import ( + "context" "fmt" "os" "strings" @@ -245,6 +246,14 @@ func getActionPinWithData(actionRepo, version string, data *WorkflowData) (strin return actionpins.ResolveActionPin(actionRepo, version, data.PinContext()) } +func resolveStrictActionPin(ctx context.Context, actionRepo, version string) (string, error) { + return actionpins.ResolveActionPin(actionRepo, version, &actionpins.PinContext{ + Ctx: ctx, + StrictMode: true, + EnforcePinned: true, + }) +} + // getCachedActionPin returns the pinned action reference for a given repository, // preferring the dynamic resolver from WorkflowData over the embedded pins. func getCachedActionPin(repo string, data *WorkflowData) string { diff --git a/pkg/workflow/action_reference.go b/pkg/workflow/action_reference.go index 8e656d574fd..6217c445a4b 100644 --- a/pkg/workflow/action_reference.go +++ b/pkg/workflow/action_reference.go @@ -132,7 +132,7 @@ func resolveRequiredActionModePin(ctx context.Context, resolver SHAResolver, act if ref := tryResolveSetupSHA(ctx, resolver, actionRepo, tag, remoteRef, "Action mode"); ref != "" { return ref } - ref, err := getActionPinWithData(actionRepo, tag, actionModePinData(&WorkflowData{Ctx: ctx})) + ref, err := resolveStrictActionPin(ctx, actionRepo, tag) if err != nil { actionRefLog.Printf("Action mode: failed to pin action %s@%s: %v", actionRepo, tag, err) return "" @@ -148,17 +148,18 @@ func resolveRequiredActionModePin(ctx context.Context, resolver SHAResolver, act } func isFullSHAPinnedActionRef(ref string) bool { - _, after, ok := strings.Cut(ref, "@") - if !ok { + at := strings.LastIndex(ref, "@") + if at < 0 { return false } - actionRef := strings.TrimSpace(after) - if before, _, ok := strings.Cut(actionRef, " "); ok { - actionRef = before - } - if before, _, ok := strings.Cut(actionRef, "#"); ok { - actionRef = before + actionRef := strings.TrimSpace(ref[at+1:]) + cut := len(actionRef) + for _, sep := range []string{" ", "\t", "#"} { + if idx := strings.Index(actionRef, sep); idx >= 0 && idx < cut { + cut = idx + } } + actionRef = strings.TrimSpace(actionRef[:cut]) return gitutil.IsValidFullSHA(actionRef) }