diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json
index eeb7cbb1ce64..e74039346989 100644
--- a/.github/aw/actions-lock.json
+++ b/.github/aw/actions-lock.json
@@ -35,20 +35,15 @@
"version": "v7.0.1",
"sha": "043fb46d1a93c77aae656e7c1c64a875d1fc6a0a"
},
- "github/gh-aw-actions/setup@v0.79.8": {
+ "github/gh-aw-actions/setup-cli@v0.80.9": {
+ "repo": "github/gh-aw-actions/setup-cli",
+ "version": "v0.80.9",
+ "sha": "8c7d04ebf1ece56cd381446125da3e0f6896294a"
+ },
+ "github/gh-aw-actions/setup@v0.80.9": {
"repo": "github/gh-aw-actions/setup",
- "version": "v0.79.8",
- "sha": "c0338fef4749d08c21f8f975fb0e37efa17dda47"
- },
- "github/gh-aw/actions/setup@v0.43.19": {
- "repo": "github/gh-aw/actions/setup",
- "version": "v0.43.19",
- "sha": "7fe5515d71ccec397a3a81ff32f79217e9bc7ba6"
- },
- "github/gh-aw/actions/setup@v0.46.0": {
- "repo": "github/gh-aw/actions/setup",
- "version": "v0.46.0",
- "sha": "f88ec26c65cc20ebb8ceabe809c9153385945bfe"
+ "version": "v0.80.9",
+ "sha": "8c7d04ebf1ece56cd381446125da3e0f6896294a"
}
}
}
diff --git a/.github/workflows/agentic-labeler.lock.yml b/.github/workflows/agentic-labeler.lock.yml
index 400b0e9f83dd..b0326bc31ce9 100644
--- a/.github/workflows/agentic-labeler.lock.yml
+++ b/.github/workflows/agentic-labeler.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"b7dcc9fe85bf8be32cd6e1e97a26958f809519b9be0b42e45016d7ab1e82407a","body_hash":"963f8cdf65121d2b9d06b462dd225d101a37fd7c06a82c52a3a79fa9bbbbd8ae","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"f6e6537a8e822a8e527b2fd7eeec42d423d99697994d419c40baa53bee721960","body_hash":"963f8cdf65121d2b9d06b462dd225d101a37fd7c06a82c52a3a79fa9bbbbd8ae","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -29,37 +29,58 @@
# type, severity, partner, regression, or any other label families — those
# remain the responsibility of human triagers.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "Agentic Labeler"
on:
issues:
types:
- opened
+ # permissions: {} # Permissions applied to pre-activation job
pull_request_target:
types:
- opened
- reopened
# roles: all # Roles processed as role check in pre-activation job
+ # steps: # Steps injected into pre-activation job
+ # - name: Prepare PAT pool activation
+ # run: echo "PAT pool pre-activation"
workflow_dispatch:
inputs:
aw_context:
@@ -82,6 +103,10 @@ run-name: "Agentic Labeler"
jobs:
activation:
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-slim
permissions:
actions: read
@@ -108,16 +133,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -125,16 +152,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -145,6 +172,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-agenticlabeler-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-agenticlabeler-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -154,6 +205,8 @@ jobs:
GH_AW_WORKFLOW_ID: "agentic-labeler"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -177,7 +230,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -213,7 +266,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -251,20 +304,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_56a2627cdf780f6c_EOF'
+ cat << 'GH_AW_PROMPT_8330c6f92efd8f39_EOF'
- GH_AW_PROMPT_56a2627cdf780f6c_EOF
+ GH_AW_PROMPT_8330c6f92efd8f39_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_56a2627cdf780f6c_EOF'
+ cat << 'GH_AW_PROMPT_8330c6f92efd8f39_EOF'
Tools: add_labels(max:10), missing_tool, missing_data, noop
- GH_AW_PROMPT_56a2627cdf780f6c_EOF
+ GH_AW_PROMPT_8330c6f92efd8f39_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_56a2627cdf780f6c_EOF'
+ cat << 'GH_AW_PROMPT_8330c6f92efd8f39_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -293,12 +346,12 @@ jobs:
{{/if}}
- GH_AW_PROMPT_56a2627cdf780f6c_EOF
+ GH_AW_PROMPT_8330c6f92efd8f39_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_56a2627cdf780f6c_EOF'
+ cat << 'GH_AW_PROMPT_8330c6f92efd8f39_EOF'
{{#runtime-import .github/workflows/agentic-labeler.md}}
- GH_AW_PROMPT_56a2627cdf780f6c_EOF
+ GH_AW_PROMPT_8330c6f92efd8f39_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -333,6 +386,7 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_INPUTS_ISSUE_NUMBER: ${{ inputs.issue_number }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -356,7 +410,8 @@ jobs:
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
GH_AW_INPUTS_ISSUE_NUMBER: process.env.GH_AW_INPUTS_ISSUE_NUMBER,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -389,10 +444,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -425,7 +482,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -434,8 +491,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -446,7 +503,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -457,17 +514,10 @@ jobs:
GH_TOKEN: ${{ github.token }}
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -483,11 +533,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Parse integrity filter lists
id: parse-guard-vars
env:
@@ -516,15 +566,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_1a7f7258dbbe69c6_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_96be62e22c0ac04a_EOF'
{"add_labels":{"max":10},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_1a7f7258dbbe69c6_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_96be62e22c0ac04a_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -637,53 +687,14 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -709,16 +720,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_1fcbd0e0ac462fda_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_d23a67758863886b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -736,10 +747,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -757,7 +784,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_1fcbd0e0ac462fda_EOF
+ GH_AW_MCP_CONFIG_d23a67758863886b_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -796,38 +823,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 15
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -842,6 +898,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -849,17 +906,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -883,8 +933,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1008,12 +1067,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1030,7 +1090,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1039,8 +1099,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1062,12 +1122,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1076,6 +1138,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1084,12 +1148,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-agenticlabeler-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-agenticlabeler-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-agenticlabeler-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1211,7 +1317,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1222,7 +1328,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1231,8 +1337,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1250,7 +1356,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1259,7 +1365,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1322,11 +1428,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1345,37 +1451,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1389,6 +1514,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1442,6 +1568,104 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Prepare PAT pool activation
+ run: echo "PAT pool pre-activation"
+
safe_outputs:
needs:
- activation
@@ -1449,7 +1673,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1465,7 +1689,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "agentic-labeler"
GH_AW_WORKFLOW_NAME: "Agentic Labeler"
@@ -1480,7 +1704,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1489,8 +1713,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Agentic Labeler"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/agentic-labeler.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1509,8 +1733,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
diff --git a/.github/workflows/agentic-labeler.md b/.github/workflows/agentic-labeler.md
index 4706ef4b7d67..9a305381c9fd 100644
--- a/.github/workflows/agentic-labeler.md
+++ b/.github/workflows/agentic-labeler.md
@@ -6,7 +6,19 @@ description: |
type, severity, partner, regression, or any other label families — those
remain the responsibility of human triagers.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
on:
issues:
@@ -19,7 +31,11 @@ on:
description: 'Issue or PR number to label'
required: true
type: number
+ steps:
+ - name: Prepare PAT pool activation
+ run: echo "PAT pool pre-activation"
reaction: eyes
+ permissions: {}
# Allow this workflow to run for any actor (including first-time community
# contributors). It is labeling-only — the agent runs with read-only tokens,
# and label writes happen through the sandboxed safe-output job capped at
@@ -42,6 +58,24 @@ permissions:
issues: read
pull-requests: read
+engine:
+ id: copilot
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
+
network: defaults
safe-outputs:
diff --git a/.github/workflows/agentics-maintenance.yml b/.github/workflows/agentics-maintenance.yml
index b3de9d130652..356aa64baa07 100644
--- a/.github/workflows/agentics-maintenance.yml
+++ b/.github/workflows/agentics-maintenance.yml
@@ -1,3 +1,4 @@
+# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -13,7 +14,6 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
-# This file was automatically generated by pkg/workflow/maintenance_workflow.go (v0.46.0). DO NOT EDIT.
#
# To regenerate this workflow, run:
# gh aw compile
@@ -21,27 +21,74 @@
#
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
-# Alternative regeneration methods:
-# make recompile
-#
-# Or use the gh-aw CLI directly:
-# ./gh-aw compile --validate --verbose
-#
-# The workflow is generated when any workflow uses the 'expires' field
-# in create-discussions, create-issues, or create-pull-request safe-outputs configuration.
-# Schedule frequency is automatically determined by the shortest expiration time.
+# This file defines the generated agentic maintenance workflow for this repository.
+# It runs scheduled cleanup for expiring safe outputs and supports manual maintenance operations.
+#
+# This workflow is generated automatically when workflows use expiring safe outputs
+# or when repository maintenance features are enabled in .github/workflows/aw.json.
+#
+# To disable maintenance workflow generation, set in .github/workflows/aw.json:
+# {"maintenance": false}
+#
+# Agentic maintenance docs:
+# https://github.github.com/gh-aw/reference/ephemerals/#manual-maintenance-operations
#
name: Agentic Maintenance
on:
schedule:
- - cron: "37 */2 * * *" # Every 2 hours (based on minimum expires: 1 days)
+ - cron: "37 0 * * *" # Daily (based on minimum expires: 30 days)
workflow_dispatch:
+ inputs:
+ operation:
+ description: 'Optional maintenance operation to run'
+ required: false
+ type: choice
+ default: ''
+ options:
+ - ''
+ - 'disable'
+ - 'enable'
+ - 'update'
+ - 'upgrade'
+ - 'safe_outputs'
+ - 'create_labels'
+ - 'activity_report'
+ - 'close_agentic_workflows_issues'
+ - 'clean_cache_memories'
+ - 'update_pull_request_branches'
+ - 'validate'
+ - 'forecast'
+ run_url:
+ description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
+ required: false
+ type: string
+ default: ''
+ workflow_call:
+ inputs:
+ operation:
+ description: 'Optional maintenance operation to run (disable, enable, update, upgrade, safe_outputs, create_labels, activity_report, close_agentic_workflows_issues, clean_cache_memories, update_pull_request_branches, validate, forecast)'
+ required: false
+ type: string
+ default: ''
+ run_url:
+ description: 'Run URL or run ID to replay safe outputs from (e.g. https://github.com/owner/repo/actions/runs/12345 or 12345). Required when operation is safe_outputs.'
+ required: false
+ type: string
+ default: ''
+ outputs:
+ operation_completed:
+ description: 'The maintenance operation that was completed (empty when none ran or a scheduled job ran)'
+ value: ${{ jobs.run_operation.outputs.operation || inputs.operation }}
+ applied_run_url:
+ description: 'The run URL that safe outputs were applied from'
+ value: ${{ jobs.apply_safe_outputs.outputs.run_url }}
permissions: {}
jobs:
close-expired-entities:
+ if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '') }}
runs-on: ubuntu-slim
permissions:
discussions: write
@@ -49,33 +96,519 @@ jobs:
pull-requests: write
steps:
- name: Setup Scripts
- uses: github/gh-aw/actions/setup@v0.46.0
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
- destination: /opt/gh-aw/actions
+ destination: ${{ runner.temp }}/gh-aw/actions
- name: Close expired discussions
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
- const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io);
- const { main } = require('/opt/gh-aw/actions/close_expired_discussions.cjs');
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_discussions.cjs');
await main();
- name: Close expired issues
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
- const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io);
- const { main } = require('/opt/gh-aw/actions/close_expired_issues.cjs');
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_issues.cjs');
await main();
- name: Close expired pull requests
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/close_expired_pull_requests.cjs');
+ await main();
+
+ cleanup-cache-memory:
+ if: ${{ (!(github.event.repository.fork)) && github.event_name != 'push' && (github.event_name != 'workflow_dispatch' && github.event_name != 'workflow_call' || inputs.operation == '' || inputs.operation == 'clean_cache_memories') }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Cleanup outdated cache-memory entries
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/cleanup_cache_memory.cjs');
+ await main();
+
+ run_operation:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation != '' && inputs.operation != 'safe_outputs' && inputs.operation != 'create_labels' && inputs.operation != 'activity_report' && inputs.operation != 'close_agentic_workflows_issues' && inputs.operation != 'clean_cache_memories' && inputs.operation != 'update_pull_request_branches' && inputs.operation != 'validate' && inputs.operation != 'forecast' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: write
+ contents: write
+ pull-requests: write
+ outputs:
+ operation: ${{ steps.record.outputs.operation }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ version: v0.80.9
+
+ - name: Run operation
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_OPERATION: ${{ inputs.operation }}
+ GH_AW_CMD_PREFIX: gh aw
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/run_operation_update_upgrade.cjs');
+ await main();
+
+ - name: Record outputs
+ id: record
+ env:
+ GH_AW_OPERATION: ${{ inputs.operation }}
+ run: echo "operation=$GH_AW_OPERATION" >> "$GITHUB_OUTPUT"
+
+ update_pull_request_branches:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'update_pull_request_branches' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ contents: write
+ pull-requests: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Update pull request branches
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/update_pull_request_branches.cjs');
+ await main();
+
+ apply_safe_outputs:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'safe_outputs' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ actions: read
+ contents: write
+ discussions: write
+ issues: write
+ pull-requests: write
+ outputs:
+ run_url: ${{ steps.record.outputs.run_url }}
+ steps:
+ - name: Checkout actions folder
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ sparse-checkout: |
+ actions
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Apply Safe Outputs
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_RUN_URL: ${{ inputs.run_url }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/apply_safe_outputs_replay.cjs');
+ await main();
+
+ - name: Record outputs
+ id: record
+ env:
+ GH_AW_RUN_URL: ${{ inputs.run_url }}
+ run: echo "run_url=$GH_AW_RUN_URL" >> "$GITHUB_OUTPUT"
+
+ create_labels:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'create_labels' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ version: v0.80.9
+
+ - name: Create missing labels
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_CMD_PREFIX: gh aw
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/create_labels.cjs');
+ await main();
+
+ activity_report:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'activity_report' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ timeout-minutes: 120
+ permissions:
+ actions: read
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ version: v0.80.9
+
+ - name: Restore activity report logs cache
+ id: activity_report_logs_cache
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.cache/gh-aw/activity-report-logs
+ key: ${{ runner.os }}-activity-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-activity-report-logs-${{ github.repository }}-
+ ${{ runner.os }}-activity-report-logs-
+ - name: Download activity report logs
+ timeout-minutes: 20
+ shell: bash
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_AW_CMD_PREFIX: gh aw
+ run: |
+ ${GH_AW_CMD_PREFIX} logs \
+ --repo "${{ github.repository }}" \
+ --start-date -1w \
+ --count 500 \
+ --output ./.cache/gh-aw/activity-report-logs \
+ --format markdown \
+ --report-file ./.cache/gh-aw/activity-report-logs/report.md
+
+ - name: Save activity report logs cache
+ if: ${{ always() }}
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.cache/gh-aw/activity-report-logs
+ key: ${{ steps.activity_report_logs_cache.outputs.cache-primary-key }}
+
+ - name: Generate activity report issue
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const fs = require('node:fs');
+ const reportPath = './.cache/gh-aw/activity-report-logs/report.md';
+ if (!fs.existsSync(reportPath)) {
+ core.warning('Activity report markdown not found at ' + reportPath + '; skipping issue creation.');
+ return;
+ }
+ let reportBody = '';
+ try {
+ reportBody = fs.readFileSync(reportPath, 'utf8').trim();
+ } catch (error) {
+ core.warning('Failed to read activity report markdown at ' + reportPath + ': ' + error.message);
+ return;
+ }
+ if (!reportBody) {
+ core.warning('Activity report markdown is empty at ' + reportPath + '; skipping issue creation.');
+ return;
+ }
+ const repoSlug = context.repo.owner + '/' + context.repo.repo;
+ const body = [
+ '### Agentic workflow activity report',
+ '',
+ 'Repository: ' + repoSlug,
+ 'Generated at: ' + new Date().toISOString(),
+ '',
+ reportBody,
+ ].join('\n');
+ const createdIssue = await github.rest.issues.create({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ title: '[aw] agentic status report',
+ body,
+ labels: ['agentic-workflows'],
+ });
+ core.info('Created issue #' + createdIssue.data.number + ': ' + createdIssue.data.html_url);
+
+ forecast_report:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'forecast' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ timeout-minutes: 60
+ permissions:
+ actions: read
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ version: v0.80.9
+
+ - name: Restore forecast report logs cache
+ id: forecast_report_logs_cache
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.github/aw/logs
+ key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+ restore-keys: |
+ ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-
+ ${{ runner.os }}-forecast-report-logs-
+
+ - name: Generate forecast report
+ id: generate_forecast_report
+ timeout-minutes: 30
+ shell: bash
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ DEBUG: "*"
+ GH_AW_CMD_PREFIX: gh aw
+ run: |
+ mkdir -p ./.cache/gh-aw/forecast
+ set +e
+ ${GH_AW_CMD_PREFIX} forecast --repo "${{ github.repository }}" --timeout 30 --verbose --json > ./.cache/gh-aw/forecast/report.json
+ forecast_exit_code=$?
+ set -e
+ if [ "${forecast_exit_code}" -eq 124 ]; then
+ echo '{"outcome":"timeout","message":"Forecast computation timed out after 30 minutes."}' > ./.cache/gh-aw/forecast/error.json
+ echo "::error::Forecast computation timed out after 30 minutes."
+ exit 1
+ fi
+ if [ "${forecast_exit_code}" -ne 0 ]; then
+ echo '{"outcome":"error","message":"Forecast computation failed before producing a report."}' > ./.cache/gh-aw/forecast/error.json
+ echo "::error::Forecast computation failed with exit code ${forecast_exit_code}."
+ exit 1
+ fi
+
+ - name: Debug forecast logs folder
+ if: ${{ always() }}
+ shell: bash
+ run: |
+ if [ ! -d ./.github/aw/logs ]; then
+ echo "Logs directory not found: ./.github/aw/logs"
+ exit 0
+ fi
+ echo "Files under ./.github/aw/logs:"
+ find ./.github/aw/logs -type f | sort
+
+ - name: Save forecast report logs cache
+ if: ${{ always() }}
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ path: ./.github/aw/logs
+ key: ${{ runner.os }}-forecast-report-logs-${{ github.repository }}-${{ github.ref_name }}-${{ github.run_id }}
+
+ - name: Generate forecast issue
+ if: ${{ always() }}
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ FORECAST_STEP_OUTCOME: ${{ steps.generate_forecast_report.outcome }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/create_forecast_issue.cjs');
+ await main();
+
+ close_agentic_workflows_issues:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'close_agentic_workflows_issues' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-slim
+ permissions:
+ issues: write
+ steps:
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Close no-repro agentic-workflows issues
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/close_agentic_workflows_issues.cjs');
+ await main();
+
+ validate_workflows:
+ if: ${{ (github.event_name == 'workflow_dispatch' || github.event_name == 'workflow_call') && inputs.operation == 'validate' && (!(github.event.repository.fork)) }}
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ issues: write
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+ with:
+ persist-credentials: false
+
+ - name: Setup Scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Check admin/maintainer permissions
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_team_member.cjs');
+ await main();
+
+ - name: Install gh-aw
+ uses: github/gh-aw-actions/setup-cli@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ version: v0.80.9
+
+ - name: Validate workflows and file issue on findings
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_CMD_PREFIX: gh aw
with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
- const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io);
- const { main } = require('/opt/gh-aw/actions/close_expired_pull_requests.cjs');
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/run_validate_workflows.cjs');
await main();
diff --git a/.github/workflows/ci-status-fix-net11.lock.yml b/.github/workflows/ci-status-fix-net11.lock.yml
index 20c3fe309669..0cbdd710f0e3 100644
--- a/.github/workflows/ci-status-fix-net11.lock.yml
+++ b/.github/workflows/ci-status-fix-net11.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d946402465899712a0d31846479b5eb1d454e545f1ee55216333b999c1639cef","body_hash":"509debc57c8b8997ca90265226cb05345367c23da40b4aa781a467d7526c2f3c","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"87de1cb360d4711133a914318e7726cbc1dafb9fbe9ec751630dd003bc587bab","body_hash":"509debc57c8b8997ca90265226cb05345367c23da40b4aa781a467d7526c2f3c","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -38,30 +38,48 @@
# (deterministic synchronization, no
# retries / timeout bumps). Always skips visual-regression / screenshot issues.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_CI_TRIGGER_TOKEN
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "CI Failure Fixer (net11.0)"
on:
+ # permissions: {} # Permissions applied to pre-activation job
schedule:
- cron: "17 */12 * * *"
# Friendly format: every 12h (scattered)
@@ -92,7 +110,10 @@ run-name: "CI Failure Fixer (net11.0)"
jobs:
activation:
- if: github.repository == 'dotnet/maui'
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true' && (github.repository == 'dotnet/maui')
runs-on: ubuntu-slim
permissions:
actions: read
@@ -115,16 +136,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -132,16 +155,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-opus-4.8"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","dev.azure.com","helix.dot.net","*.blob.core.windows.net"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -152,6 +175,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfixnet11-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusfixnet11-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -161,6 +208,8 @@ jobs:
GH_AW_WORKFLOW_ID: "ci-status-fix-net11"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -171,7 +220,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -207,7 +256,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -232,23 +281,23 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_74d71949acd1a76b_EOF'
+ cat << 'GH_AW_PROMPT_876f10b42a0c8be1_EOF'
- GH_AW_PROMPT_74d71949acd1a76b_EOF
+ GH_AW_PROMPT_876f10b42a0c8be1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_74d71949acd1a76b_EOF'
+ cat << 'GH_AW_PROMPT_876f10b42a0c8be1_EOF'
Tools: create_pull_request(max:3), missing_tool, missing_data, noop
- GH_AW_PROMPT_74d71949acd1a76b_EOF
+ GH_AW_PROMPT_876f10b42a0c8be1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
- cat << 'GH_AW_PROMPT_74d71949acd1a76b_EOF'
+ cat << 'GH_AW_PROMPT_876f10b42a0c8be1_EOF'
- GH_AW_PROMPT_74d71949acd1a76b_EOF
+ GH_AW_PROMPT_876f10b42a0c8be1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_74d71949acd1a76b_EOF'
+ cat << 'GH_AW_PROMPT_876f10b42a0c8be1_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -290,12 +339,12 @@ jobs:
stop immediately and report the limitation rather than spending turns trying to work around it.
- GH_AW_PROMPT_74d71949acd1a76b_EOF
+ GH_AW_PROMPT_876f10b42a0c8be1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_74d71949acd1a76b_EOF'
+ cat << 'GH_AW_PROMPT_876f10b42a0c8be1_EOF'
{{#runtime-import .github/workflows/ci-status-fix-net11.md}}
- GH_AW_PROMPT_74d71949acd1a76b_EOF
+ GH_AW_PROMPT_876f10b42a0c8be1_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -325,6 +374,7 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -346,7 +396,8 @@ jobs:
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -379,10 +430,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -418,7 +471,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -427,8 +480,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -439,7 +492,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 200
@@ -457,17 +510,10 @@ jobs:
GH_TOKEN: ${{ github.token }}
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -483,11 +529,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Parse integrity filter lists
id: parse-guard-vars
env:
@@ -516,15 +562,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_9a88c3e19e3a5342_EOF'
- {"create_pull_request":{"allowed_base_branches":["net11.0"],"allowed_branches":["ci-fix/**"],"allowed_files":["src/Core/**","src/Controls/**","src/Essentials/**","src/BlazorWebView/**","src/TestUtils/**","src/Templates/**","**/PublicAPI.Unshipped.txt"],"base_branch":"net11.0","draft":true,"labels":["agentic-workflows"],"max":3,"max_patch_files":100,"max_patch_size":1024,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"request_review","title_prefix":"[ci-fix] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_9a88c3e19e3a5342_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_02cce79462eaed0d_EOF'
+ {"create_pull_request":{"allowed_base_branches":["net11.0"],"allowed_branches":["ci-fix/**"],"allowed_files":["src/Core/**","src/Controls/**","src/Essentials/**","src/BlazorWebView/**","src/TestUtils/**","src/Templates/**","**/PublicAPI.Unshipped.txt"],"base_branch":"net11.0","draft":true,"labels":["agentic-workflows"],"max":3,"max_patch_files":100,"max_patch_size":4096,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"request_review","title_prefix":"[ci-fix] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_02cce79462eaed0d_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -659,53 +705,14 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -731,16 +738,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_284f116907242706_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_28c1cee580e04dd2_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -758,10 +765,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -779,7 +802,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_284f116907242706_EOF
+ GH_AW_MCP_CONFIG_28c1cee580e04dd2_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -862,38 +885,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"codeload.github.com\",\"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\",\"dev.azure.com\",\"docs.github.com\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"objects.githubusercontent.com\",\"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\",\"patch-diff.githubusercontent.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"codeload.github.com\",\"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\",\"dev.azure.com\",\"docs.github.com\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"objects.githubusercontent.com\",\"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\",\"patch-diff.githubusercontent.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(bash)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(chmod)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(dotnet:*)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(env)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(git:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sh)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(bash)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(chmod)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(dotnet:*)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(env)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(git:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sh)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-opus-4.8
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 90
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -908,6 +960,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -915,17 +968,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -949,8 +995,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1074,12 +1129,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: write
issues: write
@@ -1096,7 +1152,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1105,8 +1161,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1128,12 +1184,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1142,6 +1200,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1150,12 +1210,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfixnet11-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusfixnet11-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfixnet11-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1277,7 +1379,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1288,7 +1390,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1297,8 +1399,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1316,7 +1418,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1325,7 +1427,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1388,11 +1490,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1411,37 +1513,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-opus-4.8
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1455,6 +1576,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1508,6 +1630,115 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ if: github.repository == 'dotnet/maui'
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
+ await main();
+
safe_outputs:
needs:
- activation
@@ -1515,7 +1746,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: write
issues: write
@@ -1531,7 +1762,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-opus-4.8"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "ci-status-fix-net11"
GH_AW_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
@@ -1548,7 +1779,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1557,8 +1788,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1580,51 +1811,31 @@ jobs:
with:
name: agent
path: /tmp/gh-aw/
- - name: Extract base branch from agent output
- id: extract-base-branch
- if: steps.download-agent-output.outcome == 'success'
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
- with:
- script: |
- const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io, getOctokit);
- const { main } = require('${{ runner.temp }}/gh-aw/actions/extract_base_branch_from_agent_output.cjs');
- await main();
- - name: Checkout repository (trusted default branch for comment events)
- if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- with:
- ref: ${{ github.event.repository.default_branch }}
- token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- persist-credentials: false
- fetch-depth: 200
- name: Checkout repository
- if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && github.event_name != 'issue_comment' && github.event_name != 'pull_request_review_comment'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
- ref: net11.0
- token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- persist-credentials: false
+ persist-credentials: true
fetch-depth: 200
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ - name: Fetch additional refs
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ env:
+ GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ run: |
+ header=$(printf "x-access-token:%s" "${GH_AW_FETCH_TOKEN}" | base64 -w 0)
+ git -c "http.extraheader=Authorization: Basic ${header}" fetch origin --depth=200 '+refs/heads/net11.0:refs/remotes/origin/net11.0'
- name: Configure Git credentials
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
@@ -1639,7 +1850,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.blob.core.windows.net,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,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,dev.azure.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,helix.dot.net,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,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,patch-diff.githubusercontent.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"allowed_base_branches\":[\"net11.0\"],\"allowed_branches\":[\"ci-fix/**\"],\"allowed_files\":[\"src/Core/**\",\"src/Controls/**\",\"src/Essentials/**\",\"src/BlazorWebView/**\",\"src/TestUtils/**\",\"src/Templates/**\",\"**/PublicAPI.Unshipped.txt\"],\"base_branch\":\"net11.0\",\"draft\":true,\"labels\":[\"agentic-workflows\"],\"max\":3,\"max_patch_files\":100,\"max_patch_size\":1024,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"[ci-fix] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"allowed_base_branches\":[\"net11.0\"],\"allowed_branches\":[\"ci-fix/**\"],\"allowed_files\":[\"src/Core/**\",\"src/Controls/**\",\"src/Essentials/**\",\"src/BlazorWebView/**\",\"src/TestUtils/**\",\"src/Templates/**\",\"**/PublicAPI.Unshipped.txt\"],\"base_branch\":\"net11.0\",\"draft\":true,\"labels\":[\"agentic-workflows\"],\"max\":3,\"max_patch_files\":100,\"max_patch_size\":4096,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"[ci-fix] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci-status-fix-net11.md b/.github/workflows/ci-status-fix-net11.md
index e3b868d39f8f..92666d293b38 100644
--- a/.github/workflows/ci-status-fix-net11.md
+++ b/.github/workflows/ci-status-fix-net11.md
@@ -16,7 +16,19 @@ description: |
(deterministic synchronization, no
retries / timeout bumps). Always skips visual-regression / screenshot issues.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
permissions:
contents: read
@@ -36,6 +48,7 @@ on:
required: false
type: boolean
default: false
+ permissions: {}
if: |
github.repository == 'dotnet/maui'
@@ -43,6 +56,21 @@ if: |
engine:
id: copilot
model: claude-opus-4.8
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
concurrency:
group: "ci-status-fix-net11"
diff --git a/.github/workflows/ci-status-fix.lock.yml b/.github/workflows/ci-status-fix.lock.yml
index d7f2b35283a0..a5377c1f4930 100644
--- a/.github/workflows/ci-status-fix.lock.yml
+++ b/.github/workflows/ci-status-fix.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"ad1014f496e29a5a5c0cf7dc24dbfc0610904997563dd83409f69c8ea042a3ee","body_hash":"0ce4e1dc705a02f959fc418be5f6545ec1c87f0cd429fd3b24106ebfac489697","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"7a2dbf189b0f4c8ff2e070cab94e476d5a99e19a3f8f20e1378ebd72f3fa4022","body_hash":"0ce4e1dc705a02f959fc418be5f6545ec1c87f0cd429fd3b24106ebfac489697","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-opus-4.8","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -38,30 +38,48 @@
# de-flakes genuinely flaky ones (deterministic synchronization, no retries /
# timeout bumps). Always skips visual-regression / screenshot issues.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_CI_TRIGGER_TOKEN
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "CI Failure Fixer (main)"
on:
+ # permissions: {} # Permissions applied to pre-activation job
schedule:
- cron: "17 */12 * * *"
# Friendly format: every 12h (scattered)
@@ -92,7 +110,10 @@ run-name: "CI Failure Fixer (main)"
jobs:
activation:
- if: github.repository == 'dotnet/maui'
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true' && (github.repository == 'dotnet/maui')
runs-on: ubuntu-slim
permissions:
actions: read
@@ -115,16 +136,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -132,16 +155,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-opus-4.8"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","dev.azure.com","helix.dot.net","*.blob.core.windows.net"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -152,6 +175,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfix-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusfix-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -161,6 +208,8 @@ jobs:
GH_AW_WORKFLOW_ID: "ci-status-fix"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -171,7 +220,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -207,7 +256,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -232,23 +281,23 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_a9b7ac032967542e_EOF'
+ cat << 'GH_AW_PROMPT_03372c256c00660c_EOF'
- GH_AW_PROMPT_a9b7ac032967542e_EOF
+ GH_AW_PROMPT_03372c256c00660c_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_a9b7ac032967542e_EOF'
+ cat << 'GH_AW_PROMPT_03372c256c00660c_EOF'
Tools: create_pull_request(max:3), missing_tool, missing_data, noop
- GH_AW_PROMPT_a9b7ac032967542e_EOF
+ GH_AW_PROMPT_03372c256c00660c_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
- cat << 'GH_AW_PROMPT_a9b7ac032967542e_EOF'
+ cat << 'GH_AW_PROMPT_03372c256c00660c_EOF'
- GH_AW_PROMPT_a9b7ac032967542e_EOF
+ GH_AW_PROMPT_03372c256c00660c_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_a9b7ac032967542e_EOF'
+ cat << 'GH_AW_PROMPT_03372c256c00660c_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -290,12 +339,12 @@ jobs:
stop immediately and report the limitation rather than spending turns trying to work around it.
- GH_AW_PROMPT_a9b7ac032967542e_EOF
+ GH_AW_PROMPT_03372c256c00660c_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_a9b7ac032967542e_EOF'
+ cat << 'GH_AW_PROMPT_03372c256c00660c_EOF'
{{#runtime-import .github/workflows/ci-status-fix.md}}
- GH_AW_PROMPT_a9b7ac032967542e_EOF
+ GH_AW_PROMPT_03372c256c00660c_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -325,6 +374,7 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -346,7 +396,8 @@ jobs:
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -379,10 +430,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -418,7 +471,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -427,8 +480,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -439,7 +492,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 200
@@ -451,17 +504,10 @@ jobs:
GH_TOKEN: ${{ github.token }}
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -477,11 +523,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Parse integrity filter lists
id: parse-guard-vars
env:
@@ -510,15 +556,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_faa4a7395e59e76a_EOF'
- {"create_pull_request":{"allowed_base_branches":["main"],"allowed_branches":["ci-fix/**"],"allowed_files":["src/Core/**","src/Controls/**","src/Essentials/**","src/BlazorWebView/**","src/TestUtils/**","src/Templates/**","**/PublicAPI.Unshipped.txt"],"base_branch":"main","draft":true,"labels":["agentic-workflows"],"max":3,"max_patch_files":100,"max_patch_size":1024,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"request_review","title_prefix":"[ci-fix] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_faa4a7395e59e76a_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_3e33e0b21b41acef_EOF'
+ {"create_pull_request":{"allowed_base_branches":["main"],"allowed_branches":["ci-fix/**"],"allowed_files":["src/Core/**","src/Controls/**","src/Essentials/**","src/BlazorWebView/**","src/TestUtils/**","src/Templates/**","**/PublicAPI.Unshipped.txt"],"base_branch":"main","draft":true,"labels":["agentic-workflows"],"max":3,"max_patch_files":100,"max_patch_size":4096,"protect_top_level_dot_folders":true,"protected_files":["package.json","bun.lockb","bunfig.toml","deno.json","deno.jsonc","deno.lock","global.json","NuGet.Config","Directory.Packages.props","mix.exs","mix.lock","go.mod","go.sum","stack.yaml","stack.yaml.lock","pom.xml","build.gradle","build.gradle.kts","settings.gradle","settings.gradle.kts","gradle.properties","package-lock.json","yarn.lock","pnpm-lock.yaml","npm-shrinkwrap.json","requirements.txt","Pipfile","Pipfile.lock","pyproject.toml","setup.py","setup.cfg","Gemfile","Gemfile.lock","uv.lock","CODEOWNERS","DESIGN.md","README.md","CONTRIBUTING.md","CHANGELOG.md","SECURITY.md","CODE_OF_CONDUCT.md","AGENTS.md","CLAUDE.md","GEMINI.md"],"protected_files_policy":"request_review","title_prefix":"[ci-fix] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_3e33e0b21b41acef_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -653,53 +699,14 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -725,16 +732,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_284f116907242706_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_28c1cee580e04dd2_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -752,10 +759,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -773,7 +796,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_284f116907242706_EOF
+ GH_AW_MCP_CONFIG_28c1cee580e04dd2_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -856,38 +879,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"codeload.github.com\",\"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\",\"dev.azure.com\",\"docs.github.com\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"objects.githubusercontent.com\",\"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\",\"patch-diff.githubusercontent.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"codeload.github.com\",\"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\",\"dev.azure.com\",\"docs.github.com\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"objects.githubusercontent.com\",\"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\",\"patch-diff.githubusercontent.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(bash)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(chmod)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(dotnet:*)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(env)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(git:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sh)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(bash)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(chmod)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(dotnet:*)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(env)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(git:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sh)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-opus-4.8
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 90
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -902,6 +954,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -909,17 +962,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -943,8 +989,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1068,12 +1123,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: write
issues: write
@@ -1090,7 +1146,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1099,8 +1155,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1122,12 +1178,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1136,6 +1194,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1144,12 +1204,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfix-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusfix-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusfix-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1271,7 +1373,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1282,7 +1384,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1291,8 +1393,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1310,7 +1412,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1319,7 +1421,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1382,11 +1484,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1405,37 +1507,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-opus-4.8
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1449,6 +1570,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1502,6 +1624,115 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ if: github.repository == 'dotnet/maui'
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
+ await main();
+
safe_outputs:
needs:
- activation
@@ -1509,7 +1740,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: write
issues: write
@@ -1525,7 +1756,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-opus-4.8"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "ci-status-fix"
GH_AW_WORKFLOW_NAME: "CI Failure Fixer (main)"
@@ -1542,7 +1773,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1551,8 +1782,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Fixer (main)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-fix.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1574,51 +1805,24 @@ jobs:
with:
name: agent
path: /tmp/gh-aw/
- - name: Extract base branch from agent output
- id: extract-base-branch
- if: steps.download-agent-output.outcome == 'success'
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
- with:
- script: |
- const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
- setupGlobals(core, github, context, exec, io, getOctokit);
- const { main } = require('${{ runner.temp }}/gh-aw/actions/extract_base_branch_from_agent_output.cjs');
- await main();
- - name: Checkout repository (trusted default branch for comment events)
- if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- with:
- ref: ${{ github.event.repository.default_branch }}
- token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- persist-credentials: false
- fetch-depth: 200
- name: Checkout repository
- if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && github.event_name != 'issue_comment' && github.event_name != 'pull_request_review_comment'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
- ref: main
- token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- persist-credentials: false
+ persist-credentials: true
fetch-depth: 200
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- name: Configure Git credentials
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request')
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
@@ -1633,7 +1837,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.blob.core.windows.net,*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,codeload.github.com,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,dev.azure.com,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,helix.dot.net,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,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,patch-diff.githubusercontent.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"allowed_base_branches\":[\"main\"],\"allowed_branches\":[\"ci-fix/**\"],\"allowed_files\":[\"src/Core/**\",\"src/Controls/**\",\"src/Essentials/**\",\"src/BlazorWebView/**\",\"src/TestUtils/**\",\"src/Templates/**\",\"**/PublicAPI.Unshipped.txt\"],\"base_branch\":\"main\",\"draft\":true,\"labels\":[\"agentic-workflows\"],\"max\":3,\"max_patch_files\":100,\"max_patch_size\":1024,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"[ci-fix] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_pull_request\":{\"allowed_base_branches\":[\"main\"],\"allowed_branches\":[\"ci-fix/**\"],\"allowed_files\":[\"src/Core/**\",\"src/Controls/**\",\"src/Essentials/**\",\"src/BlazorWebView/**\",\"src/TestUtils/**\",\"src/Templates/**\",\"**/PublicAPI.Unshipped.txt\"],\"base_branch\":\"main\",\"draft\":true,\"labels\":[\"agentic-workflows\"],\"max\":3,\"max_patch_files\":100,\"max_patch_size\":4096,\"protect_top_level_dot_folders\":true,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"CODEOWNERS\",\"DESIGN.md\",\"README.md\",\"CONTRIBUTING.md\",\"CHANGELOG.md\",\"SECURITY.md\",\"CODE_OF_CONDUCT.md\",\"AGENTS.md\",\"CLAUDE.md\",\"GEMINI.md\"],\"protected_files_policy\":\"request_review\",\"title_prefix\":\"[ci-fix] \"},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"report_incomplete\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/ci-status-fix.md b/.github/workflows/ci-status-fix.md
index a2e40bdbf32b..f33b7f1d67b9 100644
--- a/.github/workflows/ci-status-fix.md
+++ b/.github/workflows/ci-status-fix.md
@@ -16,7 +16,19 @@ description: |
de-flakes genuinely flaky ones (deterministic synchronization, no retries /
timeout bumps). Always skips visual-regression / screenshot issues.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
permissions:
contents: read
@@ -36,6 +48,7 @@ on:
required: false
type: boolean
default: false
+ permissions: {}
if: |
github.repository == 'dotnet/maui'
@@ -43,6 +56,21 @@ if: |
engine:
id: copilot
model: claude-opus-4.8
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
concurrency:
group: "ci-status-fix"
diff --git a/.github/workflows/ci-status-main.lock.yml b/.github/workflows/ci-status-main.lock.yml
index c01a0491061f..36ed9991d455 100644
--- a/.github/workflows/ci-status-main.lock.yml
+++ b/.github/workflows/ci-status-main.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"b87b9d654a451bb9a07868d781e6f43842aef53fe2a3db54eaada2c168526d87","body_hash":"cc4672a01f4dfe8fc0b0078695d59139bc3385c49246674c67b36bfbb6c03b2b","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"e395e65c4805606a1e92dc3341d4dc5b650c6a4de7e4fd51529b9a92c3b1ae43","body_hash":"cc4672a01f4dfe8fc0b0078695d59139bc3385c49246674c67b36bfbb6c03b2b","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -27,30 +27,48 @@
# maui-pr-uitests). Files tracking issues for recurring failures so the team
# can triage.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "CI Failure Scanner"
on:
+ # permissions: {} # Permissions applied to pre-activation job
schedule:
- cron: "41 */12 * * *"
# Friendly format: every 12h (scattered)
@@ -72,6 +90,10 @@ run-name: "CI Failure Scanner"
jobs:
activation:
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-slim
permissions:
actions: read
@@ -94,16 +116,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -111,16 +135,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-sonnet-4.6"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet","dev.azure.com","helix.dot.net","*.blob.core.windows.net"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -131,6 +155,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusmain-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusmain-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -140,6 +188,8 @@ jobs:
GH_AW_WORKFLOW_ID: "ci-status-main"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -150,7 +200,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -186,7 +236,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -209,20 +259,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_c0472676713d4963_EOF'
+ cat << 'GH_AW_PROMPT_b77c635bc6fc7623_EOF'
- GH_AW_PROMPT_c0472676713d4963_EOF
+ GH_AW_PROMPT_b77c635bc6fc7623_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_c0472676713d4963_EOF'
+ cat << 'GH_AW_PROMPT_b77c635bc6fc7623_EOF'
Tools: create_issue(max:5), missing_tool, missing_data, noop
- GH_AW_PROMPT_c0472676713d4963_EOF
+ GH_AW_PROMPT_b77c635bc6fc7623_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_c0472676713d4963_EOF'
+ cat << 'GH_AW_PROMPT_b77c635bc6fc7623_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -264,12 +314,12 @@ jobs:
stop immediately and report the limitation rather than spending turns trying to work around it.
- GH_AW_PROMPT_c0472676713d4963_EOF
+ GH_AW_PROMPT_b77c635bc6fc7623_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_c0472676713d4963_EOF'
+ cat << 'GH_AW_PROMPT_b77c635bc6fc7623_EOF'
{{#runtime-import .github/workflows/ci-status-main.md}}
- GH_AW_PROMPT_c0472676713d4963_EOF
+ GH_AW_PROMPT_b77c635bc6fc7623_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -295,6 +345,7 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -314,7 +365,8 @@ jobs:
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -347,10 +399,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -385,7 +439,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -394,8 +448,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -406,7 +460,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
fetch-depth: 1
@@ -421,17 +475,10 @@ jobs:
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -447,11 +494,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -483,15 +530,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_790f0a7cf32fe47c_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_94c379f570fc39ec_EOF'
{"create_issue":{"allowed_labels":["ci-scan"],"close_older_issues":false,"labels":["ci-scan"],"max":5,"title_prefix":"[ci-scan] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_790f0a7cf32fe47c_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_94c379f570fc39ec_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -622,55 +669,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -696,16 +704,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_6fee703e54d76285_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_88cd2712aef28114_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -720,10 +728,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -741,7 +765,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_6fee703e54d76285_EOF
+ GH_AW_MCP_CONFIG_88cd2712aef28114_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -810,37 +834,65 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json","network":{"allowDomains":["*.blob.core.windows.net","*.vsblob.vsassets.io","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.nuget.org","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","azuresearch-usnc.nuget.org","azuresearch-ussc.nuget.org","builds.dotnet.microsoft.com","ci.dot.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","dc.services.visualstudio.com","dev.azure.com","dist.nuget.org","dot.net","dotnet.microsoft.com","dotnetcli.blob.core.windows.net","github.com","helix.dot.net","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","nuget.org","nuget.pkg.github.com","nugetregistryv2prod.blob.core.windows.net","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","oneocsp.microsoft.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","pkgs.dev.azure.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com","www.microsoft.com"]},"apiProxy":{"enabled":true,"maxRuns":500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"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*"],"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-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-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.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*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"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"],"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-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json","network":{"allowDomains":["*.blob.core.windows.net","*.vsblob.vsassets.io","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.nuget.org","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","azuresearch-usnc.nuget.org","azuresearch-ussc.nuget.org","builds.dotnet.microsoft.com","ci.dot.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","dc.services.visualstudio.com","dev.azure.com","dist.nuget.org","dot.net","dotnet.microsoft.com","dotnetcli.blob.core.windows.net","github.com","helix.dot.net","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","nuget.org","nuget.pkg.github.com","nugetregistryv2prod.blob.core.windows.net","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","oneocsp.microsoft.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","pkgs.dev.azure.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com","www.microsoft.com"]},"apiProxy":{"enabled":true,"maxRuns":500,"maxCacheMisses":5,"models":{"agent":["sonnet-6x","gpt-5.5","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"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*"],"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-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-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*"],"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*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"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"],"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-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d"}}' > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 60
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -855,6 +907,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -862,17 +915,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -896,8 +942,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1019,12 +1074,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1040,7 +1096,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1049,8 +1105,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1072,12 +1128,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1086,6 +1144,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1094,12 +1154,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusmain-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusmain-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusmain-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1219,7 +1321,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1230,7 +1332,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1239,8 +1341,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1258,7 +1360,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1267,7 +1369,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1330,11 +1432,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1353,37 +1455,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1397,6 +1518,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1450,6 +1572,114 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
+ await main();
+
safe_outputs:
needs:
- activation
@@ -1457,7 +1687,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1472,7 +1702,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-sonnet-4.6"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "ci-status-main"
GH_AW_WORKFLOW_NAME: "CI Failure Scanner"
@@ -1489,7 +1719,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1498,8 +1728,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-main.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1518,8 +1748,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
diff --git a/.github/workflows/ci-status-main.md b/.github/workflows/ci-status-main.md
index 58cd96db97e8..3392cce90b67 100644
--- a/.github/workflows/ci-status-main.md
+++ b/.github/workflows/ci-status-main.md
@@ -5,7 +5,19 @@ description: |
maui-pr-uitests). Files tracking issues for recurring failures so the team
can triage.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
permissions:
contents: read
@@ -14,10 +26,26 @@ permissions:
on:
schedule: every 12h
workflow_dispatch:
+ permissions: {}
engine:
id: copilot
model: claude-sonnet-4.6
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
concurrency:
group: "ci-failure-scan"
diff --git a/.github/workflows/ci-status-net11.lock.yml b/.github/workflows/ci-status-net11.lock.yml
index 5b075ff721a6..b3d9e8e7c8ef 100644
--- a/.github/workflows/ci-status-net11.lock.yml
+++ b/.github/workflows/ci-status-net11.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"832fbd19e6c971c8b67c95d8f359e61bfc87fc094b3f53b3d09c6009d9e67811","body_hash":"5d1e076d013495fd155ba8efebac086eec3cf76b5983e904673dae452bcc4142","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"931b207a2ab700506b6acc4c0f6532c6e596bd683b94e6563345d6665c1f787a","body_hash":"5d1e076d013495fd155ba8efebac086eec3cf76b5983e904673dae452bcc4142","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -27,30 +27,48 @@
# maui-pr-uitests). Files tracking issues for recurring failures so the team
# can triage.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "CI Failure Scanner (net11.0)"
on:
+ # permissions: {} # Permissions applied to pre-activation job
schedule:
- cron: "39 */12 * * *"
# Friendly format: every 12h (scattered)
@@ -72,6 +90,10 @@ run-name: "CI Failure Scanner (net11.0)"
jobs:
activation:
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-slim
permissions:
actions: read
@@ -94,16 +116,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -111,16 +135,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-sonnet-4.6"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet","dev.azure.com","helix.dot.net","*.blob.core.windows.net"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -131,6 +155,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusnet11-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusnet11-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -140,6 +188,8 @@ jobs:
GH_AW_WORKFLOW_ID: "ci-status-net11"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -150,7 +200,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -186,7 +236,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -209,20 +259,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_d21176ec68820ea6_EOF'
+ cat << 'GH_AW_PROMPT_33bb009c77865b2d_EOF'
- GH_AW_PROMPT_d21176ec68820ea6_EOF
+ GH_AW_PROMPT_33bb009c77865b2d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_d21176ec68820ea6_EOF'
+ cat << 'GH_AW_PROMPT_33bb009c77865b2d_EOF'
Tools: create_issue(max:5), missing_tool, missing_data, noop
- GH_AW_PROMPT_d21176ec68820ea6_EOF
+ GH_AW_PROMPT_33bb009c77865b2d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_d21176ec68820ea6_EOF'
+ cat << 'GH_AW_PROMPT_33bb009c77865b2d_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -264,12 +314,12 @@ jobs:
stop immediately and report the limitation rather than spending turns trying to work around it.
- GH_AW_PROMPT_d21176ec68820ea6_EOF
+ GH_AW_PROMPT_33bb009c77865b2d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_d21176ec68820ea6_EOF'
+ cat << 'GH_AW_PROMPT_33bb009c77865b2d_EOF'
{{#runtime-import .github/workflows/ci-status-net11.md}}
- GH_AW_PROMPT_d21176ec68820ea6_EOF
+ GH_AW_PROMPT_33bb009c77865b2d_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -295,6 +345,7 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -314,7 +365,8 @@ jobs:
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -347,10 +399,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -385,7 +439,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -394,8 +448,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -406,7 +460,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
ref: net11.0
@@ -422,17 +476,10 @@ jobs:
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -448,11 +495,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -484,15 +531,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_f8ce5cb9565667dc_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_3846a4dfed7ea530_EOF'
{"create_issue":{"allowed_labels":["ci-scan-net11"],"close_older_issues":false,"labels":["ci-scan-net11"],"max":5,"title_prefix":"[ci-scan-net11] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_f8ce5cb9565667dc_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_3846a4dfed7ea530_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -623,55 +670,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -697,16 +705,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_6fee703e54d76285_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_88cd2712aef28114_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -721,10 +729,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -742,7 +766,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_6fee703e54d76285_EOF
+ GH_AW_MCP_CONFIG_88cd2712aef28114_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -811,37 +835,65 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json","network":{"allowDomains":["*.blob.core.windows.net","*.vsblob.vsassets.io","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.nuget.org","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","azuresearch-usnc.nuget.org","azuresearch-ussc.nuget.org","builds.dotnet.microsoft.com","ci.dot.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","dc.services.visualstudio.com","dev.azure.com","dist.nuget.org","dot.net","dotnet.microsoft.com","dotnetcli.blob.core.windows.net","github.com","helix.dot.net","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","nuget.org","nuget.pkg.github.com","nugetregistryv2prod.blob.core.windows.net","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","oneocsp.microsoft.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","pkgs.dev.azure.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com","www.microsoft.com"]},"apiProxy":{"enabled":true,"maxRuns":500,"models":{"agent":["sonnet-6x","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"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*"],"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-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-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.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*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"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"],"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-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json","network":{"allowDomains":["*.blob.core.windows.net","*.vsblob.vsassets.io","api.business.githubcopilot.com","api.enterprise.githubcopilot.com","api.github.com","api.githubcopilot.com","api.individual.githubcopilot.com","api.nuget.org","api.snapcraft.io","archive.ubuntu.com","azure.archive.ubuntu.com","azuresearch-usnc.nuget.org","azuresearch-ussc.nuget.org","builds.dotnet.microsoft.com","ci.dot.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","dc.services.visualstudio.com","dev.azure.com","dist.nuget.org","dot.net","dotnet.microsoft.com","dotnetcli.blob.core.windows.net","github.com","helix.dot.net","host.docker.internal","json-schema.org","json.schemastore.org","keyserver.ubuntu.com","nuget.org","nuget.pkg.github.com","nugetregistryv2prod.blob.core.windows.net","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","oneocsp.microsoft.com","packagecloud.io","packages.cloud.google.com","packages.microsoft.com","pkgs.dev.azure.com","ppa.launchpad.net","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com","www.microsoft.com"]},"apiProxy":{"enabled":true,"maxRuns":500,"maxCacheMisses":5,"models":{"agent":["sonnet-6x","gpt-5.5","gpt-5.4","gpt-5.3","gemini-pro","any"],"antigravity":["copilot/antigravity*","google/antigravity*","gemini/antigravity*"],"any":["copilot/*","anthropic/*","openai/*","google/*","gemini/*"],"claude":["agent"],"codex":["agent"],"coding":["copilot/gpt-5*codex*","openai/gpt-5*codex*","gpt-5-codex"],"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*"],"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-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-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*"],"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*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mai-code":["copilot/MAI-Code*","copilot/mai-code*","openai/MAI-Code*"],"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"],"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-4-5-*","anthropic/*sonnet-4-5-*","copilot/*sonnet-4-6*","anthropic/*sonnet-4-6*"],"summarization":["haiku","gpt-5-mini","gemini-flash-lite","mini"],"vision":["copilot/gemini-*image*","google/gemini-*image*","gemini/gemini-*image*","copilot/gemini-*flash*","google/gemini-*flash*","gemini/gemini-*flash*"]}},"container":{"imageTag":"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d"}}' > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(awk)'\'' --allow-tool '\''shell(basename)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(curl:*)'\'' --allow-tool '\''shell(cut)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(dirname)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(find)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(mkdir)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sed)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(tee)'\'' --allow-tool '\''shell(test)'\'' --allow-tool '\''shell(tr)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(xargs)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 60
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -856,6 +908,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -863,17 +916,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -897,8 +943,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1020,12 +1075,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1041,7 +1097,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1050,8 +1106,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1073,12 +1129,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1087,6 +1145,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1095,12 +1155,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusnet11-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-cistatusnet11-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-cistatusnet11-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1220,7 +1322,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1231,7 +1333,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1240,8 +1342,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1259,7 +1361,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1268,7 +1370,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1331,11 +1433,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1354,37 +1456,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1398,6 +1519,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1451,6 +1573,114 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
+ await main();
+
safe_outputs:
needs:
- activation
@@ -1458,7 +1688,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1473,7 +1703,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-sonnet-4.6"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "ci-status-net11"
GH_AW_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
@@ -1490,7 +1720,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1499,8 +1729,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "CI Failure Scanner (net11.0)"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/ci-status-net11.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1519,8 +1749,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
diff --git a/.github/workflows/ci-status-net11.md b/.github/workflows/ci-status-net11.md
index 936fd74a569f..988fa087ce70 100644
--- a/.github/workflows/ci-status-net11.md
+++ b/.github/workflows/ci-status-net11.md
@@ -5,7 +5,19 @@ description: |
maui-pr-uitests). Files tracking issues for recurring failures so the team
can triage.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
permissions:
contents: read
@@ -14,10 +26,26 @@ permissions:
on:
schedule: every 12h
workflow_dispatch:
+ permissions: {}
engine:
id: copilot
model: claude-sonnet-4.6
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
concurrency:
group: "ci-failure-scan-net11"
diff --git a/.github/workflows/copilot-evaluate-tests.lock.yml b/.github/workflows/copilot-evaluate-tests.lock.yml
index 9e7454c80c1b..b06ad1d2aa64 100644
--- a/.github/workflows/copilot-evaluate-tests.lock.yml
+++ b/.github/workflows/copilot-evaluate-tests.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5e4d741e29aa359a3e7b80751d2b01561ce91279ff3964fa8b5aa5cc0a7f92e8","body_hash":"cb7d41851b9355ba40d25a5af58e07b83e92fa728d0379627a4285e630fcbc6a","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"0880f06d6b05634662358b96be7f3d11985091677cb6e8a893ba27f6998947b2","body_hash":"cb7d41851b9355ba40d25a5af58e07b83e92fa728d0379627a4285e630fcbc6a","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -25,27 +25,44 @@
#
# Evaluates test quality, coverage, and appropriateness on PRs that add or modify tests
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "Evaluate PR Tests"
on:
@@ -86,7 +103,9 @@ run-name: "Evaluate PR Tests"
jobs:
activation:
- needs: pre_activation
+ needs:
+ - pat_pool
+ - pre_activation
if: >
needs.pre_activation.outputs.activated == 'true' && (github.event_name == 'issue_comment' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-slim
@@ -118,7 +137,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -128,8 +147,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -137,16 +156,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-sonnet-4.6"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -157,6 +176,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotevaluatetests-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-copilotevaluatetests-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -166,6 +209,8 @@ jobs:
GH_AW_WORKFLOW_ID: "copilot-evaluate-tests"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "true"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -189,7 +234,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -225,7 +270,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -277,20 +322,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_be07805ac95f17c1_EOF'
+ cat << 'GH_AW_PROMPT_61d4fd5068b72518_EOF'
- GH_AW_PROMPT_be07805ac95f17c1_EOF
+ GH_AW_PROMPT_61d4fd5068b72518_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_be07805ac95f17c1_EOF'
+ cat << 'GH_AW_PROMPT_61d4fd5068b72518_EOF'
Tools: add_comment, missing_tool, missing_data, noop
- GH_AW_PROMPT_be07805ac95f17c1_EOF
+ GH_AW_PROMPT_61d4fd5068b72518_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_be07805ac95f17c1_EOF'
+ cat << 'GH_AW_PROMPT_61d4fd5068b72518_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -319,15 +364,15 @@ jobs:
{{/if}}
- GH_AW_PROMPT_be07805ac95f17c1_EOF
+ GH_AW_PROMPT_61d4fd5068b72518_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
fi
- cat << 'GH_AW_PROMPT_be07805ac95f17c1_EOF'
+ cat << 'GH_AW_PROMPT_61d4fd5068b72518_EOF'
{{#runtime-import .github/workflows/copilot-evaluate-tests.md}}
- GH_AW_PROMPT_be07805ac95f17c1_EOF
+ GH_AW_PROMPT_61d4fd5068b72518_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -421,10 +466,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -457,7 +504,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -466,8 +513,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -478,7 +525,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -495,17 +542,10 @@ jobs:
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -521,11 +561,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -557,15 +597,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_15e52e390d7a6e75_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_eda463bbdf806a9b_EOF'
{"add_comment":{"hide_older_comments":true,"max":1,"target":"*"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_15e52e390d7a6e75_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_eda463bbdf806a9b_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -681,55 +721,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -755,16 +756,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -779,10 +780,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -800,7 +817,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
+ GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -839,38 +856,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -885,6 +931,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -892,17 +939,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -926,8 +966,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1050,15 +1099,15 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
- discussions: write
issues: write
pull-requests: write
concurrency:
@@ -1073,7 +1122,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1082,8 +1131,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1105,12 +1154,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1119,6 +1170,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1127,12 +1180,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotevaluatetests-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-copilotevaluatetests-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotevaluatetests-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1274,7 +1369,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1285,7 +1380,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1294,8 +1389,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1313,7 +1408,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1322,7 +1417,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1385,11 +1480,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1408,37 +1503,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1452,6 +1566,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1505,12 +1620,85 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
pre_activation:
if: >
(github.event_name != 'issue_comment' && github.event_name != 'pull_request_review_comment' || contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association) ||
github.actor == 'copilot-swe-agent[bot]') && (github.event_name == 'issue_comment' || github.event_name == 'workflow_dispatch')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
outputs:
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' && steps.check_command_position.outputs.command_position_ok == 'true' }}
matched_command: ${{ steps.check_command_position.outputs.matched_command }}
@@ -1520,15 +1708,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Check team membership for command workflow
id: check_membership
@@ -1562,10 +1750,9 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
- discussions: write
issues: write
pull-requests: write
timeout-minutes: 45
@@ -1580,7 +1767,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-sonnet-4.6"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🧪 *Test evaluation by [{workflow_name}]({run_url})*\",\"runStarted\":\"🔬 Evaluating tests on this PR… [{workflow_name}]({run_url})\",\"runSuccess\":\"✅ Test evaluation complete! [{workflow_name}]({run_url})\",\"runFailure\":\"❌ Test evaluation failed. [{workflow_name}]({run_url}) {status}\"}"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "copilot-evaluate-tests"
@@ -1598,7 +1785,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1607,8 +1794,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Evaluate PR Tests"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-evaluate-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1627,8 +1814,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
diff --git a/.github/workflows/copilot-evaluate-tests.md b/.github/workflows/copilot-evaluate-tests.md
index 6b52d956e988..6ff198ada184 100644
--- a/.github/workflows/copilot-evaluate-tests.md
+++ b/.github/workflows/copilot-evaluate-tests.md
@@ -1,7 +1,19 @@
---
description: Evaluates test quality, coverage, and appropriateness on PRs that add or modify tests
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
on:
# pull_request_target is intentionally disabled — we don't want auto-runs on PR create/update.
@@ -44,6 +56,21 @@ permissions:
engine:
id: copilot
model: claude-sonnet-4.6
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
safe-outputs:
add-comment:
diff --git a/.github/workflows/copilot-review-tests.lock.yml b/.github/workflows/copilot-review-tests.lock.yml
index 96e2b246cc95..00317f436f5c 100644
--- a/.github/workflows/copilot-review-tests.lock.yml
+++ b/.github/workflows/copilot-review-tests.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9ab192f5db28928c77ad216be142ee5cc92df89e30836d460acbc8f281adb85e","body_hash":"501c316db7803b2e8550b528e9dcfcca5a9270d1d971beccedf8bc2be6af5c39","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"4ab52d614b79796382b8ac25207ef355ed42fb5ddcd4b37a53f87f2360677b0d","body_hash":"501c316db7803b2e8550b528e9dcfcca5a9270d1d971beccedf8bc2be6af5c39","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","agent_model":"claude-sonnet-4.6","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -25,27 +25,44 @@
#
# Reviews PR CI/test failures and classifies whether they are likely caused by the PR or unrelated.
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "Review PR Test Failures"
on:
@@ -133,7 +150,9 @@ run-name: "Review PR Test Failures"
jobs:
activation:
- needs: pre_activation
+ needs:
+ - pat_pool
+ - pre_activation
if: >
needs.pre_activation.outputs.activated == 'true' && (github.event_name == 'workflow_dispatch' || needs.pre_activation.outputs.exact_command_should_run == 'true')
runs-on: ubuntu-slim
@@ -162,7 +181,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -172,8 +191,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -181,16 +200,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: "claude-sonnet-4.6"
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet","github","dev.azure.com","*.visualstudio.com","helix.dot.net","*.blob.core.windows.net","img.shields.io"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -201,6 +220,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotreviewtests-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-copilotreviewtests-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -210,6 +253,8 @@ jobs:
GH_AW_WORKFLOW_ID: "copilot-review-tests"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "true"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -220,7 +265,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -256,7 +301,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -296,20 +341,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_068efbf1d2f63f6d_EOF'
+ cat << 'GH_AW_PROMPT_d762c8f49c7ab56d_EOF'
- GH_AW_PROMPT_068efbf1d2f63f6d_EOF
+ GH_AW_PROMPT_d762c8f49c7ab56d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_068efbf1d2f63f6d_EOF'
+ cat << 'GH_AW_PROMPT_d762c8f49c7ab56d_EOF'
Tools: add_comment, missing_tool, missing_data, noop
- GH_AW_PROMPT_068efbf1d2f63f6d_EOF
+ GH_AW_PROMPT_d762c8f49c7ab56d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_068efbf1d2f63f6d_EOF'
+ cat << 'GH_AW_PROMPT_d762c8f49c7ab56d_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -338,15 +383,15 @@ jobs:
{{/if}}
- GH_AW_PROMPT_068efbf1d2f63f6d_EOF
+ GH_AW_PROMPT_d762c8f49c7ab56d_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
fi
- cat << 'GH_AW_PROMPT_068efbf1d2f63f6d_EOF'
+ cat << 'GH_AW_PROMPT_d762c8f49c7ab56d_EOF'
{{#runtime-import .github/workflows/copilot-review-tests.md}}
- GH_AW_PROMPT_068efbf1d2f63f6d_EOF
+ GH_AW_PROMPT_d762c8f49c7ab56d_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -446,10 +491,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
actions: read
checks: read
@@ -484,7 +531,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -493,8 +540,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -505,7 +552,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -542,17 +589,10 @@ jobs:
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -568,11 +608,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -604,15 +644,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_2fbc93150996d70c_EOF'
- {"add_comment":{"footer":false,"hide_older_comments":true,"max":1,"target":"*"},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_2fbc93150996d70c_EOF
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_892717376c0ab1a9_EOF'
+ {"add_comment":{"discussions":false,"footer":false,"hide_older_comments":true,"max":1,"target":"*"},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
+ GH_AW_SAFE_OUTPUTS_CONFIG_892717376c0ab1a9_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -728,55 +768,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -802,16 +803,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -826,10 +827,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -847,7 +864,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
+ GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -886,38 +903,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"*.visualstudio.com\",\"*.vsblob.vsassets.io\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.nuget.org\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"azuresearch-usnc.nuget.org\",\"azuresearch-ussc.nuget.org\",\"builds.dotnet.microsoft.com\",\"ci.dot.net\",\"codeload.github.com\",\"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\",\"dc.services.visualstudio.com\",\"dev.azure.com\",\"dist.nuget.org\",\"docs.github.com\",\"dot.net\",\"dotnet.microsoft.com\",\"dotnetcli.blob.core.windows.net\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"img.shields.io\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"nuget.org\",\"nuget.pkg.github.com\",\"nugetregistryv2prod.blob.core.windows.net\",\"objects.githubusercontent.com\",\"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\",\"oneocsp.microsoft.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"patch-diff.githubusercontent.com\",\"pkgs.dev.azure.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\",\"www.microsoft.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"*.blob.core.windows.net\",\"*.githubusercontent.com\",\"*.visualstudio.com\",\"*.vsblob.vsassets.io\",\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.nuget.org\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"azuresearch-usnc.nuget.org\",\"azuresearch-ussc.nuget.org\",\"builds.dotnet.microsoft.com\",\"ci.dot.net\",\"codeload.github.com\",\"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\",\"dc.services.visualstudio.com\",\"dev.azure.com\",\"dist.nuget.org\",\"docs.github.com\",\"dot.net\",\"dotnet.microsoft.com\",\"dotnetcli.blob.core.windows.net\",\"github-cloud.githubusercontent.com\",\"github-cloud.s3.amazonaws.com\",\"github.blog\",\"github.com\",\"github.githubassets.com\",\"helix.dot.net\",\"host.docker.internal\",\"img.shields.io\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"lfs.github.com\",\"nuget.org\",\"nuget.pkg.github.com\",\"nugetregistryv2prod.blob.core.windows.net\",\"objects.githubusercontent.com\",\"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\",\"oneocsp.microsoft.com\",\"packagecloud.io\",\"packages.cloud.google.com\",\"packages.microsoft.com\",\"patch-diff.githubusercontent.com\",\"pkgs.dev.azure.com\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\",\"www.microsoft.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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: 30
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -932,6 +978,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -939,17 +986,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -973,8 +1013,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1097,12 +1146,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1119,7 +1169,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1128,8 +1178,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1151,12 +1201,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1165,6 +1217,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1173,12 +1227,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotreviewtests-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-copilotreviewtests-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-copilotreviewtests-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1300,7 +1396,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1311,7 +1407,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1320,8 +1416,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1339,7 +1435,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1348,7 +1444,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1411,11 +1507,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1434,37 +1530,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: claude-sonnet-4.6
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1478,6 +1593,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1531,12 +1647,85 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
pre_activation:
if: >
(!(github.event_name == 'issue_comment') || !contains(fromJSON('["CONTRIBUTOR","FIRST_TIME_CONTRIBUTOR","FIRST_TIMER","MANNEQUIN","NONE"]'), github.event.comment.author_association)) &&
(!(github.event_name == 'pull_request_review_comment') || !contains(fromJSON('["CONTRIBUTOR","FIRST_TIME_CONTRIBUTOR","FIRST_TIMER","MANNEQUIN","NONE"]'), github.event.comment.author_association))
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
issues: write
pull-requests: write
@@ -1551,15 +1740,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Check team membership for command workflow
id: check_membership
@@ -1658,7 +1847,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1675,7 +1864,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: "claude-sonnet-4.6"
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "copilot-review-tests"
GH_AW_WORKFLOW_NAME: "Review PR Test Failures"
@@ -1692,7 +1881,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1701,8 +1890,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Review PR Test Failures"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/copilot-review-tests.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1721,8 +1910,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
@@ -1737,7 +1925,7 @@ jobs:
GH_AW_ALLOWED_DOMAINS: "*.blob.core.windows.net,*.githubusercontent.com,*.visualstudio.com,*.vsblob.vsassets.io,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.nuget.org,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,builds.dotnet.microsoft.com,ci.dot.net,codeload.github.com,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,dc.services.visualstudio.com,dev.azure.com,dist.nuget.org,docs.github.com,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,helix.dot.net,host.docker.internal,img.shields.io,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,objects.githubusercontent.com,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,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,patch-diff.githubusercontent.com,pkgs.dev.azure.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.microsoft.com"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
- GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"footer\":false,\"hide_older_comments\":true,\"max\":1,\"target\":\"*\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}"
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"discussions\":false,\"footer\":false,\"hide_older_comments\":true,\"max\":1,\"target\":\"*\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
diff --git a/.github/workflows/copilot-review-tests.md b/.github/workflows/copilot-review-tests.md
index af2ebeeabde5..d2d03acfa008 100644
--- a/.github/workflows/copilot-review-tests.md
+++ b/.github/workflows/copilot-review-tests.md
@@ -1,7 +1,19 @@
---
description: Reviews PR CI/test failures and classifies whether they are likely caused by the PR or unrelated.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
on:
slash_command:
@@ -132,6 +144,21 @@ permissions:
engine:
id: copilot
model: claude-sonnet-4.6
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
safe-outputs:
add-comment:
diff --git a/.github/workflows/daily-repo-status.lock.yml b/.github/workflows/daily-repo-status.lock.yml
index 6d372a6fbbbd..de76374b09f9 100644
--- a/.github/workflows/daily-repo-status.lock.yml
+++ b/.github/workflows/daily-repo-status.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"f209ec8e35ee3940024b2b28050a2527b6e553a64d930d6af36e4f9d484518c4","body_hash":"75c37e9b2ccbbeb08f3cadd5c48cc07d65be87f78e73fc18f33b9b9288deb970","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"e040aa962aa79fa151fa77c1da0dae5c48a60739c98a82c877f55d1d628a82ec","body_hash":"75c37e9b2ccbbeb08f3cadd5c48cc07d65be87f78e73fc18f33b9b9288deb970","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -30,30 +30,48 @@
#
# Source: githubnext/agentics/workflows/daily-repo-status.md@69b5e3ae5fa7f35fa555b0a22aee14c36ab57ebb
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "Daily Repo Status"
on:
+ # permissions: {} # Permissions applied to pre-activation job
schedule:
- cron: "20 2 * * *"
# Friendly format: daily (scattered)
@@ -74,6 +92,10 @@ run-name: "Daily Repo Status"
jobs:
activation:
+ needs:
+ - pat_pool
+ - pre_activation
+ if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-slim
permissions:
actions: read
@@ -96,16 +118,18 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
+ trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
+ parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
@@ -114,16 +138,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_INFO_FRONTMATTER_SOURCE: "githubnext/agentics/workflows/daily-repo-status.md@69b5e3ae5fa7f35fa555b0a22aee14c36ab57ebb"
@@ -136,6 +160,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-dailyrepostatus-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-dailyrepostatus-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -145,6 +193,8 @@ jobs:
GH_AW_WORKFLOW_ID: "daily-repo-status"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -155,7 +205,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -191,7 +241,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -214,20 +264,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_8dd71881bbaf7b2f_EOF'
+ cat << 'GH_AW_PROMPT_0138ee703a7549ac_EOF'
- GH_AW_PROMPT_8dd71881bbaf7b2f_EOF
+ GH_AW_PROMPT_0138ee703a7549ac_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_8dd71881bbaf7b2f_EOF'
+ cat << 'GH_AW_PROMPT_0138ee703a7549ac_EOF'
Tools: create_issue, missing_tool, missing_data, noop
- GH_AW_PROMPT_8dd71881bbaf7b2f_EOF
+ GH_AW_PROMPT_0138ee703a7549ac_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_8dd71881bbaf7b2f_EOF'
+ cat << 'GH_AW_PROMPT_0138ee703a7549ac_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -256,12 +306,12 @@ jobs:
{{/if}}
- GH_AW_PROMPT_8dd71881bbaf7b2f_EOF
+ GH_AW_PROMPT_0138ee703a7549ac_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_8dd71881bbaf7b2f_EOF'
+ cat << 'GH_AW_PROMPT_0138ee703a7549ac_EOF'
{{#runtime-import .github/workflows/daily-repo-status.md}}
- GH_AW_PROMPT_8dd71881bbaf7b2f_EOF
+ GH_AW_PROMPT_0138ee703a7549ac_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -287,6 +337,7 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -306,7 +357,8 @@ jobs:
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
- GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST
+ GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -339,10 +391,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -378,7 +432,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -387,8 +441,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
@@ -400,7 +454,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -411,17 +465,10 @@ jobs:
GH_TOKEN: ${{ github.token }}
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -437,11 +484,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -473,15 +520,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_c99a053b00c52f16_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_3f58008c760b9373_EOF'
{"create_issue":{"close_older_issues":true,"labels":["report","daily-status","s/triaged"],"max":1,"title_prefix":"[repo-status] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_c99a053b00c52f16_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_3f58008c760b9373_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -612,55 +659,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -686,16 +694,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -710,10 +718,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -731,7 +755,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
+ GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -770,38 +794,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -816,6 +869,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -823,17 +877,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -857,8 +904,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -980,12 +1036,13 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1001,7 +1058,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1010,8 +1067,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@@ -1034,12 +1091,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1048,6 +1107,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1056,12 +1117,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
+ if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-dailyrepostatus-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-dailyrepostatus-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-dailyrepostatus-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1186,7 +1289,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1197,7 +1300,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1206,8 +1309,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@@ -1226,7 +1329,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1235,7 +1338,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1298,11 +1401,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1321,37 +1424,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1365,6 +1487,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1418,6 +1541,115 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
+ pre_activation:
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
+ matched_command: ''
+ setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
+ setup-span-id: ${{ steps.setup.outputs.span-id }}
+ setup-trace-id: ${{ steps.setup.outputs.trace-id }}
+ steps:
+ - name: Setup Scripts
+ id: setup
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+ job-name: ${{ github.job }}
+ env:
+ GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
+ GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
+ GH_AW_INFO_BODY_MODIFIED: "false"
+ GH_AW_INFO_ENGINE_ID: "copilot"
+ - name: Check team membership for workflow
+ id: check_membership
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
+ await main();
+
safe_outputs:
needs:
- activation
@@ -1425,7 +1657,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: write
@@ -1440,7 +1672,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "daily-repo-status"
GH_AW_WORKFLOW_NAME: "Daily Repo Status"
@@ -1458,7 +1690,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1467,8 +1699,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Daily Repo Status"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/daily-repo-status.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_BODY_MODIFIED: "false"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
@@ -1488,8 +1720,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
diff --git a/.github/workflows/daily-repo-status.md b/.github/workflows/daily-repo-status.md
index 7eab97383915..58adbc0d6da3 100644
--- a/.github/workflows/daily-repo-status.md
+++ b/.github/workflows/daily-repo-status.md
@@ -5,17 +5,48 @@ description: |
engaging GitHub issues with productivity insights, community highlights,
and project recommendations.
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
on:
schedule: daily
workflow_dispatch:
+ permissions: {}
permissions:
contents: read
issues: read
pull-requests: read
+engine:
+ id: copilot
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
+
network: defaults
tools:
diff --git a/.github/workflows/rerun-review-scanner.lock.yml b/.github/workflows/rerun-review-scanner.lock.yml
index 64660bc68d65..6ff5babb8707 100644
--- a/.github/workflows/rerun-review-scanner.lock.yml
+++ b/.github/workflows/rerun-review-scanner.lock.yml
@@ -1,6 +1,6 @@
-# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"dd5d57350192a7e8bced05dcedf7f7d122fa0b6b7217e81fe029b1bdf79f248c","body_hash":"b61efa7a397c7694bcae4e12ea6949a10279ade9417a9b1406c3682e827680bf","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
-# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"34e114876b0b11c390a56381ad16ebd13914f8d5","version":"v4"},{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/github-script","sha":"ed597411d8f924073f98dfc5c65a23a2325f34cd","version":"v8"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
-# This file was automatically generated by gh-aw (v0.79.8). 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":"75602053265ee75ec25af3c90d2567e8402ce2950347f38f1d8fc638a8a0f8a9","body_hash":"b61efa7a397c7694bcae4e12ea6949a10279ade9417a9b1406c3682e827680bf","compiler_version":"v0.80.9","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63"}}
+# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"34e114876b0b11c390a56381ad16ebd13914f8d5","version":"v4"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/github-script","sha":"ed597411d8f924073f98dfc5c65a23a2325f34cd","version":"v8"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"8c7d04ebf1ece56cd381446125da3e0f6896294a","version":"v0.80.9"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]}
+# This file was automatically generated by gh-aw (v0.80.9). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
#
# ___ _ _
# / _ \ | | (_)
@@ -24,29 +24,46 @@
# For more information: https://github.github.com/gh-aw/introduction/overview/
#
#
+# Resolved workflow manifest:
+# Imports:
+# - shared/pat_pool.md
+#
# Secrets used:
-# - COPILOT_GITHUB_TOKEN
+# - COPILOT_PAT_0
+# - COPILOT_PAT_1
+# - COPILOT_PAT_2
+# - COPILOT_PAT_3
+# - COPILOT_PAT_4
+# - COPILOT_PAT_5
+# - COPILOT_PAT_6
+# - COPILOT_PAT_7
+# - COPILOT_PAT_8
+# - COPILOT_PAT_9
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
# - GH_AW_GITHUB_TOKEN
# - GITHUB_TOKEN
#
# Custom actions used:
+# - actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+# - actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
# - actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
-# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+# - actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
+# - actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+# - github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
#
# Container images used:
-# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
-# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
-# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
-# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
-# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+# - ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6
+# - ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
+# - ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7
+# - ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b
+# - ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
name: "Rerun Review Scanner"
on:
@@ -116,7 +133,9 @@ run-name: "Rerun Review Scanner"
jobs:
activation:
- needs: pre_activation
+ needs:
+ - pat_pool
+ - pre_activation
if: needs.pre_activation.outputs.activated == 'true'
runs-on: ubuntu-slim
permissions:
@@ -140,7 +159,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -150,8 +169,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Generate agentic run info
id: generate_aw_info
@@ -159,16 +178,16 @@ jobs:
GH_AW_INFO_ENGINE_ID: "copilot"
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AGENT_VERSION: "1.0.60"
- GH_AW_INFO_CLI_VERSION: "v0.79.8"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AGENT_VERSION: "1.0.63"
+ GH_AW_INFO_CLI_VERSION: "v0.80.9"
GH_AW_INFO_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -179,6 +198,30 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-rerunreviewscanner-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-rerunreviewscanner-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Restore daily AIC usage cache (artifact fallback)
+ id: restore-daily-aic-cache-fallback
+ if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ env:
+ GH_AW_RESTORE_DAILY_AIC_CACHE_HIT: ${{ steps.restore-daily-aic-cache.outputs.cache-hit }}
+ GH_AW_RESTORE_DAILY_AIC_CACHE_MATCHED_KEY: ${{ steps.restore-daily-aic-cache.outputs.cache-matched-key }}
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/restore_aic_usage_cache_fallback.cjs');
+ await main();
- name: Check daily workflow token guardrail
id: daily-effective-workflow-guardrail
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
@@ -188,6 +231,8 @@ jobs:
GH_AW_WORKFLOW_ID: "rerun-review-scanner"
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
+ GH_AW_HAS_SLASH_COMMAND: "false"
+ GH_AW_HAS_LABEL_COMMAND: "false"
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
with:
@@ -198,7 +243,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
await main();
- name: Checkout .github and .agents folders
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
@@ -234,7 +279,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.79.8"
+ GH_AW_COMPILED_VERSION: "v0.80.9"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -258,20 +303,20 @@ jobs:
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_b108be01b40444cc_EOF'
+ cat << 'GH_AW_PROMPT_b2c4be8e26e80dff_EOF'
- GH_AW_PROMPT_b108be01b40444cc_EOF
+ GH_AW_PROMPT_b2c4be8e26e80dff_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_b108be01b40444cc_EOF'
+ cat << 'GH_AW_PROMPT_b2c4be8e26e80dff_EOF'
Tools: missing_tool, missing_data, noop, trigger_rerun_review
- GH_AW_PROMPT_b108be01b40444cc_EOF
+ GH_AW_PROMPT_b2c4be8e26e80dff_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_b108be01b40444cc_EOF'
+ cat << 'GH_AW_PROMPT_b2c4be8e26e80dff_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -300,12 +345,12 @@ jobs:
{{/if}}
- GH_AW_PROMPT_b108be01b40444cc_EOF
+ GH_AW_PROMPT_b2c4be8e26e80dff_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_b108be01b40444cc_EOF'
+ cat << 'GH_AW_PROMPT_b2c4be8e26e80dff_EOF'
{{#runtime-import .github/workflows/rerun-review-scanner.md}}
- GH_AW_PROMPT_b108be01b40444cc_EOF
+ GH_AW_PROMPT_b2c4be8e26e80dff_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -388,10 +433,12 @@ jobs:
retention-days: 1
agent:
- needs: activation
+ needs:
+ - activation
+ - pat_pool
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
issues: read
@@ -427,7 +474,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -436,8 +483,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -448,7 +495,7 @@ jobs:
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
} >> "$GITHUB_OUTPUT"
- name: Checkout repository
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Create gh-aw temp directory
@@ -459,17 +506,10 @@ jobs:
GH_TOKEN: ${{ github.token }}
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Checkout PR branch
id: checkout-pr
if: |
@@ -485,11 +525,11 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
@@ -521,15 +561,15 @@ 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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96 ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7 ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036
- name: Generate Safe Outputs Config
run: |
mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs"
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
- cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_1f38ac9195d9373d_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_82fab3fb625c2dcc_EOF'
{"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"trigger-rerun-review":{"description":"Apply validated rerun scanner decisions. Call EXACTLY ONCE per run, passing a `decisions` JSON array with one entry per candidate PR.","inputs":{"decisions":{"default":null,"description":"JSON array of decision objects, one per candidate PR. Each object: pr_number (string), decision ('trigger'|'skip'), rerun_comment_id (string), expected_head_sha (string), reason (short string), and optional platform and pipeline_ref strings.","required":true,"type":"string"}},"output":"Rerun scanner decisions processed."}}
- GH_AW_SAFE_OUTPUTS_CONFIG_1f38ac9195d9373d_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_82fab3fb625c2dcc_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -639,55 +679,16 @@ jobs:
setupGlobals(core, github, context, exec, io, getOctokit);
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
await main();
- - name: Generate Safe Outputs MCP Server Config
- id: safe-outputs-config
- run: |
- # Generate a secure random API key (360 bits of entropy, 40+ chars)
- # Mask immediately to prevent timing vulnerabilities
- API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
- echo "::add-mask::${API_KEY}"
-
- PORT=3001
-
- # Set outputs for next steps
- {
- echo "safe_outputs_api_key=${API_KEY}"
- echo "safe_outputs_port=${PORT}"
- } >> "$GITHUB_OUTPUT"
-
- echo "Safe Outputs MCP server will run on port ${PORT}"
-
- - name: Start Safe Outputs MCP HTTP Server
- id: safe-outputs-start
- env:
- DEBUG: '*'
- GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
- GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
- GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
- GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
- run: |
- # Environment variables are set above to prevent template injection
- export DEBUG
- export GH_AW_SAFE_OUTPUTS
- export GH_AW_SAFE_OUTPUTS_PORT
- export GH_AW_SAFE_OUTPUTS_API_KEY
- export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
- export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
- export GH_AW_MCP_LOG_DIR
-
- bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
-
- name: Start MCP Gateway
id: start-mcp-gateway
env:
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
- GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
- GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_CONFIG_PATH }}
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS_TOOLS_PATH }}
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -eo pipefail
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
@@ -713,16 +714,16 @@ jobs:
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
esac
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
- export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
+ export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --name awmg-mcpg --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DOCKER_HOST=unix:///var/run/docker.sock -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e RUNNER_TEMP -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw -v '"${RUNNER_TEMP}"'/gh-aw/safeoutputs:'"${RUNNER_TEMP}"'/gh-aw/safeoutputs:rw ghcr.io/github/gh-aw-mcpg:v0.3.27'
mkdir -p "$HOME/.copilot"
GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- cat << GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.1.2",
+ "container": "ghcr.io/github/github-mcp-server:v1.4.0",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -737,10 +738,26 @@ jobs:
}
},
"safeoutputs": {
- "type": "http",
- "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
- "headers": {
- "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
+ "type": "stdio",
+ "container": "ghcr.io/github/gh-aw-node",
+ "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "${RUNNER_TEMP}/gh-aw/safeoutputs:${RUNNER_TEMP}/gh-aw/safeoutputs:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"],
+ "args": ["-w", "\${GITHUB_WORKSPACE}"],
+ "entrypoint": "sh",
+ "entrypointArgs": ["-c", "sh ${RUNNER_TEMP}/gh-aw/safeoutputs/start_safe_outputs_mcp.sh"],
+ "env": {
+ "DEBUG": "*",
+ "DEFAULT_BRANCH": "\${DEFAULT_BRANCH}",
+ "GH_AW_ASSETS_ALLOWED_EXTS": "\${GH_AW_ASSETS_ALLOWED_EXTS}",
+ "GH_AW_ASSETS_BRANCH": "\${GH_AW_ASSETS_BRANCH}",
+ "GH_AW_ASSETS_MAX_SIZE_KB": "\${GH_AW_ASSETS_MAX_SIZE_KB}",
+ "GH_AW_MCP_LOG_DIR": "\${GH_AW_MCP_LOG_DIR}",
+ "GH_AW_SAFE_OUTPUTS": "\${GH_AW_SAFE_OUTPUTS}",
+ "GH_AW_SAFE_OUTPUTS_CONFIG_PATH": "\${GH_AW_SAFE_OUTPUTS_CONFIG_PATH}",
+ "GH_AW_SAFE_OUTPUTS_TOOLS_PATH": "\${GH_AW_SAFE_OUTPUTS_TOOLS_PATH}",
+ "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}",
+ "GITHUB_TOKEN": "\${GITHUB_TOKEN}",
+ "GITHUB_WORKSPACE": "\${GITHUB_WORKSPACE}",
+ "RUNNER_TEMP": "\${RUNNER_TEMP}"
},
"guard-policies": {
"write-sink": {
@@ -758,7 +775,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
+ GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -797,38 +814,67 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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.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*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-1000}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.com\",\"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\",\"github.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.com\",\"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\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.5\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"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*\"],\"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-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-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*\"],\"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*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"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\"],\"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-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ python3 - <<'PY'
+ import json,os,subprocess as sp
+ from pathlib import Path
+ try:
+ p=Path(os.environ["RUNNER_TEMP"])/"gh-aw"/"awf-config.json"
+ c=json.loads(p.read_text())
+ c["chroot"]={"binariesSourcePath":"/tmp/gh-aw","identity":{"user":sp.check_output(["id","-un"],text=True).strip(),"uid":int(sp.check_output(["id","-u"],text=True)),"gid":int(sp.check_output(["id","-g"],text=True)),"home":"/tmp/gh-aw/home"}}
+ out=json.dumps(c,separators=(",",":"),ensure_ascii=False)+"\n"
+ p.write_text(out)
+ Path("/tmp/gh-aw/awf-config.json").write_text(out)
+ except Exception as e:
+ raise SystemExit(f"chroot config patch failed: {e}") from e
+ PY
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: agent
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.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -843,6 +889,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Detect agent errors
if: always()
id: detect-agent-errors
@@ -850,17 +897,10 @@ jobs:
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
- name: Configure Git credentials
env:
- REPO_NAME: ${{ github.repository }}
- SERVER_URL: ${{ github.server_url }}
+ GITHUB_REPOSITORY: ${{ github.repository }}
+ GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_TOKEN: ${{ github.token }}
- run: |
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
- git config --global user.name "github-actions[bot]"
- git config --global am.keepcr true
- # Re-authenticate git with GitHub token
- SERVER_URL_STRIPPED="${SERVER_URL#https://}"
- git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
- echo "Git configured with standard GitHub Actions identity"
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_git_credentials.sh"
- name: Copy Copilot session state files to logs
if: always()
continue-on-error: true
@@ -884,8 +924,17 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
await main();
env:
- GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
- SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
+ SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1007,13 +1056,14 @@ jobs:
- activation
- agent
- detection
+ - pat_pool
- safe_outputs
- trigger_rerun_review
if: >
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions: {}
concurrency:
group: "gh-aw-conclusion-rerun-review-scanner"
@@ -1027,7 +1077,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1036,8 +1086,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1059,12 +1109,14 @@ jobs:
run: |
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
echo "Usage artifact source file status:"
- for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
+ for file in /tmp/gh-aw/aw_info.json /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
done
+ [ -f /tmp/gh-aw/aw_info.json ] && cp /tmp/gh-aw/aw_info.json /tmp/gh-aw/usage/aw_info.json || true
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
+ [ -f /tmp/gh-aw/github_rate_limits.jsonl ] && cp /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/usage/github_rate_limits.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
@@ -1073,6 +1125,8 @@ jobs:
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
+ mkdir -p /tmp/gh-aw/usage/activity
+ node ${{ runner.temp }}/gh-aw/actions/generate_usage_activity_summary.cjs
find /tmp/gh-aw/usage -type f -print | sort
- name: Upload usage artifact
if: always()
@@ -1081,12 +1135,54 @@ jobs:
with:
name: usage
path: |
+ /tmp/gh-aw/usage/aw_info.json
/tmp/gh-aw/usage/aw-info.jsonl
/tmp/gh-aw/usage/agent_usage.jsonl
/tmp/gh-aw/usage/detection_usage.jsonl
+ /tmp/gh-aw/usage/github_rate_limits.jsonl
/tmp/gh-aw/usage/agent/token_usage.jsonl
/tmp/gh-aw/usage/detection/token_usage.jsonl
+ /tmp/gh-aw/usage/activity/summary.json
if-no-files-found: ignore
+ - name: Restore daily AIC usage cache
+ id: restore-daily-aic-cache-conclusion
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-rerunreviewscanner-${{ github.run_id }}
+ restore-keys: agentic-workflow-usage-rerunreviewscanner-
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Write daily AIC usage cache entry
+ id: write-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ github-token: ${{ github.token }}
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/write_daily_aic_usage_cache.cjs');
+ await main();
+ - name: Save daily AIC usage cache
+ id: save-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ with:
+ key: agentic-workflow-usage-rerunreviewscanner-${{ github.run_id }}
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ - name: Upload daily AIC usage cache artifact
+ id: upload-daily-aic-cache
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ with:
+ name: aic-usage-cache
+ path: /tmp/gh-aw/agentic-workflow-usage-cache.jsonl
+ if-no-files-found: ignore
+ retention-days: 7
- name: Process no-op messages
id: noop
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -1206,7 +1302,7 @@ jobs:
if: >
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
contents: read
outputs:
@@ -1217,7 +1313,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1226,8 +1322,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1245,7 +1341,7 @@ jobs:
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
- name: Checkout repository for patch context
if: needs.agent.outputs.has_patch == 'true'
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
# --- Threat Detection ---
@@ -1254,7 +1350,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.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6 ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96
- name: Check if detection needed
id: detection_guard
if: always()
@@ -1317,11 +1413,11 @@ jobs:
node-version: '24'
package-manager-cache: false
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
env:
GH_HOST: github.com
- name: Install AWF binary
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.7
- name: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
continue-on-error: true
@@ -1340,37 +1436,56 @@ jobs:
export GH_AW_NODE_BIN
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
- GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
- printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MAX_AI_CREDITS="${GH_AW_MAX_AI_CREDITS:-400}"
+ printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.7/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5},\"container\":{\"imageTag\":\"0.27.7,squid=sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96,agent=sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c,api-proxy=sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6,cli-proxy=sha256:4757f198a3fa20f88bdbe70be7ae1a05f127d9c0a9e96a5d6460ef40c08fc83d\"}}" > "${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=""
+ if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
+ GH_AW_DOCKER_HOST="${DOCKER_HOST}"
+ fi
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
+ _GH_AW_CHROOT_JSON=$(jq -c --arg src /tmp/gh-aw --arg user "$(id -un)" --argjson uid "$(id -u)" --argjson gid "$(id -g)" --arg home /tmp/gh-aw/home '.chroot={"binariesSourcePath":$src,"identity":{"user":$user,"uid":$uid,"gid":$gid,"home":$home}}' "${RUNNER_TEMP}/gh-aw/awf-config.json") || { echo "chroot config patch failed" >&2; exit 1; }
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ printf '%s\n' "$_GH_AW_CHROOT_JSON" > "/tmp/gh-aw/awf-config.json"
fi
GH_AW_TOOL_CACHE_MOUNT=""
- GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"
if [ -d "$GH_AW_TOOL_CACHE" ]; then
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
fi
- elif [ -d "/home/runner/work/_tool" ]; then
- GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
fi
- # shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
- -- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
+ # shellcheck disable=SC1003,SC2086
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
+ -- /bin/bash -c 'set +o histexpand; : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
- COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_TIMEOUT_MINUTES: 20
- GH_AW_VERSION: v0.79.8
+ GH_AW_VERSION: v0.80.9
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -1384,6 +1499,7 @@ jobs:
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
RUNNER_TEMP: ${{ runner.temp }}
+ TRACEPARENT: ${{ env.GITHUB_AW_OTEL_TRACE_ID != '' && env.GITHUB_AW_OTEL_PARENT_SPAN_ID != '' && format('00-{0}-{1}-01', env.GITHUB_AW_OTEL_TRACE_ID, env.GITHUB_AW_OTEL_PARENT_SPAN_ID) || '' }}
- name: Parse threat detection token usage for step summary
id: parse_detection_token_usage
if: always()
@@ -1437,9 +1553,82 @@ jobs:
}
}
+ pat_pool:
+ needs: pre_activation
+ runs-on: ubuntu-slim
+ environment: copilot-pat-pool
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - name: Configure GH_HOST for enterprise compatibility
+ id: ghes-host-config
+ shell: bash
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
+ GH_HOST="${GH_HOST#http://}"
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
+ - name: Select Copilot token from pool
+ id: select-pat-number
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+ env:
+ COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+
pre_activation:
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
outputs:
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
matched_command: ''
@@ -1451,15 +1640,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Check team membership for workflow
id: check_membership
@@ -1516,7 +1705,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
runs-on: ubuntu-slim
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions: {}
timeout-minutes: 45
env:
@@ -1529,7 +1718,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_ENGINE_VERSION: "1.0.60"
+ GH_AW_ENGINE_VERSION: "1.0.63"
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
GH_AW_WORKFLOW_ID: "rerun-review-scanner"
GH_AW_WORKFLOW_NAME: "Rerun Review Scanner"
@@ -1544,7 +1733,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1553,8 +1742,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Rerun Review Scanner"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/rerun-review-scanner.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.60"
- GH_AW_INFO_AWF_VERSION: "v0.27.2"
+ GH_AW_INFO_VERSION: "1.0.63"
+ GH_AW_INFO_AWF_VERSION: "v0.27.7"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1573,8 +1762,7 @@ jobs:
- name: Configure GH_HOST for enterprise compatibility
id: ghes-host-config
shell: bash
- # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
- run: |
+ run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
# Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
# GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
GH_HOST="${GITHUB_SERVER_URL#https://}"
@@ -1614,7 +1802,7 @@ jobs:
- detection
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'trigger_rerun_review')
runs-on: ubuntu-latest
- environment: gh-aw-agents
+ environment: copilot-pat-pool
permissions:
actions: write
contents: read
diff --git a/.github/workflows/rerun-review-scanner.md b/.github/workflows/rerun-review-scanner.md
index 6f8ca3bb2067..2c9b4231082a 100644
--- a/.github/workflows/rerun-review-scanner.md
+++ b/.github/workflows/rerun-review-scanner.md
@@ -1,5 +1,17 @@
---
-environment: gh-aw-agents
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
on:
schedule:
@@ -69,7 +81,23 @@ concurrency:
group: "gh-aw-${{ github.workflow }}"
cancel-in-progress: false
-engine: "copilot"
+engine:
+ id: copilot
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
safe-outputs:
# gh-aw compiles this safe-output job into the `trigger_rerun_review` tool
# called by the agent below. The hyphenated job key is converted to the
diff --git a/.github/workflows/shared/pat_pool.README.md b/.github/workflows/shared/pat_pool.README.md
new file mode 100644
index 000000000000..6d691fbde995
--- /dev/null
+++ b/.github/workflows/shared/pat_pool.README.md
@@ -0,0 +1,225 @@
+# PAT Pool
+
+Selects a random Copilot PAT from a numbered pool of secrets. This addresses limitations that arise from having a single PAT shared across all agentic workflows, such as rate-limiting.
+
+**This is a stop-gap workaround.** As soon as organization/enterprise billing is available to the dotnet org, this approach will be removed from our workflows.
+
+## Repository Onboarding
+
+To use Agentic Workflows in a dotnet org repository:
+
+1. Follow the instructions for [Configuring Your Repository | Agentic Authoring | GitHub Agentic Workflows][configure-repo]. Use `gh aw` **v0.80.9 or newer**, which supports the agent job dependencies required for this implementation.
+2. Copy the `pat_pool.md` and `pat_pool.README.md` files into the repository under `.github/workflows/shared`.
+3. Merge those additions into the repository and then follow the instructions for the PAT Creation and Usage below.
+
+**Install or upgrade the `gh aw` CLI and check the version**
+
+```sh
+gh extension install github/gh-aw --force
+gh aw --version
+```
+
+### Environment
+
+Create an environment for the agentic workflows:
+ - _Configuring these settings requires repo admin permission_
+ - https://github.com/dotnet/{repo}/settings/environments
+ - Recommended Name: **copilot-pat-pool**
+ - Recommended Deployment branches and tags: **Protected branches only**
+
+This environment is used for all agentic workflows, restricting agentic workflows to the repo's protected branches and preventing the workflows from accessing secrets defined for other environments.
+
+## PAT Management
+
+Team members provide PATs into the pool with secret names matching the pattern of `_<0-9>`, such as `COPILOT_PAT_0`.
+
+[Use this link to prefill the PAT creation form with the required settings][create-pat]:
+
+1. **Resource owner** is your **user account**, not an organization.
+2. **Copilot Requests (Read)** must be the only permission granted.
+3. **8-day expiration** must be used, which enforces a weekly renewal.
+4. **Repository access** set to **Public repositories** only.
+
+The **Token Name** _does not_ need to match the secret name and is only visible to the owner of the PAT. It's recommended to use a token name indicating the PAT is used for dotnet org agentic workflows. The **Description** is also only used for your own reference.
+
+Team members providing PATs for workflows should set weekly recurring reminders to regenerate and update their PATs in the PAT pool. With an 8-day expiration, renewal can be done on the same day each week.
+
+## PAT Pool Secrets
+
+For a PAT pool that is specific to an environment, PATs can be added to repositories as **Environment Secrets** for the environment created above. _This requires repo admin permission_.
+
+* **Settings** >
+ * **Environments** >
+ * **copilot-pat-pool** (or other environment name) >
+ * **Add environment secret** (or edit your existing secret)
+ * Enter your secret name of `COPILOT_PAT_{0-9}` and paste in your PAT
+
+This can also be accomplished using the `gh` CLI, specifying the repo and environment arguments.
+
+```sh
+# Register the PAT secret. This will prompt for you to paste the PAT.
+gh secret set "_<0-9>" --repo / --env "copilot-pat-pool"
+```
+
+It's also helpful to record who owns each PAT within the pool. To capture which team member is associated with each PAT, a `_<0-9>_` "sidecar secret" can be added alongside the PAT secret to make the username for the PAT pool entry visible. This sidecar secret must have a non-empty value, but it's never consumed, so any value is sufficient.
+
+```sh
+# Record a sidecar secret that presents who owns this PAT.
+gh secret set "_<0-9>_" --body "" --repo / --env "copilot-pat-pool"
+```
+
+## Workflow Output Attribution
+
+Team members' PATs are _only_ used for the Copilot requests from within the agentic portion of the workflow. All outputs from the workflow use the `github-actions[bot]` account token. Issues, PRs, comments, and all other content generated by the workflow will be attributed to `github-actions[bot]`--not the team member's account or token.
+
+## Usage
+
+The [`pat_pool.md`](./pat_pool.md) workflow import defines a custom job with a `pat_number` output. Consuming workflows need two additions to their frontmatter to import this job and use the PAT number to override the `COPILOT_GITHUB_TOKEN` passed to the workflow's agent job.
+
+```yml
+# ###############################################################
+# Select a PAT from the pool and override COPILOT_GITHUB_TOKEN.
+# Run agentic jobs in an isolated `copilot-pat-pool` environment.
+#
+# When org-level billing is available, this will be removed.
+# See `shared/pat_pool.README.md` for more information.
+# ###############################################################
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ environment: copilot-pat-pool
+
+environment: copilot-pat-pool
+
+engine:
+ id: copilot
+ env:
+ COPILOT_GITHUB_TOKEN: |
+ ${{ case(
+ needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
+ needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
+ needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
+ needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
+ needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
+ needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
+ needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
+ needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
+ needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
+ needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
+ 'NO COPILOT PAT AVAILABLE')
+ }}
+```
+
+The `COPILOT_GITHUB_TOKEN` expression can be collapsed onto a single line if desired. `gh-aw compile` automatically wires `pat_pool` into the activation and agent jobs' `needs:` graph because of the `needs.pat_pool.` references within the `engine.env` property.
+
+```sh
+gh aw compile --schedule-seed /
+```
+
+### Specifying the environment
+
+The `environment` must be specified both to the `pat_pool.md` import and to the containing workflow to ensure both jobs access the PAT pool from the same environment. The `copilot-pat-pool` environment name is recommended as the isolated environment for agentic workflows that use the PAT pool.
+
+### Customizing the pool
+
+The import declares 10 optional inputs (`COPILOT_PAT_0` through `COPILOT_PAT_9`), each defaulting to `secrets.COPILOT_PAT_#` of the matching number. To point a workflow at a different pool of repository secrets, use the parameterized `uses`/`with` form when importing and pass the substitute secrets as the `COPILOT_PAT_#` inputs:
+
+```yml
+imports:
+ - uses: shared/pat_pool.md
+ with:
+ COPILOT_PAT_0: ${{ secrets.MY_TEAM_PAT_0 }}
+ COPILOT_PAT_1: ${{ secrets.MY_TEAM_PAT_1 }}
+ # Unspecified inputs default to `secrets.COPILOT_PAT_#` lookups
+```
+
+The secrets passed via `with:` must match the secrets referenced in the consuming workflow's `case` expression that overrides `COPILOT_GITHUB_TOKEN`--both sides need to agree on which secret backs each `COPILOT_PAT_#` slot. Update the `case` expression accordingly:
+
+```yml
+engine:
+ id: copilot
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ case(needs.pat_pool.outputs.pat_number == '0', secrets.MY_TEAM_PAT_0, needs.pat_pool.outputs.pat_number == '1', secrets.MY_TEAM_PAT_1, ..., 'NO COPILOT PAT AVAILABLE') }}
+```
+
+This approach aligns with GitHub's documented guidance for [passing secrets][passing-secrets] between workflows, where the `pat_pool` job returns a PAT number and the `case` statement acts as a secret store to look the PAT secret up based on the selected number.
+
+## Design / Security
+
+There are several details of this implementation that keep our workflows and repositories safe.
+
+1. **Secrets adhere to existing trust boundaries.** The pool of PAT secrets is
+ provided to a dedicated step within the `pat_pool` job. That job runs
+ after `pre_activation` and contains only the trusted checkout and action
+ steps--no untrusted context or input is within scope. The
+ `select-pat-number` action only references the secret values to determine
+ which are non-empty, filtering the secret numbers to those with values.
+1. **The `pat_pool` job emits only a number, never a secret.** Its sole output,
+ `pat_number`, is the 0-9 index of the selected PAT (or empty when the pool
+ is empty). The actual secret materializes only later, in the activation
+ job's `engine.env` mapping, where the `case()` expression resolves the
+ number to the matching secret. This follows GitHub's guidance for
+ [passing secrets][passing-secrets] between jobs or workflows, with the
+ `case` statement acting as a very simple secret store.
+1. **The `select-pat-number` action does not require any permissions.** It
+ reads only the `COPILOT_PAT_#` environment variables passed to it and writes
+ only to `GITHUB_OUTPUT`. The job that hosts it sets `permissions:` to the
+ workflow defaults (no elevated scopes).
+1. **The implementation uses supported Agentic Workflow extensibility hooks.**
+ Defining a custom job inside an [imported workflow file][imports] is
+ supported by `gh aw compile`. gh-aw automatically wires `pat_pool` into the
+ activation job's `needs:` graph based on the `needs.pat_pool.outputs.pat_number`
+ references in `engine.env`. The [secret override][secret-override]
+ capability supplies the `COPILOT_GITHUB_TOKEN` value via `engine.env`
+ rather than the default secret of the same name.
+
+Each of the references below contributed to the design and implementation to ensure a secure and reliable design.
+
+## Known Issues
+
+The `pat_pool` import integration requires that the workflow's compilation results in a `pre_activation` job. If nothing in your workflow definition produces a `pre_activation` job, a compilation error will be received.
+
+```text
+✗ Failed workflows:
+ ✗ .md
+
+.github\workflows\.md:1:1: error: failed to generate YAML: failed to build and validate jobs: job dependency validation failed: job 'pat_pool' depends on non-existent job 'pre_activation'
+```
+
+To work around this, add `on.permissions: {}` to your workflow, which forces a no-op `pre_activation` job to be generated.
+
+```yml
+on:
+ permissions: {}
+```
+
+See: [Activation 'needs' does not incorporate jobs in engine.env expressions (github/gh-aw#30790)](https://github.com/github/gh-aw/issues/30790)
+
+## References
+
+- [Agentic Workflows CLI Extension][cli-setup]
+- [Agentic Authoring][configure-repo]
+- [Authentication][authentication]
+- [Agentic Workflow Imports][imports]
+- [Custom Steps][steps]
+- [Custom Jobs][jobs]
+- [Job Outputs][job-outputs]
+- [Engine Configuration][engine]
+- [Engine Environment Variables][engine-vars]
+- [Update agentic engine token handling to use user-provided secrets (github/gh-aw#18017)][secret-override]
+- [Case Function in Workflow Expressions][case-expression]
+- [Passing a secret between jobs or workflows][passing-secrets]
+
+[cli-setup]: https://github.github.com/gh-aw/setup/cli/
+[configure-repo]: https://github.github.com/gh-aw/guides/agentic-authoring/#configuring-your-repository
+[authentication]: https://github.github.com/gh-aw/reference/auth/
+[create-pat]: https://github.com/settings/personal-access-tokens/new?name=dotnet%20org%20agentic%20workflows&description=GitHub+Agentic+Workflows+-+Copilot+engine+authentication.++Used+for+dotnet+org+workflows.+MUST+be+configured+with+only+Copilot+Requests+permissions+and+user+account+as+resource+owner.+Weekly+expiration+and+required+renewal.&user_copilot_requests=read&expires_in=8
+[imports]: https://github.github.com/gh-aw/reference/imports/
+[steps]: https://github.github.com/gh-aw/reference/frontmatter/#custom-steps-steps
+[jobs]: https://github.github.com/gh-aw/reference/frontmatter/#custom-jobs-jobs
+[job-outputs]: https://github.github.com/gh-aw/reference/frontmatter/#job-outputs
+[engine]: https://github.github.com/gh-aw/reference/frontmatter/#ai-engine-engine
+[engine-vars]: https://github.github.com/gh-aw/reference/engines/#engine-environment-variables
+[secret-override]: https://github.com/github/gh-aw/pull/18017
+[case-expression]: https://docs.github.com/actions/reference/workflows-and-actions/expressions#case
+[passing-secrets]: https://docs.github.com/actions/reference/workflows-and-actions/workflow-commands#example-masking-and-passing-a-secret-between-jobs-or-workflows
diff --git a/.github/workflows/shared/pat_pool.md b/.github/workflows/shared/pat_pool.md
new file mode 100644
index 000000000000..7d9b3b974e65
--- /dev/null
+++ b/.github/workflows/shared/pat_pool.md
@@ -0,0 +1,119 @@
+---
+description: Agentic workflow import to integrate the Copilot PAT Pool
+
+jobs:
+ pat_pool:
+ environment: ${{ github.aw.import-inputs.environment }}
+ needs: [pre_activation]
+ runs-on: ubuntu-slim
+ outputs:
+ pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
+ steps:
+ - id: select-pat-number
+ name: Select Copilot token from pool
+ env:
+ COPILOT_PAT_0: ${{ github.aw.import-inputs.COPILOT_PAT_0 }}
+ COPILOT_PAT_1: ${{ github.aw.import-inputs.COPILOT_PAT_1 }}
+ COPILOT_PAT_2: ${{ github.aw.import-inputs.COPILOT_PAT_2 }}
+ COPILOT_PAT_3: ${{ github.aw.import-inputs.COPILOT_PAT_3 }}
+ COPILOT_PAT_4: ${{ github.aw.import-inputs.COPILOT_PAT_4 }}
+ COPILOT_PAT_5: ${{ github.aw.import-inputs.COPILOT_PAT_5 }}
+ COPILOT_PAT_6: ${{ github.aw.import-inputs.COPILOT_PAT_6 }}
+ COPILOT_PAT_7: ${{ github.aw.import-inputs.COPILOT_PAT_7 }}
+ COPILOT_PAT_8: ${{ github.aw.import-inputs.COPILOT_PAT_8 }}
+ COPILOT_PAT_9: ${{ github.aw.import-inputs.COPILOT_PAT_9 }}
+ RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
+ shell: bash
+ run: |
+ # Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
+ PAT_NUMBERS=()
+ POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
+
+ for i in $(seq 0 9); do
+ var="COPILOT_PAT_${i}"
+ val="${!var}"
+ if [ -n "$val" ]; then
+ PAT_NUMBERS+=(${i})
+ POOL_INDICATORS[${i}]="🟪"
+ fi
+ done
+
+ # If none of the entries in the pool have values, emit a warning
+ # and do not set an output value. The consumer can fall back to
+ # using COPILOT_GITHUB_TOKEN.
+ if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
+ warning_message="::warning::None of the PAT pool entries had values "
+ warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
+ echo "$warning_message"
+ exit 0
+ fi
+
+ # Select a random index using the seed if specified.
+ if [ -n "$RANDOM_SEED" ]; then
+ RANDOM=$RANDOM_SEED
+ fi
+
+ PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
+ PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
+ POOL_INDICATORS[${PAT_NUMBER}]="✅"
+
+ echo "Pool size: ${#PAT_NUMBERS[@]}"
+ echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
+
+ echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
+ echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
+ (IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
+
+ echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
+
+import-schema:
+ environment:
+ type: string
+ required: true
+ COPILOT_PAT_0:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_0 }}
+ COPILOT_PAT_1:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_1 }}
+ COPILOT_PAT_2:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_2 }}
+ COPILOT_PAT_3:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_3 }}
+ COPILOT_PAT_4:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_4 }}
+ COPILOT_PAT_5:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_5 }}
+ COPILOT_PAT_6:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_6 }}
+ COPILOT_PAT_7:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_7 }}
+ COPILOT_PAT_8:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_8 }}
+ COPILOT_PAT_9:
+ type: string
+ required: false
+ default: ${{ secrets.COPILOT_PAT_9 }}
+ random_seed:
+ type: number
+ required: false
+ description: >-
+ A seed number to use for the random PAT number selection,
+ for deterministic selection if needed.
+---
diff --git a/.github/workflows/validate-pat-pool.yml b/.github/workflows/validate-pat-pool.yml
new file mode 100644
index 000000000000..67092d1ec3de
--- /dev/null
+++ b/.github/workflows/validate-pat-pool.yml
@@ -0,0 +1,206 @@
+name: Validate PAT Pool
+
+on:
+ schedule:
+ - cron: '17 2 * * *' # Daily at ~2:17 AM UTC (off-round to reduce contention)
+ workflow_dispatch:
+
+permissions: {}
+
+jobs:
+ validate:
+ environment: copilot-pat-pool
+ name: Validate Copilot PAT Pool
+ if: ${{ github.event_name == 'workflow_dispatch' || !github.event.repository.fork }}
+ runs-on: ubuntu-latest
+ env:
+ VALIDATE_PAT: |
+ if [ -z "$COPILOT_GITHUB_TOKEN" ]; then echo "status=empty" >> "$GITHUB_OUTPUT"; exit 0; fi
+ set +e; timeout 30 copilot --prompt "Say OK" --available-tools="" --silent --effort=low; rc=$?; set -e
+ if [ $rc -eq 0 ]; then echo "status=valid" >> "$GITHUB_OUTPUT"
+ elif [ $rc -eq 124 ]; then echo "status=unknown" >> "$GITHUB_OUTPUT"
+ else echo "status=invalid" >> "$GITHUB_OUTPUT"; fi
+ steps:
+ - name: Setup gh-aw scripts
+ uses: github/gh-aw-actions/setup@8c7d04ebf1ece56cd381446125da3e0f6896294a # v0.80.9
+ with:
+ destination: ${{ runner.temp }}/gh-aw/actions
+
+ - name: Install Copilot CLI
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.63
+
+ - name: Validate COPILOT_PAT_0
+ id: pat0
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_0 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_1
+ id: pat1
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_1 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_2
+ id: pat2
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_2 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_3
+ id: pat3
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_3 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_4
+ id: pat4
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_4 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_5
+ id: pat5
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_5 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_6
+ id: pat6
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_6 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_7
+ id: pat7
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_7 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_8
+ id: pat8
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_8 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Validate COPILOT_PAT_9
+ id: pat9
+ continue-on-error: true
+ env:
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_PAT_9 }}
+ shell: bash
+ run: |
+ eval "$VALIDATE_PAT"
+
+ - name: Build summary
+ if: always()
+ env:
+ S0: ${{ steps.pat0.outputs.status }}
+ S1: ${{ steps.pat1.outputs.status }}
+ S2: ${{ steps.pat2.outputs.status }}
+ S3: ${{ steps.pat3.outputs.status }}
+ S4: ${{ steps.pat4.outputs.status }}
+ S5: ${{ steps.pat5.outputs.status }}
+ S6: ${{ steps.pat6.outputs.status }}
+ S7: ${{ steps.pat7.outputs.status }}
+ S8: ${{ steps.pat8.outputs.status }}
+ S9: ${{ steps.pat9.outputs.status }}
+ shell: bash
+ run: |
+ statuses=("$S0" "$S1" "$S2" "$S3" "$S4" "$S5" "$S6" "$S7" "$S8" "$S9")
+
+ valid=0; empty=0; invalid=0; unknown=0
+ for s in "${statuses[@]}"; do
+ case "$s" in
+ valid) valid=$((valid + 1)) ;;
+ empty) empty=$((empty + 1)) ;;
+ invalid) invalid=$((invalid + 1)) ;;
+ *) unknown=$((unknown + 1)) ;;
+ esac
+ done
+
+ {
+ if [ $invalid -eq 0 ] && [ $unknown -eq 0 ] && [ $valid -gt 0 ]; then
+ echo "> [!NOTE]"
+ echo "> **PAT pool is valid** -- no action needed"
+ echo ""
+ fi
+
+ if [ $invalid -eq 0 ] && [ $unknown -eq 0 ] && [ $valid -eq 0 ]; then
+ echo "> [!WARNING]"
+ echo "> **Empty PAT pool** -- no PATs are configured, so this check fails (exit 1) to surface the gap. Agentic workflows themselves fall back to the shared default \`COPILOT_GITHUB_TOKEN\` (more throttling-prone), but the pool should be populated."
+ echo ""
+ fi
+
+ if [ $invalid -gt 0 ]; then
+ echo "> [!CAUTION]"
+ echo "> **Invalid PAT pool** -- agentic workflows selecting an invalid PAT will fail."
+ echo ""
+ fi
+
+ if [ $unknown -gt 0 ]; then
+ echo "> [!WARNING]"
+ echo "> **PAT pool not verified** due to transient errors -- re-run the workflow to retry."
+ echo ""
+ fi
+
+ echo "☑️ Valid: ${valid} • ⏹️ Empty: ${empty} • ❌ Invalid: ${invalid} • ❓ Unknown: ${unknown}"
+ echo ""
+
+ echo "| PAT Secret | Status |"
+ echo "|:-----------|:-------|"
+
+ for i in $(seq 0 9); do
+ case "${statuses[$i]}" in
+ valid) symbol="☑️ Valid" ;;
+ empty) symbol="⏹️ Empty" ;;
+ invalid) symbol="❌ Invalid" ;;
+ *) symbol="❓ Unknown" ;;
+ esac
+ echo "| \`COPILOT_PAT_${i}\` | ${symbol} |"
+ done
+ } >> "$GITHUB_STEP_SUMMARY"
+
+ if [ $invalid -gt 0 ]; then
+ echo "::error::${invalid} PAT(s) in the pool are invalid and need to be removed or replaced"
+ exit 1
+ fi
+
+ if [ $unknown -gt 0 ]; then
+ echo "::error::${unknown} PAT(s) could not be verified due to transient errors -- re-run to retry"
+ exit 1
+ fi
+
+ if [ $valid -eq 0 ]; then
+ echo "::error::The PAT pool is empty -- no PATs are available"
+ exit 1
+ fi
+
+ echo "PAT pool validation passed: ${valid} valid PAT(s)"