diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index ac0f8fed5..b2f72f857 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -130,16 +130,21 @@ "version": "v4.36.0", "sha": "7211b7c8077ea37d8641b6271f6a365a22a5fbfa" }, - "github/gh-aw-actions/setup@v0.75.4": { + "github/gh-aw-actions/setup@v0.76.1": { "repo": "github/gh-aw-actions/setup", - "version": "v0.75.4", - "sha": "9f050961da586148d135e113d8bb025185cdf2b8" + "version": "v0.76.1", + "sha": "46d564922b082d0db93244972e8005ea6904ee5f" }, "github/gh-aw/actions/setup-cli@v0.75.4": { "repo": "github/gh-aw/actions/setup-cli", "version": "v0.75.4", "sha": "1a7f4119f6c4398ed2fc824f99276a55fb382e3f" }, + "github/gh-aw/actions/setup-cli@v0.76.1": { + "repo": "github/gh-aw/actions/setup-cli", + "version": "v0.76.1", + "sha": "58d1bedbb7200f59c2d224151339e38fd8687d05" + }, "github/gh-aw/actions/setup@v0.75.4": { "repo": "github/gh-aw/actions/setup", "version": "v0.75.4", diff --git a/.github/workflows/smoke-allowonly.lock.yml b/.github/workflows/smoke-allowonly.lock.yml index 455eaa04d..b1ba75623 100644 --- a/.github/workflows/smoke-allowonly.lock.yml +++ b/.github/workflows/smoke-allowonly.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"3e7bcabac41c719666005736dab6fdfa81488db08c0aed000ba2367a7c4b8253","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"},{"repo":"github/gh-aw/actions/setup-cli","sha":"1a7f4119f6c4398ed2fc824f99276a55fb382e3f","version":"v0.75.4"}],"containers":[{"image":"alpine:latest","digest":"sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659","pinned_image":"alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"7a509d1a524aea1b70b47ed20f821004514cb50a192823002c07d1b462d2452f","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"},{"repo":"github/gh-aw/actions/setup-cli","sha":"58d1bedbb7200f59c2d224151339e38fd8687d05","version":"v0.76.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659","pinned_image":"alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -42,15 +42,15 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 -# - github/gh-aw/actions/setup-cli@1a7f4119f6c4398ed2fc824f99276a55fb382e3f # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 +# - github/gh-aw/actions/setup-cli@58d1bedbb7200f59c2d224151339e38fd8687d05 # v0.76.1 # # Container images used: # - alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -108,7 +108,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -118,7 +118,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-allowonly.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -128,15 +128,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -171,6 +171,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -181,8 +182,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -200,7 +201,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -235,22 +236,22 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_9d95777041d7e9a1_EOF' + cat << 'GH_AW_PROMPT_0226acf36bc23906_EOF' - GH_AW_PROMPT_9d95777041d7e9a1_EOF + GH_AW_PROMPT_0226acf36bc23906_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/agentic_workflows_guide.md" cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_9d95777041d7e9a1_EOF' + cat << 'GH_AW_PROMPT_0226acf36bc23906_EOF' Tools: add_comment(max:2), create_issue, add_labels, missing_tool, missing_data, noop - GH_AW_PROMPT_9d95777041d7e9a1_EOF + GH_AW_PROMPT_0226acf36bc23906_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_9d95777041d7e9a1_EOF' + cat << 'GH_AW_PROMPT_0226acf36bc23906_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -279,15 +280,15 @@ jobs: {{/if}} - GH_AW_PROMPT_9d95777041d7e9a1_EOF + GH_AW_PROMPT_0226acf36bc23906_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_9d95777041d7e9a1_EOF' + cat << 'GH_AW_PROMPT_0226acf36bc23906_EOF' {{#runtime-import .github/workflows/shared/mcp-pagination.md}} {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-allowonly.md}} - GH_AW_PROMPT_9d95777041d7e9a1_EOF + GH_AW_PROMPT_0226acf36bc23906_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -372,6 +373,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -408,7 +410,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -418,7 +420,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-allowonly.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -485,7 +487,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -501,20 +503,37 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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" alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 ghcr.io/github/gh-aw-firewall/agent:0.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - name: Install gh-aw extension - uses: github/gh-aw/actions/setup-cli@1a7f4119f6c4398ed2fc824f99276a55fb382e3f # v0.75.4 + uses: github/gh-aw/actions/setup-cli@58d1bedbb7200f59c2d224151339e38fd8687d05 # v0.76.1 with: - version: 'v0.75.4' + version: 'v0.76.1' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - name: Copy gh-aw binary for MCP server run: | @@ -545,9 +564,9 @@ jobs: 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_761550b0ab2b2ffe_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_2d9089b903d83d81_EOF' {"add_comment":{"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-allowonly"]},"create_issue":{"close_older_issues":true,"expires":2,"group":true,"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_761550b0ab2b2ffe_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_2d9089b903d83d81_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -793,11 +812,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_a2635eb03a220e36_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_30bc2c10746d8c36_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -864,7 +883,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_a2635eb03a220e36_EOF + GH_AW_MCP_CONFIG_30bc2c10746d8c36_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -916,7 +935,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -935,7 +954,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1140,7 +1159,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1150,7 +1169,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-allowonly.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1268,7 +1287,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1276,7 +1295,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-allowonly.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1327,7 +1346,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1337,7 +1356,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke AllowOnly" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-allowonly.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-allowonly.md b/.github/workflows/smoke-allowonly.md index e4574393d..85e529c7e 100644 --- a/.github/workflows/smoke-allowonly.md +++ b/.github/workflows/smoke-allowonly.md @@ -42,6 +42,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 0597bc29d..44982e986 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5e970668eb9e5169710ef6515af6cea2805b1b7343aa983fc9249782a346df61","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"mcr.microsoft.com/playwright/mcp","digest":"sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2","pinned_image":"mcr.microsoft.com/playwright/mcp@sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5e970668eb9e5169710ef6515af6cea2805b1b7343aa983fc9249782a346df61","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"mcr.microsoft.com/playwright/mcp","digest":"sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2","pinned_image":"mcr.microsoft.com/playwright/mcp@sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -44,13 +44,13 @@ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 # - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - mcr.microsoft.com/playwright/mcp@sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2 @@ -110,7 +110,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -120,7 +120,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Copilot" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-copilot.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -130,14 +130,14 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Copilot" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","playwright","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" @@ -173,6 +173,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -183,8 +184,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -202,7 +203,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -375,6 +376,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -411,7 +413,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -421,7 +423,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Copilot" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-copilot.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -496,7 +498,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -512,16 +514,33 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 mcr.microsoft.com/playwright/mcp@sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 mcr.microsoft.com/playwright/mcp@sha256:7b82f29c6ef83480a97f612d53ac3fd5f30a32df3fea1e06923d4204d3532bb2 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - name: Generate Safe Outputs Config run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" @@ -860,7 +879,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","cdn.playwright.dev","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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","go.dev","golang.org","goproxy.io","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","pkg.go.dev","playwright.download.prss.microsoft.com","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","cdn.playwright.dev","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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","go.dev","golang.org","goproxy.io","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","pkg.go.dev","playwright.download.prss.microsoft.com","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -879,7 +898,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || github.token }} GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true @@ -1089,7 +1108,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1099,7 +1118,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Copilot" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-copilot.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1217,7 +1236,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1225,7 +1244,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Copilot" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-copilot.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1276,7 +1295,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1286,7 +1305,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Copilot" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-copilot.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-long-session.lock.yml b/.github/workflows/smoke-long-session.lock.yml index 96fc85484..467b062d8 100644 --- a/.github/workflows/smoke-long-session.lock.yml +++ b/.github/workflows/smoke-long-session.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"82deafacd985a06cac32617a62f953a1a9c3495acb8f4f65571176bfd062d342","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"82deafacd985a06cac32617a62f953a1a9c3495acb8f4f65571176bfd062d342","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.19"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -42,13 +42,13 @@ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:v0.3.19 # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -92,7 +92,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -100,7 +100,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Long Session" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-long-session.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -110,14 +110,14 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Long Session" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","go"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_AWMG_VERSION: "" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" @@ -140,6 +140,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -150,8 +151,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -169,7 +170,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -329,6 +330,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -365,7 +367,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -375,7 +377,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Long Session" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-long-session.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -450,7 +452,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -469,16 +471,33 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:v0.3.19 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - name: Generate Safe Outputs Config run: | mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" @@ -690,7 +709,7 @@ 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.18' + 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.19' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) @@ -769,7 +788,7 @@ 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.25.53/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","go.dev","golang.org","goproxy.io","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","pkg.go.dev","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/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","go.dev","golang.org","goproxy.io","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","pkg.go.dev","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -788,7 +807,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -989,7 +1008,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -999,7 +1018,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Long Session" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-long-session.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1135,7 +1154,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1145,7 +1164,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Long Session" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-long-session.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-otel-tracing.lock.yml b/.github/workflows/smoke-otel-tracing.lock.yml index 758e0cd32..7c8dff529 100644 --- a/.github/workflows/smoke-otel-tracing.lock.yml +++ b/.github/workflows/smoke-otel-tracing.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c281d28bb2a4ac983be268d584b1d0d912e9a7ff4a4271e36cbbac61d43f09ec","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.15"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9232ae1f82e60111b301b31f36d828fb5fa81ad26eefd7f77ad929e5f792b6cd","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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-go","sha":"4a3601121dd01d1626a1e23e37211e3254c1c06c","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -44,13 +44,13 @@ # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) # - actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.15 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -101,7 +101,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -109,7 +109,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke OTel Tracing" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-otel-tracing.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" @@ -121,15 +121,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke OTel Tracing" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","go","*.ingest.us.sentry.io"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "v0.3.15" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -151,6 +151,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -161,8 +162,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -180,7 +181,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -203,21 +204,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_c8c96f08c90c38b8_EOF' + cat << 'GH_AW_PROMPT_a019c3d5254e0cb8_EOF' - GH_AW_PROMPT_c8c96f08c90c38b8_EOF + GH_AW_PROMPT_a019c3d5254e0cb8_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_c8c96f08c90c38b8_EOF' + cat << 'GH_AW_PROMPT_a019c3d5254e0cb8_EOF' Tools: create_issue, missing_tool, missing_data, noop - GH_AW_PROMPT_c8c96f08c90c38b8_EOF + GH_AW_PROMPT_a019c3d5254e0cb8_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_c8c96f08c90c38b8_EOF' + cat << 'GH_AW_PROMPT_a019c3d5254e0cb8_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -246,13 +247,13 @@ jobs: {{/if}} - GH_AW_PROMPT_c8c96f08c90c38b8_EOF + GH_AW_PROMPT_a019c3d5254e0cb8_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_c8c96f08c90c38b8_EOF' + cat << 'GH_AW_PROMPT_a019c3d5254e0cb8_EOF' {{#runtime-import .github/workflows/shared/go-make.md}} {{#runtime-import .github/workflows/smoke-otel-tracing.md}} - GH_AW_PROMPT_c8c96f08c90c38b8_EOF + GH_AW_PROMPT_a019c3d5254e0cb8_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -330,6 +331,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -367,7 +369,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -377,7 +379,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke OTel Tracing" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-otel-tracing.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -454,7 +456,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Determine automatic lockdown mode for GitHub MCP Server id: determine-automatic-lockdown uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9) @@ -473,24 +475,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.15 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_4bc97967ffbc2200_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_e8f6f45c0b5593a1_EOF' {"create_issue":{"close_older_issues":true,"expires":168,"group":true,"labels":["smoke-test","otel","tracing","automation"],"max":1,"title_prefix":"[smoke-otel-tracing] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_4bc97967ffbc2200_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_e8f6f45c0b5593a1_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -694,11 +713,11 @@ 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 -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -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.15' + 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 -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -e OTEL_EXPORTER_OTLP_HEADERS -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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_0c088eb3a3a1127b_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_123050faabf4d9ef_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -744,7 +763,7 @@ jobs: } } } - GH_AW_MCP_CONFIG_0c088eb3a3a1127b_EOF + GH_AW_MCP_CONFIG_123050faabf4d9ef_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -778,7 +797,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.ingest.us.sentry.io","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","go.dev","golang.org","goproxy.io","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","pkg.go.dev","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.ingest.us.sentry.io","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","go.dev","golang.org","goproxy.io","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","pkg.go.dev","ppa.launchpad.net","proxy.golang.org","raw.githubusercontent.com","registry.npmjs.org","s.symcb.com","s.symcd.com","security.ubuntu.com","storage.googleapis.com","sum.golang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -797,7 +816,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1009,7 +1028,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1019,7 +1038,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke OTel Tracing" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-otel-tracing.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1155,7 +1174,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1165,7 +1184,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke OTel Tracing" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-otel-tracing.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Mask OTLP telemetry headers run: bash "${RUNNER_TEMP}/gh-aw/actions/mask_otlp_headers.sh" diff --git a/.github/workflows/smoke-otel-tracing.md b/.github/workflows/smoke-otel-tracing.md index b8cb27688..0a10042a7 100644 --- a/.github/workflows/smoke-otel-tracing.md +++ b/.github/workflows/smoke-otel-tracing.md @@ -36,7 +36,7 @@ runtimes: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" - version: "v0.3.15" + version: "latest" steps: - name: Set up Go uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0 diff --git a/.github/workflows/smoke-proxy-github-script.invalid.yml b/.github/workflows/smoke-proxy-github-script.invalid.yml deleted file mode 100644 index 0b7952d7a..000000000 --- a/.github/workflows/smoke-proxy-github-script.invalid.yml +++ /dev/null @@ -1,1299 +0,0 @@ -# ___ _ _ -# / _ \ | | (_) -# | |_| | __ _ ___ _ __ | |_ _ ___ -# | _ |/ _` |/ _ \ '_ \| __| |/ __| -# | | | | (_| | __/ | | | |_| | (__ -# \_| |_/\__, |\___|_| |_|\__|_|\___| -# __/ | -# _ _ |___/ -# | | | | / _| | -# | | | | ___ _ __ _ __| |_| | _____ ____ -# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___| -# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ -# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ -# -# This file was automatically generated by gh-aw (v0.63.0). DO NOT EDIT. -# -# To update this file, edit the corresponding .md file and run: -# gh aw compile -# Not all edits will cause changes to this file. -# -# For more information: https://github.github.com/gh-aw/introduction/overview/ -# -# Smoke test validating that the MCP Gateway proxy applies DIFC integrity filtering to actions/github-script (octokit) API calls -# -# Resolved workflow manifest: -# Imports: -# - shared/reporting.md -# -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"057319c2c1e4b6b398628dcda3b178108681cb7d66dd35a832d2d37fb66250b4","compiler_version":"v0.63.0","agent_id":"copilot"} - -name: "Smoke: Proxy + github-script" -"on": - pull_request: - # names: # Label filtering applied via job conditions - # - smoke # Label filtering applied via job conditions - types: - - labeled - workflow_dispatch: - inputs: - aw_context: - default: "" - description: (Internal) JSON context injected by the calling agentic workflow. Not intended for direct user input. - required: false - type: string - -permissions: {} - -concurrency: - group: "gh-aw-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }}" - cancel-in-progress: true - -run-name: "Smoke: Proxy + github-script" - -jobs: - activation: - needs: pre_activation - if: > - needs.pre_activation.outputs.activated == 'true' && ((github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke')) - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - outputs: - body: ${{ steps.sanitized.outputs.body }} - comment_id: "" - comment_repo: "" - lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }} - model: ${{ steps.generate_aw_info.outputs.model }} - secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} - text: ${{ steps.sanitized.outputs.text }} - title: ${{ steps.sanitized.outputs.title }} - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Generate agentic run info - id: generate_aw_info - env: - GH_AW_INFO_ENGINE_ID: "copilot" - GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" - GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }} - GH_AW_INFO_VERSION: "latest" - GH_AW_INFO_AGENT_VERSION: "latest" - GH_AW_INFO_CLI_VERSION: "v0.63.0" - GH_AW_INFO_WORKFLOW_NAME: "Smoke: Proxy + github-script" - GH_AW_INFO_EXPERIMENTAL: "false" - GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" - GH_AW_INFO_STAGED: "false" - GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com","rust"]' - GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.0" - GH_AW_INFO_AWMG_VERSION: "" - GH_AW_INFO_FIREWALL_TYPE: "squid" - GH_AW_COMPILED_STRICT: "false" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs'); - await main(core, context); - - name: Add eyes reaction for immediate feedback - id: react - if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_REACTION: "eyes" - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs'); - await main(); - - name: Validate COPILOT_GITHUB_TOKEN secret - id: validate-secret - run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default - env: - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - - name: Checkout .github and .agents folders - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - sparse-checkout: | - .github - .agents - sparse-checkout-cone-mode: true - fetch-depth: 1 - - name: Check workflow file timestamps - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_WORKFLOW_FILE: "smoke-proxy-github-script.lock.yml" - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs'); - await main(); - - name: Compute current body text - id: sanitized - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs'); - await main(); - - name: Create prompt with built-in context - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - run: | - bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh - { - cat << 'GH_AW_PROMPT_EOF' - - GH_AW_PROMPT_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/agentic_workflows_guide.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" - cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_EOF' - - Tools: add_comment, create_issue, missing_tool, missing_data, noop - - - The following GitHub context information is available for this workflow: - {{#if __GH_AW_GITHUB_ACTOR__ }} - - **actor**: __GH_AW_GITHUB_ACTOR__ - {{/if}} - {{#if __GH_AW_GITHUB_REPOSITORY__ }} - - **repository**: __GH_AW_GITHUB_REPOSITORY__ - {{/if}} - {{#if __GH_AW_GITHUB_WORKSPACE__ }} - - **workspace**: __GH_AW_GITHUB_WORKSPACE__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }} - - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }} - - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }} - - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ - {{/if}} - {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }} - - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__ - {{/if}} - {{#if __GH_AW_GITHUB_RUN_ID__ }} - - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__ - {{/if}} - - - GH_AW_PROMPT_EOF - cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_EOF' - - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' - {{#runtime-import .github/workflows/shared/reporting.md}} - GH_AW_PROMPT_EOF - cat << 'GH_AW_PROMPT_EOF' - {{#runtime-import .github/workflows/smoke-proxy-github-script.md}} - GH_AW_PROMPT_EOF - } > "$GH_AW_PROMPT" - - name: Interpolate variables and render templates - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs'); - await main(); - - name: Substitute placeholders - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_ALLOWED_EXTENSIONS: '' - GH_AW_CACHE_DESCRIPTION: '' - GH_AW_CACHE_DIR: '/tmp/gh-aw/cache-memory/' - GH_AW_GITHUB_ACTOR: ${{ github.actor }} - GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} - GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} - GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} - GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} - GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - 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'); - setupGlobals(core, github, context, exec, io); - - const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs'); - - // Call the substitution function - return await substitutePlaceholders({ - file: process.env.GH_AW_PROMPT, - substitutions: { - GH_AW_ALLOWED_EXTENSIONS: process.env.GH_AW_ALLOWED_EXTENSIONS, - GH_AW_CACHE_DESCRIPTION: process.env.GH_AW_CACHE_DESCRIPTION, - GH_AW_CACHE_DIR: process.env.GH_AW_CACHE_DIR, - GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR, - GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID, - GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER, - GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER, - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER, - 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_SERVER_URL: process.env.GH_AW_GITHUB_SERVER_URL, - GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE, - GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED - } - }); - - name: Validate prompt placeholders - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh - - name: Print prompt - env: - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh - - name: Upload activation artifact - if: success() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: activation - path: | - /tmp/gh-aw/aw_info.json - /tmp/gh-aw/aw-prompts/prompt.txt - retention-days: 1 - - agent: - needs: activation - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - issues: read - pull-requests: read - env: - DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} - GH_AW_ASSETS_ALLOWED_EXTS: "" - GH_AW_ASSETS_BRANCH: "" - GH_AW_ASSETS_MAX_SIZE_KB: 0 - GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs - GH_AW_WORKFLOW_ID_SANITIZED: smokeproxygithubscript - outputs: - checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }} - detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }} - detection_success: ${{ steps.detection_conclusion.outputs.success }} - has_patch: ${{ steps.collect_output.outputs.has_patch }} - inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }} - model: ${{ needs.activation.outputs.model }} - output: ${{ steps.collect_output.outputs.output }} - output_types: ${{ steps.collect_output.outputs.output_types }} - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Set runtime paths - id: set-runtime-paths - run: | - echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT" - echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT" - echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT" - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - persist-credentials: false - - name: Create gh-aw temp directory - run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Configure gh CLI for GitHub Enterprise - run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh - env: - GH_TOKEN: ${{ github.token }} - - name: Build MCP Gateway image - run: "# Install Rust and WASM target if not present\nif ! command -v rustup &>/dev/null; then\n curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable\n source \"$HOME/.cargo/env\"\nfi\nrustup target add wasm32-wasip1\n\n# Build the Rust WASM guard (required by Dockerfile)\ncd guards/github-guard/rust-guard\nbash build.sh\ncd ../../..\n\n# Build Docker image\ndocker build -t awmg-local:latest .\n" - - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - name: Start DIFC proxy - run: "PROXY_LOG_DIR=/tmp/gh-aw/proxy-logs\nMCP_LOG_DIR=/tmp/gh-aw/mcp-logs\nRESULTS_DIR=/tmp/gh-aw/github-script-results\nmkdir -p \"$PROXY_LOG_DIR\" \"$MCP_LOG_DIR\" \"$RESULTS_DIR\"\n\nPOLICY='{\"allow-only\":{\"repos\":[\"github/gh-aw-mcpg\"],\"min-integrity\":\"approved\"}}'\n\n# Plain HTTP — avoids TLS cert trust issues with undici/Node.js\ndocker run -d --name awmg-proxy --network host \\\n -e GH_TOKEN \\\n -e DEBUG='*' \\\n -v \"$PROXY_LOG_DIR:$PROXY_LOG_DIR\" \\\n -v \"$MCP_LOG_DIR:$MCP_LOG_DIR\" \\\n awmg-local:latest proxy \\\n --policy \"$POLICY\" \\\n --listen 0.0.0.0:18443 \\\n --log-dir \"$MCP_LOG_DIR\" \\\n --guards-mode filter \\\n --trusted-bots github-actions[bot],dependabot[bot],copilot\n\n# Wait for proxy health check\nPROXY_READY=false\nfor i in $(seq 1 30); do\n if curl -sf \"http://localhost:18443/health\" -o /dev/null 2>/dev/null; then\n echo \"DIFC proxy ready on port 18443\"\n PROXY_READY=true\n break\n fi\n sleep 1\ndone\n\nif [ \"$PROXY_READY\" = \"false\" ]; then\n echo \"::error::DIFC proxy failed to start\"\n docker logs awmg-proxy 2>&1 | tail -30 || true\n exit 1\nfi\n\necho \"RESULTS_DIR=$RESULTS_DIR\" >> \"$GITHUB_ENV\"\n" - - name: "Test 1: In-scope list issues (REST)" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n const result = await github.rest.issues.listForRepo({\n owner: 'github',\n repo: 'gh-aw-mcpg',\n per_page: 5,\n state: 'open'\n });\n const summary = {\n test: 'in-scope-list-issues',\n status_code: result.status,\n item_count: result.data.length,\n items: result.data.map(i => ({\n number: i.number,\n title: i.title.substring(0, 60),\n author: i.user?.login || 'unknown',\n author_association: i.author_association || 'N/A'\n }))\n };\n fs.writeFileSync(`${dir}/test1-in-scope-issues.json`, JSON.stringify(summary, null, 2));\n console.log(`✅ In-scope list_issues: ${result.data.length} items returned`);\n} catch (err) {\n const summary = { test: 'in-scope-list-issues', error: err.message, status: err.status };\n fs.writeFileSync(`${dir}/test1-in-scope-issues.json`, JSON.stringify(summary, null, 2));\n console.log(`❌ In-scope list_issues failed: ${err.message}`);\n}\n" - - name: "Test 2: Out-of-scope list issues (REST)" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n const result = await github.rest.issues.listForRepo({\n owner: 'octocat',\n repo: 'Hello-World',\n per_page: 5\n });\n const summary = {\n test: 'out-of-scope-list-issues',\n status_code: result.status,\n item_count: result.data.length,\n items: result.data.map(i => ({\n number: i.number,\n title: i.title.substring(0, 60),\n author: i.user?.login || 'unknown'\n }))\n };\n fs.writeFileSync(`${dir}/test2-out-of-scope-issues.json`, JSON.stringify(summary, null, 2));\n console.log(`Out-of-scope list_issues: ${result.data.length} items (expected: 0 or blocked)`);\n} catch (err) {\n const summary = { test: 'out-of-scope-list-issues', error: err.message, status: err.status };\n fs.writeFileSync(`${dir}/test2-out-of-scope-issues.json`, JSON.stringify(summary, null, 2));\n console.log(`Out-of-scope list_issues error (may be expected): ${err.message}`);\n}\n" - - name: "Test 3: In-scope GraphQL query" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n const result = await github.graphql(`\n query($owner: String!, $repo: String!, $count: Int!) {\n repository(owner: $owner, name: $repo) {\n issues(first: $count, states: OPEN, orderBy: {field: CREATED_AT, direction: DESC}) {\n totalCount\n nodes {\n number\n title\n author { login }\n authorAssociation\n }\n }\n }\n }\n `, { owner: 'github', repo: 'gh-aw-mcpg', count: 5 });\n const issues = result.repository.issues;\n const summary = {\n test: 'in-scope-graphql-issues',\n total_count: issues.totalCount,\n item_count: issues.nodes.length,\n items: issues.nodes.map(i => ({\n number: i.number,\n title: i.title.substring(0, 60),\n author: i.author?.login || 'unknown',\n author_association: i.authorAssociation || 'N/A'\n }))\n };\n fs.writeFileSync(`${dir}/test3-in-scope-graphql.json`, JSON.stringify(summary, null, 2));\n console.log(`✅ In-scope GraphQL issues: ${issues.nodes.length} items`);\n} catch (err) {\n const summary = { test: 'in-scope-graphql-issues', error: err.message };\n fs.writeFileSync(`${dir}/test3-in-scope-graphql.json`, JSON.stringify(summary, null, 2));\n console.log(`❌ In-scope GraphQL failed: ${err.message}`);\n}\n" - - name: "Test 4: Out-of-scope GraphQL query" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n const result = await github.graphql(`\n query($owner: String!, $repo: String!, $count: Int!) {\n repository(owner: $owner, name: $repo) {\n issues(first: $count, states: OPEN) {\n totalCount\n nodes { number title author { login } }\n }\n }\n }\n `, { owner: 'octocat', repo: 'Hello-World', count: 5 });\n const issues = result.repository.issues;\n const summary = {\n test: 'out-of-scope-graphql-issues',\n total_count: issues.totalCount,\n item_count: issues.nodes.length,\n items: issues.nodes.slice(0, 3).map(i => ({\n number: i.number,\n author: i.author?.login || 'unknown'\n }))\n };\n fs.writeFileSync(`${dir}/test4-out-of-scope-graphql.json`, JSON.stringify(summary, null, 2));\n console.log(`Out-of-scope GraphQL issues: ${issues.nodes.length} items (expected: 0 or blocked)`);\n} catch (err) {\n const summary = { test: 'out-of-scope-graphql-issues', error: err.message };\n fs.writeFileSync(`${dir}/test4-out-of-scope-graphql.json`, JSON.stringify(summary, null, 2));\n console.log(`Out-of-scope GraphQL error (may be expected): ${err.message}`);\n}\n" - - name: "Test 5: In-scope search code (REST)" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n const result = await github.rest.search.code({\n q: 'repo:github/gh-aw-mcpg filename:README',\n per_page: 3\n });\n const summary = {\n test: 'in-scope-search-code',\n total_count: result.data.total_count,\n item_count: result.data.items.length,\n items: result.data.items.map(i => ({\n name: i.name,\n path: i.path,\n repo: i.repository?.full_name\n }))\n };\n fs.writeFileSync(`${dir}/test5-in-scope-search.json`, JSON.stringify(summary, null, 2));\n console.log(`✅ In-scope search_code: ${result.data.items.length} items`);\n} catch (err) {\n const summary = { test: 'in-scope-search-code', error: err.message, status: err.status };\n fs.writeFileSync(`${dir}/test5-in-scope-search.json`, JSON.stringify(summary, null, 2));\n console.log(`❌ In-scope search failed: ${err.message}`);\n}\n" - - name: "Test 6: Integrity filtering of bot-authored content" - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - base-url: http://localhost:18443 - script: "const fs = require('fs');\nconst dir = process.env.RESULTS_DIR;\ntry {\n // Search for issues authored by github-actions[bot] — these should pass\n // because trusted bots get writer (approved) integrity\n const result = await github.rest.issues.listForRepo({\n owner: 'github',\n repo: 'gh-aw-mcpg',\n per_page: 20,\n state: 'all',\n creator: 'github-actions[bot]'\n });\n const summary = {\n test: 'integrity-bot-authored',\n status_code: result.status,\n bot_issue_count: result.data.length,\n items: result.data.slice(0, 5).map(i => ({\n number: i.number,\n title: i.title.substring(0, 60),\n author: i.user?.login || 'unknown',\n author_association: i.author_association || 'N/A'\n })),\n note: 'Bot-authored issues should pass integrity filter (trusted bot = approved)'\n };\n fs.writeFileSync(`${dir}/test6-bot-integrity.json`, JSON.stringify(summary, null, 2));\n console.log(`Bot-authored issues visible: ${result.data.length}`);\n} catch (err) {\n const summary = { test: 'integrity-bot-authored', error: err.message, status: err.status };\n fs.writeFileSync(`${dir}/test6-bot-integrity.json`, JSON.stringify(summary, null, 2));\n console.log(`Bot integrity test error: ${err.message}`);\n}\n" - - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - name: "Test 7-12: gh CLI tests via proxy" - run: "RESULTS_DIR=\"${RESULTS_DIR:-/tmp/gh-aw/github-script-results}\"\nPROXY=\"http://localhost:18443\"\n\n# Test 7: In-scope list issues (gh CLI REST)\necho \"--- Test 7: In-scope list issues (gh CLI) ---\"\nRESPONSE=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/issues?per_page=5&state=open\" --jq 'length' 2>&1) || true\nCOUNT=$(echo \"$RESPONSE\" | head -1)\nif [ \"$COUNT\" -gt 0 ] 2>/dev/null; then\n echo \"✅ Test 7: $COUNT items\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-list-issues\\\",\\\"item_count\\\":$COUNT}\" > \"$RESULTS_DIR/test7-gh-in-scope-issues.json\"\nelse\n echo \"❌ Test 7: $RESPONSE\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-list-issues\\\",\\\"error\\\":\\\"unexpected: $RESPONSE\\\"}\" > \"$RESULTS_DIR/test7-gh-in-scope-issues.json\"\nfi\n\n# Test 8: Out-of-scope list issues (gh CLI REST)\necho \"--- Test 8: Out-of-scope list issues (gh CLI) ---\"\nRESPONSE=$(gh api \"$PROXY/repos/octocat/Hello-World/issues?per_page=5\" --jq 'length' 2>&1) || true\nCOUNT=$(echo \"$RESPONSE\" | head -1)\nif [ \"$COUNT\" = \"0\" ] 2>/dev/null; then\n echo \"✅ Test 8: 0 items (blocked)\"\n echo \"{\\\"test\\\":\\\"gh-out-of-scope-list-issues\\\",\\\"item_count\\\":0}\" > \"$RESULTS_DIR/test8-gh-out-of-scope-issues.json\"\nelse\n echo \"Test 8: $COUNT items (expected: 0) — raw: $RESPONSE\"\n echo \"{\\\"test\\\":\\\"gh-out-of-scope-list-issues\\\",\\\"item_count\\\":\\\"$COUNT\\\",\\\"raw\\\":\\\"$RESPONSE\\\"}\" > \"$RESULTS_DIR/test8-gh-out-of-scope-issues.json\"\nfi\n\n# Test 9: In-scope GraphQL (gh CLI)\necho \"--- Test 9: In-scope GraphQL (gh CLI) ---\"\nQUERY='query { repository(owner:\"github\", name:\"gh-aw-mcpg\") { issues(first:5, states:OPEN) { totalCount nodes { number title author { login } authorAssociation } } } }'\nRESPONSE=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.repository.issues.totalCount' 2>&1) || true\nCOUNT=$(echo \"$RESPONSE\" | head -1)\nif [ \"$COUNT\" -gt 0 ] 2>/dev/null; then\n echo \"✅ Test 9: totalCount=$COUNT\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-graphql\\\",\\\"total_count\\\":$COUNT}\" > \"$RESULTS_DIR/test9-gh-in-scope-graphql.json\"\nelse\n echo \"❌ Test 9: $RESPONSE\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-graphql\\\",\\\"error\\\":\\\"$RESPONSE\\\"}\" > \"$RESULTS_DIR/test9-gh-in-scope-graphql.json\"\nfi\n\n# Test 10: Out-of-scope GraphQL (gh CLI)\necho \"--- Test 10: Out-of-scope GraphQL (gh CLI) ---\"\nQUERY='query { repository(owner:\"octocat\", name:\"Hello-World\") { issues(first:5, states:OPEN) { totalCount nodes { number title author { login } } } } }'\nRESPONSE=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.repository.issues.totalCount' 2>&1) || true\nCOUNT=$(echo \"$RESPONSE\" | head -1)\nif [ \"$COUNT\" = \"0\" ] || [ -z \"$COUNT\" ] || [ \"$COUNT\" = \"null\" ]; then\n echo \"✅ Test 10: blocked (count=$COUNT)\"\n echo \"{\\\"test\\\":\\\"gh-out-of-scope-graphql\\\",\\\"total_count\\\":0,\\\"raw\\\":\\\"$RESPONSE\\\"}\" > \"$RESULTS_DIR/test10-gh-out-of-scope-graphql.json\"\nelse\n echo \"Test 10: totalCount=$COUNT (expected: 0)\"\n echo \"{\\\"test\\\":\\\"gh-out-of-scope-graphql\\\",\\\"total_count\\\":$COUNT}\" > \"$RESULTS_DIR/test10-gh-out-of-scope-graphql.json\"\nfi\n\n# Test 11: In-scope search code (gh CLI) — uses /api/v3/ prefix to test StripGHHostPrefix\necho \"--- Test 11: In-scope search code (gh CLI, /api/v3 prefix) ---\"\nRESPONSE=$(gh api \"$PROXY/api/v3/search/code?q=repo:github/gh-aw-mcpg+filename:README&per_page=3\" --jq '.total_count' 2>&1) || true\nCOUNT=$(echo \"$RESPONSE\" | head -1)\nif [ \"$COUNT\" -gt 0 ] 2>/dev/null; then\n echo \"✅ Test 11: $COUNT results (via /api/v3/ prefix)\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-search\\\",\\\"total_count\\\":$COUNT,\\\"note\\\":\\\"used /api/v3/ prefix\\\"}\" > \"$RESULTS_DIR/test11-gh-in-scope-search.json\"\nelse\n echo \"❌ Test 11: $RESPONSE\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-search\\\",\\\"error\\\":\\\"$RESPONSE\\\"}\" > \"$RESULTS_DIR/test11-gh-in-scope-search.json\"\nfi\n\n# Test 12: In-scope get file contents (gh CLI) — uses /api/v3/ prefix\necho \"--- Test 12: In-scope get file contents (gh CLI, /api/v3 prefix) ---\"\nRESPONSE=$(gh api \"$PROXY/api/v3/repos/github/gh-aw-mcpg/contents/README.md\" --jq '.name' 2>&1) || true\nif [ \"$RESPONSE\" = \"README.md\" ]; then\n echo \"✅ Test 12: $RESPONSE (via /api/v3/ prefix)\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-file-contents\\\",\\\"name\\\":\\\"$RESPONSE\\\",\\\"note\\\":\\\"used /api/v3/ prefix\\\"}\" > \"$RESULTS_DIR/test12-gh-in-scope-file.json\"\nelse\n echo \"❌ Test 12: $RESPONSE\"\n echo \"{\\\"test\\\":\\\"gh-in-scope-file-contents\\\",\\\"error\\\":\\\"$RESPONSE\\\"}\" > \"$RESULTS_DIR/test12-gh-in-scope-file.json\"\nfi\n\necho \"--- gh CLI tests complete ---\"\n" - - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - name: "Test 13-47: Comprehensive proxy route coverage" - run: "RESULTS_DIR=\"${RESULTS_DIR:-/tmp/gh-aw/github-script-results}\"\nPROXY=\"http://localhost:18443\"\nPASS=0; FAIL=0; SKIP=0\n\nwrite_result() {\n local num=\"$1\" name=\"$2\" tool=\"$3\" scope=\"$4\" result=\"$5\" count=\"$6\" note=\"$7\"\n echo \"{\\\"test\\\":\\\"${name}\\\",\\\"tool\\\":\\\"${tool}\\\",\\\"scope\\\":\\\"${scope}\\\",\\\"result\\\":\\\"${result}\\\",\\\"item_count\\\":${count:-0},\\\"note\\\":\\\"${note}\\\"}\" \\\n > \"$RESULTS_DIR/test${num}-${name}.json\"\n case \"$result\" in\n pass) echo \"✅ Test $num ($name): $note\"; PASS=$((PASS+1)) ;;\n skip) echo \"⏭️ Test $num ($name): $note\"; SKIP=$((SKIP+1)) ;;\n *) echo \"❌ Test $num ($name): $note\"; FAIL=$((FAIL+1)) ;;\n esac\n}\n\n# ── Discovery: extract IDs from in-scope repo ──────────────────\necho \"=== Discovering test fixtures ===\"\n\nISSUE_NUM=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/issues?per_page=1&state=all\" --jq '.[0].number' 2>&1) || true\n[ \"$ISSUE_NUM\" -gt 0 ] 2>/dev/null || ISSUE_NUM=\"\"\necho \"Issue: ${ISSUE_NUM:-none}\"\n\nPR_NUM=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls?per_page=1&state=all\" --jq '.[0].number' 2>&1) || true\n[ \"$PR_NUM\" -gt 0 ] 2>/dev/null || PR_NUM=\"\"\necho \"PR: ${PR_NUM:-none}\"\n\nCOMMIT_SHA=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/commits?per_page=1\" --jq '.[0].sha' 2>&1) || true\n[ \"${#COMMIT_SHA}\" -ge 7 ] 2>/dev/null || COMMIT_SHA=\"\"\necho \"Commit: ${COMMIT_SHA:-none}\"\n\necho \"\"\necho \"=== Tests 13-47: Comprehensive proxy route coverage ===\"\n\n# ── Issues (13-16) ─────────────────────────────────────────────\n\necho \"--- Test 13: issue_read in-scope ---\"\nif [ -n \"$ISSUE_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/issues/$ISSUE_NUM\" --jq '.number' 2>&1) || true\n if [ \"$RESP\" = \"$ISSUE_NUM\" ]; then\n write_result 13 issue-read-inscope issue_read in-scope pass 1 \"issue #$ISSUE_NUM\"\n else\n write_result 13 issue-read-inscope issue_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 13 issue-read-inscope issue_read in-scope skip 0 \"no issues to test\"\nfi\n\necho \"--- Test 14: issue_read out-of-scope ---\"\nif RESP=$(gh api \"$PROXY/repos/octocat/Hello-World/issues/1\" --jq '.number' 2>/dev/null); then\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 14 issue-read-outscope issue_read out-of-scope fail 1 \"returned issue #$RESP\"\n else\n write_result 14 issue-read-outscope issue_read out-of-scope pass 0 \"blocked\"\n fi\nelse\n write_result 14 issue-read-outscope issue_read out-of-scope pass 0 \"blocked (error)\"\nfi\n\necho \"--- Test 15: issue_read comments in-scope ---\"\nif [ -n \"$ISSUE_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/issues/$ISSUE_NUM/comments?per_page=5\" --jq 'length' 2>&1) || true\n if [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 15 issue-comments-inscope issue_read in-scope pass \"$RESP\" \"$RESP comments\"\n else\n write_result 15 issue-comments-inscope issue_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 15 issue-comments-inscope issue_read in-scope skip 0 \"no issues to test\"\nfi\n\necho \"--- Test 16: issue_read labels in-scope ---\"\nif [ -n \"$ISSUE_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/issues/$ISSUE_NUM/labels\" --jq 'length' 2>&1) || true\n if [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 16 issue-labels-inscope issue_read in-scope pass \"$RESP\" \"$RESP labels\"\n else\n write_result 16 issue-labels-inscope issue_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 16 issue-labels-inscope issue_read in-scope skip 0 \"no issues to test\"\nfi\n\n# ── Pull Requests (17-22) ──────────────────────────────────────\n\necho \"--- Test 17: list_pull_requests in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls?per_page=5&state=all\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 17 list-prs-inscope list_pull_requests in-scope pass \"$RESP\" \"$RESP PRs\"\nelif [ \"$RESP\" = \"0\" ]; then\n write_result 17 list-prs-inscope list_pull_requests in-scope skip 0 \"no PRs found\"\nelse\n write_result 17 list-prs-inscope list_pull_requests in-scope fail 0 \"unexpected response\"\nfi\n\necho \"--- Test 18: list_pull_requests out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/pulls?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 18 list-prs-outscope list_pull_requests out-of-scope pass 0 \"blocked\"\nelse\n write_result 18 list-prs-outscope list_pull_requests out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\necho \"--- Test 19: pull_request_read in-scope ---\"\nif [ -n \"$PR_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls/$PR_NUM\" --jq '.number' 2>&1) || true\n if [ \"$RESP\" = \"$PR_NUM\" ]; then\n write_result 19 pr-read-inscope pull_request_read in-scope pass 1 \"PR #$PR_NUM\"\n else\n write_result 19 pr-read-inscope pull_request_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 19 pr-read-inscope pull_request_read in-scope skip 0 \"no PRs to test\"\nfi\n\necho \"--- Test 20: pull_request_read files in-scope ---\"\nif [ -n \"$PR_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls/$PR_NUM/files?per_page=5\" --jq 'length' 2>&1) || true\n if [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 20 pr-files-inscope pull_request_read in-scope pass \"$RESP\" \"$RESP files\"\n else\n write_result 20 pr-files-inscope pull_request_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 20 pr-files-inscope pull_request_read in-scope skip 0 \"no PRs to test\"\nfi\n\necho \"--- Test 21: pull_request_read reviews in-scope ---\"\nif [ -n \"$PR_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls/$PR_NUM/reviews\" --jq 'length' 2>&1) || true\n if [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 21 pr-reviews-inscope pull_request_read in-scope pass \"$RESP\" \"$RESP reviews\"\n else\n write_result 21 pr-reviews-inscope pull_request_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 21 pr-reviews-inscope pull_request_read in-scope skip 0 \"no PRs to test\"\nfi\n\necho \"--- Test 22: pull_request_read comments in-scope ---\"\nif [ -n \"$PR_NUM\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/pulls/$PR_NUM/comments\" --jq 'length' 2>&1) || true\n if [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 22 pr-comments-inscope pull_request_read in-scope pass \"$RESP\" \"$RESP comments\"\n else\n write_result 22 pr-comments-inscope pull_request_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 22 pr-comments-inscope pull_request_read in-scope skip 0 \"no PRs to test\"\nfi\n\n# ── Commits (23-25) ────────────────────────────────────────────\n\necho \"--- Test 23: list_commits in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/commits?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 23 list-commits-inscope list_commits in-scope pass \"$RESP\" \"$RESP commits\"\nelse\n write_result 23 list-commits-inscope list_commits in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 24: list_commits out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/commits?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 24 list-commits-outscope list_commits out-of-scope pass 0 \"blocked\"\nelse\n write_result 24 list-commits-outscope list_commits out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\necho \"--- Test 25: get_commit in-scope ---\"\nif [ -n \"$COMMIT_SHA\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/commits/$COMMIT_SHA\" --jq '.sha' 2>&1) || true\n if [ \"$RESP\" = \"$COMMIT_SHA\" ]; then\n write_result 25 get-commit-inscope get_commit in-scope pass 1 \"sha ${COMMIT_SHA:0:12}\"\n else\n write_result 25 get-commit-inscope get_commit in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 25 get-commit-inscope get_commit in-scope skip 0 \"no commits to test\"\nfi\n\n# ── Branches & Tags (26-29) ────────────────────────────────────\n\necho \"--- Test 26: list_branches in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/branches?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 26 list-branches-inscope list_branches in-scope pass \"$RESP\" \"$RESP branches\"\nelse\n write_result 26 list-branches-inscope list_branches in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 27: list_branches out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/branches?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 27 list-branches-outscope list_branches out-of-scope pass 0 \"blocked\"\nelse\n write_result 27 list-branches-outscope list_branches out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\necho \"--- Test 28: list_tags in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/tags?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 28 list-tags-inscope list_tags in-scope pass \"$RESP\" \"$RESP tags\"\nelse\n write_result 28 list-tags-inscope list_tags in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 29: list_tags out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/tags?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 29 list-tags-outscope list_tags out-of-scope pass 0 \"blocked\"\nelse\n write_result 29 list-tags-outscope list_tags out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\n# ── Releases (30-32) ───────────────────────────────────────────\n\necho \"--- Test 30: list_releases in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/releases?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 30 list-releases-inscope list_releases in-scope pass \"$RESP\" \"$RESP releases\"\nelse\n write_result 30 list-releases-inscope list_releases in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 31: list_releases out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/releases?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 31 list-releases-outscope list_releases out-of-scope pass 0 \"blocked\"\nelse\n write_result 31 list-releases-outscope list_releases out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\necho \"--- Test 32: get_latest_release in-scope ---\"\nif RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/releases/latest\" --jq '.tag_name' 2>/dev/null); then\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 32 latest-release-inscope get_latest_release in-scope pass 1 \"tag $RESP\"\n else\n write_result 32 latest-release-inscope get_latest_release in-scope skip 0 \"no releases\"\n fi\nelse\n write_result 32 latest-release-inscope get_latest_release in-scope skip 0 \"404 no releases\"\nfi\n\n# ── Labels (33-35) ─────────────────────────────────────────────\n\necho \"--- Test 33: list_labels in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/labels?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 33 list-labels-inscope list_labels in-scope pass \"$RESP\" \"$RESP labels (0 expected: labels lack authorship)\"\nelse\n write_result 33 list-labels-inscope list_labels in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 34: list_labels out-of-scope ---\"\nRESP=$(gh api \"$PROXY/repos/octocat/Hello-World/labels?per_page=5\" --jq 'length' 2>&1) || true\nif [ \"$RESP\" = \"0\" ]; then\n write_result 34 list-labels-outscope list_labels out-of-scope pass 0 \"blocked\"\nelse\n write_result 34 list-labels-outscope list_labels out-of-scope fail \"${RESP:-0}\" \"expected 0, got $RESP\"\nfi\n\necho \"--- Test 35: get_label in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/labels/bug\" --jq '.name' 2>&1) || true\nif [ \"$RESP\" = \"bug\" ]; then\n write_result 35 get-label-inscope get_label in-scope pass 1 \"label: bug\"\nelse\n if RESP2=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/labels/enhancement\" --jq '.name' 2>/dev/null); then\n write_result 35 get-label-inscope get_label in-scope pass 1 \"label: $RESP2\"\n else\n write_result 35 get-label-inscope get_label in-scope skip 0 \"no known label found\"\n fi\nfi\n\n# ── Actions (36-37) ────────────────────────────────────────────\n\necho \"--- Test 36: actions_list workflows in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/actions/workflows?per_page=3\" --jq '.total_count' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 36 actions-workflows-inscope actions_list in-scope pass \"$RESP\" \"$RESP workflows\"\nelif [ \"$RESP\" = \"0\" ]; then\n write_result 36 actions-workflows-inscope actions_list in-scope skip 0 \"no workflows\"\nelse\n write_result 36 actions-workflows-inscope actions_list in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 37: actions_list runs in-scope ---\"\nRESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/actions/runs?per_page=3\" --jq '.total_count' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 37 actions-runs-inscope actions_list in-scope pass \"$RESP\" \"$RESP runs\"\nelif [ \"$RESP\" = \"0\" ]; then\n write_result 37 actions-runs-inscope actions_list in-scope skip 0 \"no runs\"\nelse\n write_result 37 actions-runs-inscope actions_list in-scope fail 0 \"unexpected: $RESP\"\nfi\n\n# ── User/Global (38-40) ────────────────────────────────────────\n\necho \"--- Test 38: get_me (should be blocked) ---\"\nif RESP=$(gh api \"$PROXY/user\" --jq '.login' 2>/dev/null); then\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 38 get-me-blocked get_me global fail 1 \"returned login: $RESP\"\n else\n write_result 38 get-me-blocked get_me global pass 0 \"blocked\"\n fi\nelse\n write_result 38 get-me-blocked get_me global pass 0 \"blocked (error)\"\nfi\n\necho \"--- Test 39: search_issues in-scope ---\"\nRESP=$(gh api \"$PROXY/search/issues?q=repo:github/gh-aw-mcpg+is:open&per_page=3\" --jq '.total_count' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 39 search-issues-inscope search_issues in-scope pass \"$RESP\" \"$RESP results\"\nelse\n write_result 39 search-issues-inscope search_issues in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 40: search_repositories ---\"\nRESP=$(gh api \"$PROXY/search/repositories?q=gh-aw-mcpg&per_page=3\" --jq '.total_count' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 40 search-repos search_repositories global pass \"$RESP\" \"$RESP results\"\nelse\n write_result 40 search-repos search_repositories global pass 0 \"blocked or error\"\nfi\n\n# ── GraphQL Expansions (41-44) ─────────────────────────────────\n\necho \"--- Test 41: GraphQL pull_request_read in-scope ---\"\nQUERY='query { repository(owner:\"github\", name:\"gh-aw-mcpg\") { pullRequests(first:3, states:[OPEN,MERGED]) { nodes { number title } } } }'\nRESP=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.repository.pullRequests.nodes | length' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null; then\n write_result 41 graphql-prs-inscope pull_request_read in-scope pass \"$RESP\" \"$RESP PRs via GraphQL\"\nelse\n write_result 41 graphql-prs-inscope pull_request_read in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 42: GraphQL list_commits in-scope ---\"\nQUERY='query { repository(owner:\"github\", name:\"gh-aw-mcpg\") { defaultBranchRef { target { ... on Commit { history(first:3) { nodes { oid message } } } } } } }'\nRESP=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.repository.defaultBranchRef.target.history.nodes | length' 2>&1) || true\nif [ \"$RESP\" -gt 0 ] 2>/dev/null; then\n write_result 42 graphql-commits-inscope list_commits in-scope pass \"$RESP\" \"$RESP commits via GraphQL\"\nelse\n write_result 42 graphql-commits-inscope list_commits in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 43: GraphQL search in-scope ---\"\nQUERY='query { search(query:\"repo:github/gh-aw-mcpg is:issue\", type:ISSUE, first:3) { issueCount nodes { ... on Issue { number title } } } }'\nRESP=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.search.issueCount // 0' 2>&1) || true\nif [ \"$RESP\" -ge 0 ] 2>/dev/null && [ \"$RESP\" -gt 0 ]; then\n write_result 43 graphql-search-inscope search_issues in-scope pass \"$RESP\" \"$RESP issues via GraphQL\"\nelif [ \"$RESP\" = \"0\" ] 2>/dev/null; then\n write_result 43 graphql-search-inscope search_issues in-scope pass 0 \"0 issues (guard may lack repo scope on GraphQL search items)\"\nelse\n write_result 43 graphql-search-inscope search_issues in-scope fail 0 \"unexpected: $RESP\"\nfi\n\necho \"--- Test 44: GraphQL viewer (should be blocked) ---\"\nQUERY='query { viewer { login } }'\nRESP=$(gh api \"$PROXY/graphql\" -f query=\"$QUERY\" --jq '.data.viewer.login // empty' 2>&1) || true\nif [ -z \"$RESP\" ] || [ \"$RESP\" = \"null\" ]; then\n write_result 44 graphql-viewer-blocked get_me global pass 0 \"blocked\"\nelse\n write_result 44 graphql-viewer-blocked get_me global fail 1 \"returned: $RESP\"\nfi\n\n# ── Compare (45) ───────────────────────────────────────────────\n\necho \"--- Test 45: compare in-scope ---\"\nif [ -n \"$COMMIT_SHA\" ]; then\n RESP=$(gh api \"$PROXY/repos/github/gh-aw-mcpg/compare/main...$COMMIT_SHA\" --jq '.status' 2>&1) || true\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 45 compare-inscope pull_request_read in-scope pass 1 \"status: $RESP\"\n else\n write_result 45 compare-inscope pull_request_read in-scope fail 0 \"unexpected response\"\n fi\nelse\n write_result 45 compare-inscope pull_request_read in-scope skip 0 \"no commit SHA\"\nfi\n\n# ── Out-of-scope single objects (46-47) ────────────────────────\n\necho \"--- Test 46: get_file_contents out-of-scope ---\"\nif RESP=$(gh api \"$PROXY/repos/octocat/Hello-World/contents/README\" --jq '.name' 2>/dev/null); then\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 46 file-contents-outscope get_file_contents out-of-scope fail 1 \"returned: $RESP\"\n else\n write_result 46 file-contents-outscope get_file_contents out-of-scope pass 0 \"blocked\"\n fi\nelse\n write_result 46 file-contents-outscope get_file_contents out-of-scope pass 0 \"blocked (error)\"\nfi\n\necho \"--- Test 47: get_commit out-of-scope ---\"\nOOS_SHA=$(gh api \"$PROXY/repos/octocat/Hello-World/commits?per_page=1\" --jq '.[0].sha' 2>&1) || true\nif [ \"${#OOS_SHA}\" -ge 7 ]; then\n if RESP=$(gh api \"$PROXY/repos/octocat/Hello-World/commits/$OOS_SHA\" --jq '.sha' 2>/dev/null); then\n if [ -n \"$RESP\" ] && [ \"$RESP\" != \"null\" ]; then\n write_result 47 get-commit-outscope get_commit out-of-scope fail 1 \"returned SHA\"\n else\n write_result 47 get-commit-outscope get_commit out-of-scope pass 0 \"blocked\"\n fi\n else\n write_result 47 get-commit-outscope get_commit out-of-scope pass 0 \"blocked (error)\"\n fi\nelse\n write_result 47 get-commit-outscope get_commit out-of-scope pass 0 \"list blocked (no SHA)\"\nfi\n\n# ── Summary ────────────────────────────────────────────────────\necho \"\"\necho \"=== Route Coverage Summary ===\"\necho \"✅ Passed: $PASS\"\necho \"❌ Failed: $FAIL\"\necho \"⏭️ Skipped: $SKIP\"\necho \"Total: $((PASS + FAIL + SKIP)) tests\"\necho \"\"\nif [ \"$FAIL\" -gt 0 ]; then\n echo \"::warning::$FAIL test(s) failed in comprehensive route coverage\"\nfi\n" - - if: always() - name: Collect proxy logs and stop proxy - run: "RESULTS_DIR=\"${RESULTS_DIR:-/tmp/gh-aw/github-script-results}\"\nMCP_LOG_DIR=/tmp/gh-aw/mcp-logs\n\n# Save proxy container logs\ndocker logs awmg-proxy 2>&1 > \"$RESULTS_DIR/proxy-container.log\" || true\n\n# Count DIFC events in JSONL\nif [ -f \"$MCP_LOG_DIR/rpc-messages.jsonl\" ]; then\n cp \"$MCP_LOG_DIR/rpc-messages.jsonl\" \"$RESULTS_DIR/rpc-messages.jsonl\"\n FILTERED=$(grep -c '\"event\":\"difc_filtered\"' \"$MCP_LOG_DIR/rpc-messages.jsonl\" 2>/dev/null || echo \"0\")\n TOTAL=$(wc -l < \"$MCP_LOG_DIR/rpc-messages.jsonl\" 2>/dev/null || echo \"0\")\n echo \"{\\\"difc_filtered_count\\\": $FILTERED, \\\"total_rpc_messages\\\": $TOTAL}\" > \"$RESULTS_DIR/difc-summary.json\"\n echo \"DIFC events: $FILTERED filtered out of $TOTAL RPC messages\"\nfi\n\n# Stop proxy\ndocker rm -f awmg-proxy 2>/dev/null || true\necho \"Proxy stopped\"\n" - - # Cache memory file share configuration from frontmatter processed below - - name: Create cache-memory directory - run: bash ${RUNNER_TEMP}/gh-aw/actions/create_cache_memory_dir.sh - - name: Restore cache-memory file share data - uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 - with: - key: memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} - path: /tmp/gh-aw/cache-memory - restore-keys: | - memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}- - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - 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" - - name: Checkout PR branch - id: checkout-pr - if: | - github.event.pull_request || github.event.issue.pull_request - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - with: - github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs'); - await main(); - - name: Install GitHub Copilot CLI - run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest - env: - GH_HOST: github.com - - name: Install AWF binary - run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.0 - - name: Parse integrity filter lists - id: parse-guard-vars - env: - GH_AW_BLOCKED_USERS_VAR: ${{ vars.GH_AW_GITHUB_BLOCKED_USERS || '' }} - GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }} - run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh - - name: Download container images - run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh alpine:latest ghcr.io/github/gh-aw-firewall/agent:0.25.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.0 ghcr.io/github/gh-aw-firewall/squid:0.25.0 ghcr.io/github/gh-aw-mcpg:v0.2.2 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine - - name: Install gh-aw extension - env: - GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - run: | - # Check if gh-aw extension is already installed - if gh extension list | grep -q "github/gh-aw"; then - echo "gh-aw extension already installed, upgrading..." - gh extension upgrade gh-aw || true - else - echo "Installing gh-aw extension..." - gh extension install github/gh-aw - fi - gh aw --version - # Copy the gh-aw binary to ${RUNNER_TEMP}/gh-aw for MCP server containerization - mkdir -p ${RUNNER_TEMP}/gh-aw - GH_AW_BIN=$(which gh-aw 2>/dev/null || find ~/.local/share/gh/extensions/gh-aw -name 'gh-aw' -type f 2>/dev/null | head -1) - if [ -n "$GH_AW_BIN" ] && [ -f "$GH_AW_BIN" ]; then - cp "$GH_AW_BIN" ${RUNNER_TEMP}/gh-aw/gh-aw - chmod +x ${RUNNER_TEMP}/gh-aw/gh-aw - echo "Copied gh-aw binary to ${RUNNER_TEMP}/gh-aw/gh-aw" - else - echo "::error::Failed to find gh-aw binary for MCP server" - exit 1 - fi - - name: Write 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_EOF' - {"add_comment":{"max":2},"create_issue":{"expires":2,"group":true,"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_EOF - - name: Write Safe Outputs Tools - run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF' - { - "description_suffixes": { - "add_comment": " CONSTRAINTS: Maximum 2 comment(s) can be added.", - "create_issue": " CONSTRAINTS: Maximum 1 issue(s) can be created." - }, - "repo_params": {}, - "dynamic_tools": [] - } - GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF' - { - "add_comment": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "item_number": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - } - } - }, - "create_issue": { - "defaultMax": 1, - "fields": { - "body": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - }, - "labels": { - "type": "array", - "itemType": "string", - "itemSanitize": true, - "itemMaxLength": 128 - }, - "parent": { - "issueOrPRNumber": true - }, - "repo": { - "type": "string", - "maxLength": 256 - }, - "temporary_id": { - "type": "string" - }, - "title": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "missing_data": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "context": { - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "data_type": { - "type": "string", - "sanitize": true, - "maxLength": 128 - }, - "reason": { - "type": "string", - "sanitize": true, - "maxLength": 256 - } - } - }, - "missing_tool": { - "defaultMax": 20, - "fields": { - "alternatives": { - "type": "string", - "sanitize": true, - "maxLength": 512 - }, - "reason": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 256 - }, - "tool": { - "type": "string", - "sanitize": true, - "maxLength": 128 - } - } - }, - "noop": { - "defaultMax": 1, - "fields": { - "message": { - "required": true, - "type": "string", - "sanitize": true, - "maxLength": 65000 - } - } - } - } - GH_AW_SAFE_OUTPUTS_VALIDATION_EOF - node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs - - 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_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_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 }} - 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 /tmp/gh-aw/mcp-config - - # Export gateway environment variables for MCP config and gateway script - export MCP_GATEWAY_PORT="80" - export MCP_GATEWAY_DOMAIN="host.docker.internal" - MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=') - echo "::add-mask::${MCP_GATEWAY_API_KEY}" - export MCP_GATEWAY_API_KEY - export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads" - mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}" - export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288" - export DEBUG="*" - - export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/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 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.2.2' - - mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh - { - "mcpServers": { - "agenticworkflows": { - "type": "stdio", - "container": "alpine:latest", - "entrypoint": "${RUNNER_TEMP}/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server", "--validate-actor"], - "mounts": ["${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], - "args": ["--network", "host", "-w", "\${GITHUB_WORKSPACE}"], - "env": { - "DEBUG": "*", - "GITHUB_TOKEN": "\${GITHUB_TOKEN}", - "GITHUB_ACTOR": "\${GITHUB_ACTOR}", - "GITHUB_REPOSITORY": "\${GITHUB_REPOSITORY}" - }, - "guard-policies": { - "write-sink": { - "accept": [ - "private:github/gh-aw-mcpg" - ] - } - } - }, - "github": { - "type": "stdio", - "container": "ghcr.io/github/github-mcp-server:v0.32.0", - "env": { - "GITHUB_HOST": "\${GITHUB_SERVER_URL}", - "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}", - "GITHUB_READ_ONLY": "1", - "GITHUB_TOOLSETS": "repos,issues" - }, - "guard-policies": { - "allow-only": { - "approval-labels": ${{ steps.parse-guard-vars.outputs.approval_labels }}, - "blocked-users": ${{ steps.parse-guard-vars.outputs.blocked_users }}, - "min-integrity": "approved", - "repos": [ - "github/gh-aw-mcpg" - ] - } - } - }, - "safeoutputs": { - "type": "http", - "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", - "headers": { - "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}" - }, - "guard-policies": { - "write-sink": { - "accept": [ - "private:github/gh-aw-mcpg" - ] - } - } - } - }, - "gateway": { - "port": $MCP_GATEWAY_PORT, - "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "${MCP_GATEWAY_API_KEY}", - "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" - } - } - GH_AW_MCP_CONFIG_EOF - - name: Download activation artifact - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: activation - path: /tmp/gh-aw - - name: Clean git credentials - continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh - - name: Execute GitHub Copilot CLI - id: agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool github - # --allow-tool safeoutputs - # --allow-tool shell(cat) - # --allow-tool shell(curl) - # --allow-tool shell(date) - # --allow-tool shell(echo) - # --allow-tool shell(gh:*) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(pwd) - # --allow-tool shell(sort) - # --allow-tool shell(tail) - # --allow-tool shell(uniq) - # --allow-tool shell(wc) - # --allow-tool shell(yq) - # --allow-tool write - timeout-minutes: 15 - run: | - set -o pipefail - touch /tmp/gh-aw/agent-step-summary.md - # shellcheck disable=SC1003 - sudo -E awf --env-all --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" --allow-domains "*.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,crates.io,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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,index.crates.io,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,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sh.rustup.rs,static.crates.io,static.rust-lang.org,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.25.0 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(curl)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(gh:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} - GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json - 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_VERSION: v0.63.0 - GITHUB_API_URL: ${{ github.api_url }} - GITHUB_AW: true - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md - GITHUB_WORKSPACE: ${{ github.workspace }} - GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_AUTHOR_NAME: github-actions[bot] - GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_COMMITTER_NAME: github-actions[bot] - XDG_CONFIG_HOME: /home/runner - - name: Detect inference access error - id: detect-inference-error - if: always() - continue-on-error: true - run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh - - name: Configure Git credentials - env: - REPO_NAME: ${{ github.repository }} - SERVER_URL: ${{ github.server_url }} - 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" - - name: Copy Copilot session state files to logs - if: always() - continue-on-error: true - run: | - # Copy Copilot session state files to logs folder for artifact collection - # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them - SESSION_STATE_DIR="$HOME/.copilot/session-state" - LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs" - - if [ -d "$SESSION_STATE_DIR" ]; then - echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR" - mkdir -p "$LOGS_DIR" - cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true - echo "Session state files copied successfully" - else - echo "No session-state directory found at $SESSION_STATE_DIR" - fi - - name: Stop MCP Gateway - if: always() - continue-on-error: true - env: - MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }} - MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }} - GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }} - run: | - bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID" - - name: Redact secrets in logs - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - 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 }} - 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 }} - - name: Append agent step summary - if: always() - run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh - - name: Copy Safe Outputs - if: always() - env: - GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - run: | - mkdir -p /tmp/gh-aw - cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true - - name: Ingest agent output - id: collect_output - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.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,crates.io,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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,index.crates.io,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,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sh.rustup.rs,static.crates.io,static.rust-lang.org,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 }} - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs'); - await main(); - - name: Parse agent logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/ - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs'); - await main(); - - name: Parse MCP Gateway logs for step summary - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs'); - await main(); - - name: Print firewall logs - if: always() - continue-on-error: true - env: - AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs - run: | - # Fix permissions on firewall logs so they can be uploaded as artifacts - # AWF runs with sudo, creating files owned by root - sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true - # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step) - if command -v awf &> /dev/null; then - awf logs summary | tee -a "$GITHUB_STEP_SUMMARY" - else - echo 'AWF binary not installed, skipping firewall log summary' - fi - - name: Upload cache-memory data as artifact - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - if: always() - with: - name: cache-memory - path: /tmp/gh-aw/cache-memory - - name: Upload agent artifacts - if: always() - continue-on-error: true - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: agent - path: | - /tmp/gh-aw/aw-prompts/prompt.txt - /tmp/gh-aw/sandbox/agent/logs/ - /tmp/gh-aw/redacted-urls.log - /tmp/gh-aw/mcp-logs/ - /tmp/gh-aw/sandbox/firewall/logs/ - /tmp/gh-aw/agent-stdio.log - /tmp/gh-aw/agent/ - /tmp/gh-aw/safeoutputs.jsonl - /tmp/gh-aw/agent_output.json - if-no-files-found: ignore - # --- Threat Detection (inline) --- - - name: Check if detection needed - id: detection_guard - if: always() - env: - OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }} - HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} - run: | - if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then - echo "run_detection=true" >> "$GITHUB_OUTPUT" - echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH" - else - echo "run_detection=false" >> "$GITHUB_OUTPUT" - echo "Detection skipped: no agent outputs or patches to analyze" - fi - - name: Clear MCP configuration for detection - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - rm -f /tmp/gh-aw/mcp-config/mcp-servers.json - rm -f /home/runner/.copilot/mcp-config.json - rm -f "$GITHUB_WORKSPACE/.gemini/settings.json" - - name: Prepare threat detection files - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - mkdir -p /tmp/gh-aw/threat-detection/aw-prompts - cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true - cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true - for f in /tmp/gh-aw/aw-*.patch; do - [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true - done - echo "Prepared threat detection files:" - ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true - - name: Setup threat detection - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - WORKFLOW_NAME: "Smoke: Proxy + github-script" - WORKFLOW_DESCRIPTION: "Smoke test validating that the MCP Gateway proxy applies DIFC integrity filtering to actions/github-script (octokit) API calls" - HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }} - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs'); - await main(); - - name: Ensure threat-detection directory and log - if: always() && steps.detection_guard.outputs.run_detection == 'true' - run: | - mkdir -p /tmp/gh-aw/threat-detection - touch /tmp/gh-aw/threat-detection/detection.log - - name: Execute GitHub Copilot CLI - if: always() && steps.detection_guard.outputs.run_detection == 'true' - id: detection_agentic_execution - # Copilot CLI tool arguments (sorted): - # --allow-tool shell(cat) - # --allow-tool shell(grep) - # --allow-tool shell(head) - # --allow-tool shell(jq) - # --allow-tool shell(ls) - # --allow-tool shell(tail) - # --allow-tool shell(wc) - timeout-minutes: 20 - run: | - set -o pipefail - touch /tmp/gh-aw/agent-step-summary.md - # shellcheck disable=SC1003 - sudo -E awf --env-all --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" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.25.0 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log - env: - COPILOT_AGENT_RUNNER_TYPE: STANDALONE - COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} - COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }} - GH_AW_PHASE: detection - GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt - GH_AW_VERSION: v0.63.0 - GITHUB_API_URL: ${{ github.api_url }} - GITHUB_AW: true - GITHUB_HEAD_REF: ${{ github.head_ref }} - GITHUB_REF_NAME: ${{ github.ref_name }} - GITHUB_SERVER_URL: ${{ github.server_url }} - GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md - GITHUB_WORKSPACE: ${{ github.workspace }} - GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_AUTHOR_NAME: github-actions[bot] - GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com - GIT_COMMITTER_NAME: github-actions[bot] - XDG_CONFIG_HOME: /home/runner - - name: Parse threat detection results - id: parse_detection_results - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - with: - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs'); - await main(); - - name: Upload threat detection log - if: always() && steps.detection_guard.outputs.run_detection == 'true' - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: detection - path: /tmp/gh-aw/threat-detection/detection.log - if-no-files-found: ignore - - name: Set detection conclusion - id: detection_conclusion - if: always() - env: - RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }} - DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }} - run: | - if [[ "$RUN_DETECTION" != "true" ]]; then - echo "conclusion=skipped" >> "$GITHUB_OUTPUT" - echo "success=true" >> "$GITHUB_OUTPUT" - echo "Detection was not needed, marking as skipped" - elif [[ "$DETECTION_SUCCESS" == "true" ]]; then - echo "conclusion=success" >> "$GITHUB_OUTPUT" - echo "success=true" >> "$GITHUB_OUTPUT" - echo "Detection passed successfully" - else - echo "conclusion=failure" >> "$GITHUB_OUTPUT" - echo "success=false" >> "$GITHUB_OUTPUT" - echo "Detection found issues" - fi - - conclusion: - needs: - - activation - - agent - - safe_outputs - - update_cache_memory - if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true') - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - concurrency: - group: "gh-aw-conclusion-smoke-proxy-github-script" - cancel-in-progress: false - outputs: - noop_message: ${{ steps.noop.outputs.noop_message }} - tools_reported: ${{ steps.missing_tool.outputs.tools_reported }} - total_count: ${{ steps.missing_tool.outputs.total_count }} - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Download agent output artifact - id: download-agent-output - continue-on-error: true - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: agent - path: /tmp/gh-aw/ - - name: Setup agent output environment variable - id: setup-agent-output-env - if: steps.download-agent-output.outcome == 'success' - run: | - mkdir -p /tmp/gh-aw/ - find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Process No-Op Messages - id: noop - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} - GH_AW_NOOP_MAX: "1" - GH_AW_WORKFLOW_NAME: "Smoke: Proxy + github-script" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs'); - await main(); - - name: Record Missing Tool - id: missing_tool - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Smoke: Proxy + github-script" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs'); - await main(); - - name: Handle Agent Failure - id: handle_agent_failure - if: always() - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Smoke: Proxy + github-script" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_WORKFLOW_ID: "smoke-proxy-github-script" - GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }} - GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }} - GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }} - GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Proxy + github-script smoke test by [{workflow_name}]({run_url})*\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing DIFC proxy with actions/github-script...\",\"runSuccess\":\"🔬 [{workflow_name}]({run_url}) completed. See results issue. ✅\",\"runFailure\":\"🔬 [{workflow_name}]({run_url}) reports {status}. ⚠️\"}" - GH_AW_GROUP_REPORTS: "false" - GH_AW_FAILURE_REPORT_AS_ISSUE: "true" - GH_AW_TIMEOUT_MINUTES: "15" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs'); - await main(); - - name: Handle No-Op Message - id: handle_noop_message - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} - GH_AW_WORKFLOW_NAME: "Smoke: Proxy + github-script" - GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} - GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} - GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }} - GH_AW_NOOP_REPORT_AS_ISSUE: "true" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs'); - await main(); - - pre_activation: - if: > - (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id) && - (github.event_name != 'pull_request' || github.event.action != 'labeled' || github.event.label.name == 'smoke') - runs-on: ubuntu-slim - outputs: - activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }} - matched_command: '' - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Check team membership for workflow - id: check_membership - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - 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); - const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs'); - await main(); - - safe_outputs: - needs: agent - if: (!cancelled()) && needs.agent.result != 'skipped' && needs.agent.outputs.detection_success == 'true' - runs-on: ubuntu-slim - permissions: - contents: read - discussions: write - issues: write - pull-requests: write - timeout-minutes: 15 - env: - GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/smoke-proxy-github-script" - GH_AW_ENGINE_ID: "copilot" - GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }} - GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e 🔬 *Proxy + github-script smoke test by [{workflow_name}]({run_url})*\",\"runStarted\":\"🔬 [{workflow_name}]({run_url}) is testing DIFC proxy with actions/github-script...\",\"runSuccess\":\"🔬 [{workflow_name}]({run_url}) completed. See results issue. ✅\",\"runFailure\":\"🔬 [{workflow_name}]({run_url}) reports {status}. ⚠️\"}" - GH_AW_WORKFLOW_ID: "smoke-proxy-github-script" - GH_AW_WORKFLOW_NAME: "Smoke: Proxy + github-script" - outputs: - code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }} - code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }} - comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }} - comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }} - create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }} - create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }} - created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }} - created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }} - process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }} - process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }} - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Download agent output artifact - id: download-agent-output - continue-on-error: true - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: agent - path: /tmp/gh-aw/ - - name: Setup agent output environment variable - id: setup-agent-output-env - if: steps.download-agent-output.outcome == 'success' - run: | - mkdir -p /tmp/gh-aw/ - find "/tmp/gh-aw/" -type f -print - echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT" - - name: Configure GH_HOST for enterprise compatibility - id: ghes-host-config - shell: bash - run: | - # 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_OUTPUT" - - name: Process Safe Outputs - id: process_safe_outputs - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 - env: - GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }} - GH_AW_ALLOWED_DOMAINS: "*.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,crates.io,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,docs.github.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,host.docker.internal,index.crates.io,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,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,sh.rustup.rs,static.crates.io,static.rust-lang.org,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: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":2},\"create_issue\":{\"close_older_issues\":true,\"expires\":2,\"group\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"}}" - with: - github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); - setupGlobals(core, github, context, exec, io); - const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs'); - await main(); - - name: Upload safe output items - if: always() - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7 - with: - name: safe-output-items - path: /tmp/gh-aw/safe-output-items.jsonl - if-no-files-found: ignore - - update_cache_memory: - needs: agent - if: always() && needs.agent.outputs.detection_success == 'true' - runs-on: ubuntu-latest - permissions: {} - env: - GH_AW_WORKFLOW_ID_SANITIZED: smokeproxygithubscript - steps: - - name: Setup Scripts - uses: github/gh-aw-actions/setup@9128d2542bbf1bdfec94dabeaf3e1d3c0d402577 # v0.63.0 - with: - destination: ${{ runner.temp }}/gh-aw/actions - - name: Download cache-memory artifact (default) - id: download_cache_default - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - continue-on-error: true - with: - name: cache-memory - path: /tmp/gh-aw/cache-memory - - name: Check if cache-memory folder has content (default) - id: check_cache_default - shell: bash - run: | - if [ -d "/tmp/gh-aw/cache-memory" ] && [ "$(ls -A /tmp/gh-aw/cache-memory 2>/dev/null)" ]; then - echo "has_content=true" >> "$GITHUB_OUTPUT" - else - echo "has_content=false" >> "$GITHUB_OUTPUT" - fi - - name: Save cache-memory to cache (default) - if: steps.check_cache_default.outputs.has_content == 'true' - uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 - with: - key: memory-${{ env.GH_AW_WORKFLOW_ID_SANITIZED }}-${{ github.run_id }} - path: /tmp/gh-aw/cache-memory diff --git a/.github/workflows/smoke-proxy-github-script.lock.yml b/.github/workflows/smoke-proxy-github-script.lock.yml index 2fe68ad71..12aae5ec7 100644 --- a/.github/workflows/smoke-proxy-github-script.lock.yml +++ b/.github/workflows/smoke-proxy-github-script.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"7d3071c7446a0287cdffa70ef597f748d3671232ddd7b13a9552578fddf875bf","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"},{"repo":"github/gh-aw/actions/setup-cli","sha":"1a7f4119f6c4398ed2fc824f99276a55fb382e3f","version":"v0.75.4"}],"containers":[{"image":"alpine:latest","digest":"sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659","pinned_image":"alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"8bd61cf1ac9d2eb0260b5d081191e8192b3ea59da92f7e5de57b42963477f388","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"},{"repo":"github/gh-aw/actions/setup-cli","sha":"58d1bedbb7200f59c2d224151339e38fd8687d05","version":"v0.76.1"}],"containers":[{"image":"alpine:latest","digest":"sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659","pinned_image":"alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659"},{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -40,15 +40,15 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 -# - github/gh-aw/actions/setup-cli@1a7f4119f6c4398ed2fc824f99276a55fb382e3f # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 +# - github/gh-aw/actions/setup-cli@58d1bedbb7200f59c2d224151339e38fd8687d05 # v0.76.1 # # Container images used: # - alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -104,7 +104,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -114,7 +114,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-proxy-github-script.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -124,15 +124,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com","rust"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -167,6 +167,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -177,8 +178,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -196,7 +197,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -231,22 +232,22 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_e3a2a017c2341a19_EOF' + cat << 'GH_AW_PROMPT_da14c315cc3748a5_EOF' - GH_AW_PROMPT_e3a2a017c2341a19_EOF + GH_AW_PROMPT_da14c315cc3748a5_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/agentic_workflows_guide.md" cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_e3a2a017c2341a19_EOF' + cat << 'GH_AW_PROMPT_da14c315cc3748a5_EOF' Tools: add_comment(max:2), create_issue, missing_tool, missing_data, noop - GH_AW_PROMPT_e3a2a017c2341a19_EOF + GH_AW_PROMPT_da14c315cc3748a5_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_e3a2a017c2341a19_EOF' + cat << 'GH_AW_PROMPT_da14c315cc3748a5_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -275,13 +276,13 @@ jobs: {{/if}} - GH_AW_PROMPT_e3a2a017c2341a19_EOF + GH_AW_PROMPT_da14c315cc3748a5_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_e3a2a017c2341a19_EOF' + cat << 'GH_AW_PROMPT_da14c315cc3748a5_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/smoke-proxy-github-script.md}} - GH_AW_PROMPT_e3a2a017c2341a19_EOF + GH_AW_PROMPT_da14c315cc3748a5_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -366,6 +367,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -402,7 +404,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -412,7 +414,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-proxy-github-script.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -437,7 +439,7 @@ jobs: GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITHUB_SERVER_URL: ${{ github.server_url }} DIFC_PROXY_POLICY: '{"allow-only":{"min-integrity":"approved","repos":["github/gh-aw-mcpg"]}}' - DIFC_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.3.18' + DIFC_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:latest' run: | bash "${RUNNER_TEMP}/gh-aw/actions/start_difc_proxy.sh" - name: Build MCP Gateway image @@ -1334,7 +1336,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -1354,20 +1356,37 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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" alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 ghcr.io/github/gh-aw-firewall/agent:0.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" alpine:latest@sha256:25109184c71bdad752c8312a8623239686a9a2071e8825f20acb8f2198c3f659 ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - name: Install gh-aw extension - uses: github/gh-aw/actions/setup-cli@1a7f4119f6c4398ed2fc824f99276a55fb382e3f # v0.75.4 + uses: github/gh-aw/actions/setup-cli@58d1bedbb7200f59c2d224151339e38fd8687d05 # v0.76.1 with: - version: 'v0.75.4' + version: 'v0.76.1' github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - name: Copy gh-aw binary for MCP server run: | @@ -1398,9 +1417,9 @@ jobs: 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_732349b4a7181d9c_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_86fd618242e5e1a8_EOF' {"add_comment":{"hide_older_comments":true,"max":2},"create_issue":{"close_older_issues":true,"expires":2,"group":true,"max":1},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_732349b4a7181d9c_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_86fd618242e5e1a8_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -1626,11 +1645,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_aace741d97c9350a_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_bd3771b4c51b3b6f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "agenticworkflows": { @@ -1697,7 +1716,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_aace741d97c9350a_EOF + GH_AW_MCP_CONFIG_bd3771b4c51b3b6f_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -1751,7 +1770,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","crates.io","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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","index.crates.io","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","sh.rustup.rs","static.crates.io","static.rust-lang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","crates.io","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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","index.crates.io","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","sh.rustup.rs","static.crates.io","static.rust-lang.org","telemetry.enterprise.githubcopilot.com","ts-crl.ws.symantec.com","ts-ocsp.ws.symantec.com","www.googleapis.com"]},"apiProxy":{"enabled":true,"enableTokenSteering":true,"maxRuns":500,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -1770,7 +1789,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1975,7 +1994,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1985,7 +2004,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-proxy-github-script.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -2103,7 +2122,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2111,7 +2130,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-proxy-github-script.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -2162,7 +2181,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -2172,7 +2191,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke: Proxy + github-script" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-proxy-github-script.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-proxy-github-script.md b/.github/workflows/smoke-proxy-github-script.md index e740a4ff1..d18b81754 100644 --- a/.github/workflows/smoke-proxy-github-script.md +++ b/.github/workflows/smoke-proxy-github-script.md @@ -46,6 +46,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" steps: # ── Build the gateway container image from source ────────────────── - name: Build MCP Gateway image diff --git a/.github/workflows/smoke-safeoutputs-discussions.lock.yml b/.github/workflows/smoke-safeoutputs-discussions.lock.yml index 1e20f90b3..f8535455e 100644 --- a/.github/workflows/smoke-safeoutputs-discussions.lock.yml +++ b/.github/workflows/smoke-safeoutputs-discussions.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"bc3dd6326daa87550a21c275e43b52b3029a76314ca7b2a66d542a289e4efcbb","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"5dcc0dfac683751b078b9704b22c2b99a09a7b804456bd8d27bbacc1b0284574","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -41,13 +41,13 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -104,7 +104,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -114,7 +114,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-discussions.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -124,15 +124,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -154,6 +154,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -164,8 +165,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -183,7 +184,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -219,21 +220,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_467e72e0ef16ef25_EOF' + cat << 'GH_AW_PROMPT_b2e04dfd3e43a47a_EOF' - GH_AW_PROMPT_467e72e0ef16ef25_EOF + GH_AW_PROMPT_b2e04dfd3e43a47a_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_467e72e0ef16ef25_EOF' + cat << 'GH_AW_PROMPT_b2e04dfd3e43a47a_EOF' Tools: add_comment(max:2), create_issue, create_discussion, update_discussion, close_discussion, missing_tool, missing_data, noop - GH_AW_PROMPT_467e72e0ef16ef25_EOF + GH_AW_PROMPT_b2e04dfd3e43a47a_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_467e72e0ef16ef25_EOF' + cat << 'GH_AW_PROMPT_b2e04dfd3e43a47a_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -262,14 +263,14 @@ jobs: {{/if}} - GH_AW_PROMPT_467e72e0ef16ef25_EOF + GH_AW_PROMPT_b2e04dfd3e43a47a_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_467e72e0ef16ef25_EOF' + cat << 'GH_AW_PROMPT_b2e04dfd3e43a47a_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-safeoutputs-discussions.md}} - GH_AW_PROMPT_467e72e0ef16ef25_EOF + GH_AW_PROMPT_b2e04dfd3e43a47a_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -357,6 +358,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -394,7 +396,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -404,7 +406,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-discussions.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -471,7 +473,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -487,24 +489,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_04a0655bb3fa9048_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_218e862365685c3b_EOF' {"add_comment":{"hide_older_comments":true,"max":2,"target":"triggering"},"close_discussion":{"max":1,"required_labels":["smoke-test"]},"create_discussion":{"category":"general","close_older_discussions":true,"expires":168,"fallback_to_issue":true,"labels":["smoke-test"],"max":1,"title_prefix":"[smoke-safeoutputs] "},"create_issue":{"close_older_issues":true,"expires":2,"labels":["smoke-test","automated"],"max":1,"title_prefix":"[smoke-safeoutputs] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"update_discussion":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_04a0655bb3fa9048_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_218e862365685c3b_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -814,11 +833,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_a2e565acb12dd8eb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_e8b81b43296ab9f8_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -864,7 +883,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_a2e565acb12dd8eb_EOF + GH_AW_MCP_CONFIG_e8b81b43296ab9f8_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -915,7 +934,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -934,7 +953,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1139,7 +1158,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1149,7 +1168,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-discussions.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1269,7 +1288,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1277,7 +1296,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-discussions.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1328,7 +1347,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1338,7 +1357,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Discussions" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-discussions.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-safeoutputs-discussions.md b/.github/workflows/smoke-safeoutputs-discussions.md index d7c5cf21d..1cba69d81 100644 --- a/.github/workflows/smoke-safeoutputs-discussions.md +++ b/.github/workflows/smoke-safeoutputs-discussions.md @@ -40,6 +40,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/.github/workflows/smoke-safeoutputs-issues.lock.yml b/.github/workflows/smoke-safeoutputs-issues.lock.yml index 02aa7470e..a4ad7631b 100644 --- a/.github/workflows/smoke-safeoutputs-issues.lock.yml +++ b/.github/workflows/smoke-safeoutputs-issues.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"f28810f3b6d30c45cbe5c86e7b1a2a88cbe50ac57f7b8fd020fd1b8e314d8ba4","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"ac76e2cd3b342859b95a7115dbe9cadb63d6d46428e7d58466cc70cdbd483f38","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -41,13 +41,13 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -104,7 +104,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -114,7 +114,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-issues.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -124,15 +124,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -154,6 +154,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -164,8 +165,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -183,7 +184,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -219,21 +220,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_5e92e71f44a72011_EOF' + cat << 'GH_AW_PROMPT_017dcbada43c0c10_EOF' - GH_AW_PROMPT_5e92e71f44a72011_EOF + GH_AW_PROMPT_017dcbada43c0c10_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_5e92e71f44a72011_EOF' + cat << 'GH_AW_PROMPT_017dcbada43c0c10_EOF' Tools: create_issue(max:3), close_issue, update_issue, assign_milestone, link_sub_issue, missing_tool, missing_data, noop - GH_AW_PROMPT_5e92e71f44a72011_EOF + GH_AW_PROMPT_017dcbada43c0c10_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_5e92e71f44a72011_EOF' + cat << 'GH_AW_PROMPT_017dcbada43c0c10_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -262,14 +263,14 @@ jobs: {{/if}} - GH_AW_PROMPT_5e92e71f44a72011_EOF + GH_AW_PROMPT_017dcbada43c0c10_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_5e92e71f44a72011_EOF' + cat << 'GH_AW_PROMPT_017dcbada43c0c10_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-safeoutputs-issues.md}} - GH_AW_PROMPT_5e92e71f44a72011_EOF + GH_AW_PROMPT_017dcbada43c0c10_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -357,6 +358,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -393,7 +395,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -403,7 +405,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-issues.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -470,7 +472,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -486,24 +488,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_b97dcf3fea2008f1_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_ce00d5d569eaa53d_EOF' {"assign_milestone":{"allowed":["v1.0"],"max":1},"close_issue":{"max":1,"required_labels":["smoke-test"],"required_title_prefix":"[smoke-safeoutputs]"},"create_issue":{"close_older_issues":true,"expires":2,"labels":["smoke-test","automated"],"max":3,"title_prefix":"[smoke-safeoutputs] "},"create_report_incomplete_issue":{},"link_sub_issue":{"max":1,"parent_title_prefix":"[smoke-safeoutputs]","sub_title_prefix":"[smoke-safeoutputs]"},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"update_issue":{"allow_body":true,"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_b97dcf3fea2008f1_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_ce00d5d569eaa53d_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -814,11 +833,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_8cf1b2468ee73b7d_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_9d0ec985d5506c6f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -864,7 +883,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_8cf1b2468ee73b7d_EOF + GH_AW_MCP_CONFIG_9d0ec985d5506c6f_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -915,7 +934,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -934,7 +953,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1137,7 +1156,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1147,7 +1166,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-issues.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1265,7 +1284,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1273,7 +1292,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-issues.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1321,7 +1340,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1331,7 +1350,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Issues" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-issues.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-safeoutputs-issues.md b/.github/workflows/smoke-safeoutputs-issues.md index 7e11325e3..5d1d5e35b 100644 --- a/.github/workflows/smoke-safeoutputs-issues.md +++ b/.github/workflows/smoke-safeoutputs-issues.md @@ -39,6 +39,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/.github/workflows/smoke-safeoutputs-labels.lock.yml b/.github/workflows/smoke-safeoutputs-labels.lock.yml index 9ea3dde02..aa0e498ee 100644 --- a/.github/workflows/smoke-safeoutputs-labels.lock.yml +++ b/.github/workflows/smoke-safeoutputs-labels.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"add6c4460404066dd42977376ffbeadeecdd855f4b4088f697ab382a56627e0d","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"1dc96b1c471abf7c1c2fca2f193f66d05bee31ec1ac7c84a24fa53318aa5565e","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -41,13 +41,13 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -104,7 +104,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -114,7 +114,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-labels.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -124,15 +124,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -154,6 +154,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -164,8 +165,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -183,7 +184,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -219,21 +220,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_fb10cb5e9900801e_EOF' + cat << 'GH_AW_PROMPT_f452dd185b1118c9_EOF' - GH_AW_PROMPT_fb10cb5e9900801e_EOF + GH_AW_PROMPT_f452dd185b1118c9_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_fb10cb5e9900801e_EOF' + cat << 'GH_AW_PROMPT_f452dd185b1118c9_EOF' Tools: create_issue, add_labels(max:2), remove_labels, missing_tool, missing_data, noop - GH_AW_PROMPT_fb10cb5e9900801e_EOF + GH_AW_PROMPT_f452dd185b1118c9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_fb10cb5e9900801e_EOF' + cat << 'GH_AW_PROMPT_f452dd185b1118c9_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -262,14 +263,14 @@ jobs: {{/if}} - GH_AW_PROMPT_fb10cb5e9900801e_EOF + GH_AW_PROMPT_f452dd185b1118c9_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_fb10cb5e9900801e_EOF' + cat << 'GH_AW_PROMPT_f452dd185b1118c9_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-safeoutputs-labels.md}} - GH_AW_PROMPT_fb10cb5e9900801e_EOF + GH_AW_PROMPT_f452dd185b1118c9_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -357,6 +358,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -393,7 +395,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -403,7 +405,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-labels.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -470,7 +472,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -486,24 +488,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_4d7003b8bcf0c56b_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_791658fd7970e461_EOF' {"add_labels":{"allowed":["smoke-test","verified"],"max":2,"target":"triggering"},"create_issue":{"close_older_issues":true,"expires":2,"labels":["smoke-test","automated"],"max":1,"title_prefix":"[smoke-safeoutputs] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"remove_labels":{"allowed":["smoke-test"],"max":1,"target":"triggering"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_4d7003b8bcf0c56b_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_791658fd7970e461_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -745,11 +764,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_69fb8581d98f5368_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_e2f03d1f5ae97b1a_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -795,7 +814,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_69fb8581d98f5368_EOF + GH_AW_MCP_CONFIG_e2f03d1f5ae97b1a_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -846,7 +865,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -865,7 +884,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1069,7 +1088,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1079,7 +1098,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-labels.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1197,7 +1216,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1205,7 +1224,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-labels.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1253,7 +1272,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1263,7 +1282,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Labels" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-labels.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-safeoutputs-labels.md b/.github/workflows/smoke-safeoutputs-labels.md index f893ecb27..eba1878cc 100644 --- a/.github/workflows/smoke-safeoutputs-labels.md +++ b/.github/workflows/smoke-safeoutputs-labels.md @@ -39,6 +39,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/.github/workflows/smoke-safeoutputs-prs.lock.yml b/.github/workflows/smoke-safeoutputs-prs.lock.yml index 408498f45..c00892cca 100644 --- a/.github/workflows/smoke-safeoutputs-prs.lock.yml +++ b/.github/workflows/smoke-safeoutputs-prs.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"25444464feaf0c8d24f2716c6e12bad2768b492e297f0070effcd4a524e594e2","compiler_version":"v0.75.4","agent_id":"copilot"} -# 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/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"9e93eaeb3ca8cbdd2465b8f737fb1f62b0a8307b05c1e1b8f343216821b49ca3","compiler_version":"v0.76.1","agent_id":"copilot"} +# 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/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -42,13 +42,13 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -105,7 +105,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -115,7 +115,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-prs.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -125,15 +125,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -155,6 +155,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -165,8 +166,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -184,7 +185,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -220,25 +221,25 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_d64bda1d51433455_EOF' + cat << 'GH_AW_PROMPT_ac674c06be638703_EOF' - GH_AW_PROMPT_d64bda1d51433455_EOF + GH_AW_PROMPT_ac674c06be638703_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_d64bda1d51433455_EOF' + cat << 'GH_AW_PROMPT_ac674c06be638703_EOF' Tools: create_issue, create_pull_request, close_pull_request, update_pull_request, mark_pull_request_as_ready_for_review, add_reviewer, push_to_pull_request_branch, missing_tool, missing_data, noop - GH_AW_PROMPT_d64bda1d51433455_EOF + GH_AW_PROMPT_ac674c06be638703_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md" - cat << 'GH_AW_PROMPT_d64bda1d51433455_EOF' + cat << 'GH_AW_PROMPT_ac674c06be638703_EOF' - GH_AW_PROMPT_d64bda1d51433455_EOF + GH_AW_PROMPT_ac674c06be638703_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_d64bda1d51433455_EOF' + cat << 'GH_AW_PROMPT_ac674c06be638703_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -267,14 +268,14 @@ jobs: {{/if}} - GH_AW_PROMPT_d64bda1d51433455_EOF + GH_AW_PROMPT_ac674c06be638703_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_d64bda1d51433455_EOF' + cat << 'GH_AW_PROMPT_ac674c06be638703_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-safeoutputs-prs.md}} - GH_AW_PROMPT_d64bda1d51433455_EOF + GH_AW_PROMPT_ac674c06be638703_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -362,6 +363,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -398,7 +400,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -408,7 +410,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-prs.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -475,7 +477,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -491,24 +493,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_9c7a53e725d32d1a_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_823fc8636faf58b5_EOF' {"add_reviewer":{"allowed":["copilot"],"max":1},"close_pull_request":{"max":1,"required_labels":["smoke-test"],"required_title_prefix":"[smoke-safeoutputs]"},"create_issue":{"close_older_issues":true,"expires":2,"labels":["smoke-test","automated"],"max":1,"title_prefix":"[smoke-safeoutputs] "},"create_pull_request":{"draft":true,"labels":["smoke-test"],"max":1,"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":"[smoke-safeoutputs] "},"create_report_incomplete_issue":{},"mark_pull_request_as_ready_for_review":{"max":1,"required_labels":["smoke-test"]},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_to_pull_request_branch":{"if_no_changes":"warn","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"],"target":"triggering","title_prefix":"[smoke-safeoutputs]"},"report_incomplete":{},"update_pull_request":{"allow_body":false,"allow_title":true,"max":1,"update_branch":false}} - GH_AW_SAFE_OUTPUTS_CONFIG_9c7a53e725d32d1a_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_823fc8636faf58b5_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -874,11 +893,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_86716361915a1a25_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_edaabaecd2fe72eb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -924,7 +943,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_86716361915a1a25_EOF + GH_AW_MCP_CONFIG_edaabaecd2fe72eb_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -985,7 +1004,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -1004,7 +1023,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1210,7 +1229,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1220,7 +1239,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-prs.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1340,7 +1359,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1348,7 +1367,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-prs.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1401,7 +1420,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1411,7 +1430,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs PRs" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-prs.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-safeoutputs-prs.md b/.github/workflows/smoke-safeoutputs-prs.md index 073b7d2c1..931768e07 100644 --- a/.github/workflows/smoke-safeoutputs-prs.md +++ b/.github/workflows/smoke-safeoutputs-prs.md @@ -41,6 +41,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/.github/workflows/smoke-safeoutputs-reviews.lock.yml b/.github/workflows/smoke-safeoutputs-reviews.lock.yml index 09991e0b6..d91283351 100644 --- a/.github/workflows/smoke-safeoutputs-reviews.lock.yml +++ b/.github/workflows/smoke-safeoutputs-reviews.lock.yml @@ -1,5 +1,5 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"0e991fd111d12295587bca974976960b656f9e8a9246f22d96670bfe4b089bd5","compiler_version":"v0.75.4","agent_id":"copilot"} -# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"9f050961da586148d135e113d8bb025185cdf2b8","version":"v0.75.4"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.53"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.18"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"95501fad99ea64ae2e7b8e20f5d1b0778ea2b45e916965f5fcc60a95adde980c","compiler_version":"v0.76.1","agent_id":"copilot"} +# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"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/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"46d564922b082d0db93244972e8005ea6904ee5f","version":"v0.76.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.55"},{"image":"ghcr.io/github/gh-aw-mcpg:latest"},{"image":"ghcr.io/github/github-mcp-server:v1.0.4","digest":"sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4"},{"image":"node:lts-alpine","digest":"sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b","pinned_image":"node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b"}]} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -14,7 +14,7 @@ # \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \ # \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/ # -# This file was automatically generated by gh-aw (v0.75.4). DO NOT EDIT. +# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT. # # To update this file, edit the corresponding .md file and run: # gh aw compile @@ -41,13 +41,13 @@ # - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 # - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 # - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 -# - github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 +# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 # # Container images used: -# - ghcr.io/github/gh-aw-firewall/agent:0.25.53 -# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 -# - ghcr.io/github/gh-aw-firewall/squid:0.25.53 -# - ghcr.io/github/gh-aw-mcpg:v0.3.18 +# - ghcr.io/github/gh-aw-firewall/agent:0.25.55 +# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 +# - ghcr.io/github/gh-aw-firewall/squid:0.25.55 +# - ghcr.io/github/gh-aw-mcpg:latest # - ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 # - node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b @@ -104,7 +104,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -114,7 +114,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-reviews.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info id: generate_aw_info @@ -124,15 +124,15 @@ jobs: GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }} GH_AW_INFO_VERSION: "1.0.52" GH_AW_INFO_AGENT_VERSION: "1.0.52" - GH_AW_INFO_CLI_VERSION: "v0.75.4" + GH_AW_INFO_CLI_VERSION: "v0.76.1" GH_AW_INFO_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" GH_AW_INFO_STAGED: "false" GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","github","github.com"]' GH_AW_INFO_FIREWALL_ENABLED: "true" - GH_AW_INFO_AWF_VERSION: "v0.25.53" - GH_AW_INFO_AWMG_VERSION: "" + GH_AW_INFO_AWF_VERSION: "v0.25.55" + GH_AW_INFO_AWMG_VERSION: "latest" GH_AW_INFO_FIREWALL_TYPE: "squid" GH_AW_COMPILED_STRICT: "false" uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -154,6 +154,7 @@ jobs: sparse-checkout: | .github .agents + .antigravity .claude .codex .crush @@ -164,8 +165,8 @@ jobs: fetch-depth: 1 - name: Save agent config folders for base branch restoration env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" # poutine:ignore untrusted_checkout_exec run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh" - name: Check workflow lock file @@ -183,7 +184,7 @@ jobs: - name: Check compile-agentic version uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_COMPILED_VERSION: "v0.75.4" + GH_AW_COMPILED_VERSION: "v0.76.1" with: script: | const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs'); @@ -219,21 +220,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_9bf81b1df275df81_EOF' + cat << 'GH_AW_PROMPT_4f071cd6e6caf01b_EOF' - GH_AW_PROMPT_9bf81b1df275df81_EOF + GH_AW_PROMPT_4f071cd6e6caf01b_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/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_9bf81b1df275df81_EOF' + cat << 'GH_AW_PROMPT_4f071cd6e6caf01b_EOF' Tools: create_issue, create_pull_request_review_comment(max:2), submit_pull_request_review, reply_to_pull_request_review_comment(max:2), resolve_pull_request_review_thread(max:2), missing_tool, missing_data, noop - GH_AW_PROMPT_9bf81b1df275df81_EOF + GH_AW_PROMPT_4f071cd6e6caf01b_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_9bf81b1df275df81_EOF' + cat << 'GH_AW_PROMPT_4f071cd6e6caf01b_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -262,14 +263,14 @@ jobs: {{/if}} - GH_AW_PROMPT_9bf81b1df275df81_EOF + GH_AW_PROMPT_4f071cd6e6caf01b_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_9bf81b1df275df81_EOF' + cat << 'GH_AW_PROMPT_4f071cd6e6caf01b_EOF' {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/github-mcp-app.md}} {{#runtime-import .github/workflows/smoke-safeoutputs-reviews.md}} - GH_AW_PROMPT_9bf81b1df275df81_EOF + GH_AW_PROMPT_4f071cd6e6caf01b_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -357,6 +358,7 @@ jobs: /tmp/gh-aw/github_rate_limits.jsonl /tmp/gh-aw/base /tmp/gh-aw/.github/agents + /tmp/gh-aw/.github/skills if-no-files-found: ignore retention-days: 1 @@ -393,7 +395,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -403,7 +405,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-reviews.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Set runtime paths id: set-runtime-paths @@ -470,7 +472,7 @@ jobs: env: GH_HOST: github.com - name: Install AWF binary - run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.53 + run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.25.55 - name: Parse integrity filter lists id: parse-guard-vars env: @@ -486,24 +488,41 @@ jobs: - name: Restore agent config folders from base branch if: steps.checkout-pr.outcome == 'success' env: - GH_AW_AGENT_FOLDERS: ".agents .claude .codex .crush .gemini .github .opencode .pi" - GH_AW_AGENT_FILES: ".crush.json AGENTS.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" + GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi" + GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh" - name: Restore inline sub-agents from activation artifact env: GH_AW_SUB_AGENT_DIR: ".github/agents" GH_AW_SUB_AGENT_EXT: ".agent.md" run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh" + - name: Restore inline skills from activation artifact + env: + 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.25.53 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.53 ghcr.io/github/gh-aw-firewall/squid:0.25.53 ghcr.io/github/gh-aw-mcpg:v0.3.18 ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.55 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.55 ghcr.io/github/gh-aw-firewall/squid:0.25.55 ghcr.io/github/gh-aw-mcpg:latest ghcr.io/github/github-mcp-server:v1.0.4@sha256:e3816a476a977cfb836e7d221510011436c654d11861db66ecfd826601aba6a4 node:lts-alpine@sha256:01743339035a5c3c11a373cd7c83aeab6ed1457b55da6a69e014a95ac4e4700b + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" - 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_5303f3c98e6699fa_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_bb7beab7b2c60bf1_EOF' {"create_issue":{"close_older_issues":true,"expires":2,"labels":["smoke-test","automated"],"max":1,"title_prefix":"[smoke-safeoutputs] "},"create_pull_request_review_comment":{"max":2,"side":"RIGHT","target":"triggering"},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"reply_to_pull_request_review_comment":{"max":2},"report_incomplete":{},"resolve_pull_request_review_thread":{"max":2},"submit_pull_request_review":{"footer":"if-body","max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_5303f3c98e6699fa_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_bb7beab7b2c60bf1_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -795,11 +814,11 @@ 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.18' + 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:latest' mkdir -p /home/runner/.copilot GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_34b6d0ddf968c425_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_acf4111ca2afcceb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -845,7 +864,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_34b6d0ddf968c425_EOF + GH_AW_MCP_CONFIG_acf4111ca2afcceb_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true @@ -896,7 +915,7 @@ 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.25.53/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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.3":["copilot/gpt-5.3*","openai/gpt-5.3*"],"gpt-5.4":["copilot/gpt-5.4*","openai/gpt-5.4*"],"haiku":["copilot/*haiku*","anthropic/*haiku*"],"large":["sonnet","gpt-5-pro","gpt-5","gemini-pro"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.53"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" + printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.55/awf-config.schema.json","network":{"allowDomains":["*.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","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","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,"maxEffectiveTokens":25000000,"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*","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-4.1":["copilot/gpt-4.1*","openai/gpt-4.1*"],"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"],"mini":["haiku","gpt-5-mini","gpt-5-nano","gemini-flash-lite"],"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"],"sonnet":["copilot/*sonnet*","anthropic/*sonnet*"],"sonnet-6x":["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.25.55"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json" cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="" if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then @@ -915,7 +934,7 @@ jobs: 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_VERSION: v0.75.4 + GH_AW_VERSION: v0.76.1 GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows @@ -1119,7 +1138,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1129,7 +1148,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-reviews.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output @@ -1247,7 +1266,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1255,7 +1274,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-reviews.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow id: check_membership @@ -1303,7 +1322,7 @@ jobs: steps: - name: Setup Scripts id: setup - uses: github/gh-aw-actions/setup@9f050961da586148d135e113d8bb025185cdf2b8 # v0.75.4 + uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1 with: destination: ${{ runner.temp }}/gh-aw/actions job-name: ${{ github.job }} @@ -1313,7 +1332,7 @@ jobs: GH_AW_SETUP_WORKFLOW_NAME: "Smoke Safe-Outputs Reviews" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/smoke-safeoutputs-reviews.lock.yml@${{ github.ref }} GH_AW_INFO_VERSION: "1.0.52" - GH_AW_INFO_AWF_VERSION: "v0.25.53" + GH_AW_INFO_AWF_VERSION: "v0.25.55" GH_AW_INFO_ENGINE_ID: "copilot" - name: Download agent output artifact id: download-agent-output diff --git a/.github/workflows/smoke-safeoutputs-reviews.md b/.github/workflows/smoke-safeoutputs-reviews.md index f23864f7d..7966ec875 100644 --- a/.github/workflows/smoke-safeoutputs-reviews.md +++ b/.github/workflows/smoke-safeoutputs-reviews.md @@ -39,6 +39,7 @@ tools: sandbox: mcp: container: "ghcr.io/github/gh-aw-mcpg" + version: "latest" safe-outputs: threat-detection: enabled: false diff --git a/AGENTS.md b/AGENTS.md index b42c64080..8dcf3c499 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -67,7 +67,7 @@ Quick reference for AI agents working with MCP Gateway (Go-based MCP proxy serve ```toml [gateway] port = 3000 -api_key = "your-api-key" +agent_id = "your-agent-id" payload_dir = "/tmp/jq-payloads" # Optional: directory for large payload storage (must be absolute) [servers.github] @@ -392,7 +392,7 @@ DEBUG_COLORS=0 DEBUG=* ./awmg --config config.toml - `ACTIONS_ID_TOKEN_REQUEST_TOKEN` - GitHub Actions OIDC request token; required for `github-oidc` auth type - `MCP_GATEWAY_PORT` - Used by environment validation (`--validate-env`) for container port-mapping checks (validated 1-65535); does not override the gateway listen address - `MCP_GATEWAY_DOMAIN` - Used by environment validation (`--validate-env`) and containerized startup checks; to set config values use `gateway.domain` (or `"${MCP_GATEWAY_DOMAIN}"` in JSON stdin config) -- `MCP_GATEWAY_API_KEY` - Used by environment validation (`--validate-env`) and containerized startup checks; to enable auth set `gateway.apiKey` (commonly `"${MCP_GATEWAY_API_KEY}"` in JSON stdin config) +- `MCP_GATEWAY_AGENT_ID` - Used by environment validation (`--validate-env`) and containerized startup checks; to enable auth set `gateway.agentId` (commonly `"${MCP_GATEWAY_AGENT_ID}"` in JSON stdin config) - `DEBUG` - Enable debug logging (e.g., `DEBUG=*`, `DEBUG=server:*,launcher:*`) - `DEBUG_COLORS` - Control colored output (0 to disable, auto-disabled when piping) - `MCP_GATEWAY_LOG_DIR` - Log file directory (sets default for `--log-dir` flag, default: `/tmp/gh-aw/mcp-logs`) @@ -494,8 +494,8 @@ DEBUG_COLORS=0 DEBUG=* ./awmg --config config.toml ## Security Notes -- **Auth**: `Authorization: ` header (plain API key per spec 7.1, NOT Bearer scheme) -- **Sessions**: Session ID extracted from Authorization header value +- **Auth**: `Authorization: ` header (plain value per spec 7.1, NOT Bearer scheme) +- **Sessions**: Session ID extracted from `X-Agent-ID` (preferred) or Authorization header value - **Stdio servers**: Containerized execution only (no direct command support) - **mTLS**: Mutual TLS can be enabled with `--tls-cert`, `--tls-key`, and `--tls-ca` flags (or corresponding env vars) to require client certificates for all connections - **HMAC request signing**: Set `--hmac-secret` (or `MCP_GATEWAY_HMAC_SECRET`) to require HMAC-SHA256 signed requests; protects against replay attacks using `X-MCP-Timestamp`, `X-MCP-Nonce`, and `X-MCP-Signature` headers diff --git a/README.md b/README.md index 75ee35ac2..5ce5a04b1 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This gateway is used with [GitHub Agentic Workflows](https://github.com/github/g ```json { "gateway": { - "apiKey": "${MCP_GATEWAY_API_KEY}" + "agentId": "${MCP_GATEWAY_AGENT_ID}" }, "mcpServers": { "github": { @@ -36,7 +36,7 @@ This gateway is used with [GitHub Agentic Workflows](https://github.com/github/g docker run --rm -i \ -e MCP_GATEWAY_PORT=8000 \ -e MCP_GATEWAY_DOMAIN=localhost \ - -e MCP_GATEWAY_API_KEY=your-secret-key \ + -e MCP_GATEWAY_AGENT_ID=your-agent-id \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /path/to/logs:/tmp/gh-aw/mcp-logs \ -p 8000:8000 \ @@ -181,7 +181,8 @@ Key configuration fields (gateway-level under `[gateway]` in TOML / `"gateway"` | Field | Description | |-------|-------------| -| `api_key` / `apiKey` | API key for gateway authentication (MCP spec 7.1) | +| `agent_id` / `agentId` | Agent/session identifier used for routing and optional auth matching | +| `api_key` / `apiKey` | Deprecated alias for `agent_id` / `agentId` (accepted with warnings) | | `port` | Listen port | | `payload_dir` / `payloadDir` | Directory for large payload storage (must be absolute path) | | `payload_size_threshold` / `payloadSizeThreshold` | Size threshold in bytes for payload storage (default: `524288`) | @@ -215,7 +216,7 @@ For the full gateway field list (including rate limiting, tracing, keepalive, an **Routing**: Routed mode (`/mcp/{serverID}`) exposes each backend at its own endpoint. Unified mode (`/mcp`) routes to all configured servers through a single endpoint. -**Security**: WASM-based DIFC guards enforce secrecy and integrity labels per request. Guards are loaded from `MCP_GATEWAY_WASM_GUARDS_DIR` and assigned per-server. Authentication uses plain API keys per MCP spec 7.1 (`Authorization: `). +**Security**: WASM-based DIFC guards enforce secrecy and integrity labels per request. Guards are loaded from `MCP_GATEWAY_WASM_GUARDS_DIR` and assigned per-server. Authentication uses the configured agent identifier value per MCP spec 7.1 (`Authorization: `), and session routing can also use `X-Agent-ID`. **Logging**: Per-server log files (`{serverID}.log`) and unified `mcp-gateway.log` use bracketed UTC ISO-8601 timestamps with milliseconds (`[YYYY-MM-DDTHH:mm:ss.SSSZ]`). Machine-readable `rpc-messages.jsonl` records include required `timestamp`, `event` (`snake_case`), and `_schema` fields; RPC events use `_schema: "rpc-message/v2"` with `event` values `rpc_request`/`rpc_response`, and DIFC filter records use `_schema: "difc-filtered/v2"` with `event: "difc_filtered"`. Markdown workflow previews (`gateway.md`) and the wazero cache (`/wazero-cache`, a sibling of `--log-dir` by default) are also produced. diff --git a/config.example.toml b/config.example.toml index 7a9f9b9d2..f04a32faa 100644 --- a/config.example.toml +++ b/config.example.toml @@ -13,10 +13,10 @@ # This field is stored for metadata purposes only. Valid range: 1-65535 port = 3000 -# API key for authentication (optional) -# When set, clients must provide this key in the Authorization header -# Format: Authorization: -api_key = "" +# Agent ID for routing and optional authentication matching (optional) +# When set, clients must provide this agent ID in the Authorization header +# Format: Authorization: +agent_id = "" # Domain name for the gateway (optional) # Used for CORS and other domain-specific features diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index a996fbc76..77b23f016 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -22,7 +22,7 @@ TOML configuration requires `command = "docker"` for stdio-based MCP servers to ```toml [gateway] port = 3000 -api_key = "your-api-key" +agent_id = "your-agent-id" [servers.github] command = "docker" @@ -84,7 +84,7 @@ JSON configuration is the primary format for containerized deployments. Pass via }, "gateway": { "port": 8080, - "apiKey": "${MCP_GATEWAY_API_KEY}", + "agentId": "${MCP_GATEWAY_AGENT_ID}", "domain": "localhost" } } @@ -411,7 +411,7 @@ The `customSchemas` top-level field allows you to define custom server types bey - **TOML format**: - Uses `command` and `args` fields directly (e.g., `command = "docker"`) - Variable expansion with `${VAR_NAME}` is only supported in `[gateway.opentelemetry]` and legacy `[gateway.tracing]` fields - - Server `env` values, `url`, `args`, `gateway.api_key`, and other non-tracing fields are not expanded + - Server `env` values, `url`, `args`, `gateway.agent_id`, and other non-tracing fields are not expanded - For host environment passthrough to container `env`, use an empty string `""` value - **Common rules** (both formats): - Empty/"local" type automatically normalized to "stdio" @@ -427,7 +427,8 @@ The `customSchemas` top-level field allows you to define custom server types bey | Field | Description | Default | |-------|-------------|---------| | `port` | Validated and stored for metadata purposes only. The actual listen address is always set by the `--listen` CLI flag (default `127.0.0.1:3000`). | `3000` (informational only) | -| `apiKey` | API key for authentication | (disabled) | +| `agentId` | Agent/session identifier used for routing and optional auth matching | (disabled) | +| `apiKey` | Deprecated alias for `agentId` (accepted for backward compatibility) | (deprecated) | | `domain` | Gateway domain (`"localhost"`, `"host.docker.internal"`, or `"${VAR}"`) | (unset) | | `startupTimeout` | Seconds to wait for backend startup | `30` | | `toolTimeout` | Maximum seconds for a single tool call, enforced as a context deadline on all backend requests (stdio and HTTP) | `60` | diff --git a/docs/ENVIRONMENT_VARIABLES.md b/docs/ENVIRONMENT_VARIABLES.md index 16f4da8d8..c753b12f9 100644 --- a/docs/ENVIRONMENT_VARIABLES.md +++ b/docs/ENVIRONMENT_VARIABLES.md @@ -10,7 +10,8 @@ When running in a container (`run_containerized.sh`), these variables **must** b |----------|-------------|---------| | `MCP_GATEWAY_PORT` | Port used by `run.sh`/`run_containerized.sh` to build the `--listen` address; also read by `awmg --validate-env` for port-mapping checks | `8000` | | `MCP_GATEWAY_DOMAIN` | The domain name for the gateway | `localhost` | -| `MCP_GATEWAY_API_KEY` | API key checked by `run_containerized.sh` as a deployment gate; must be referenced in your JSON config via `"${MCP_GATEWAY_API_KEY}"` to enable authentication | `your-secret-key` | +| `MCP_GATEWAY_AGENT_ID` | Agent/session identifier checked by `run_containerized.sh` as a deployment gate; reference it in JSON config via `"${MCP_GATEWAY_AGENT_ID}"` to enable auth matching | `your-agent-id` | +| `MCP_GATEWAY_API_KEY` | Deprecated alias for `MCP_GATEWAY_AGENT_ID` (still accepted with warning) | (deprecated) | ## Optional (Non-Containerized Mode) @@ -20,7 +21,8 @@ When running locally (`run.sh`), these variables are optional (warnings shown if |----------|-------------|---------| | `MCP_GATEWAY_PORT` | Port used by `run.sh` to build the `--listen` address; also read by `awmg --validate-env` for port-mapping checks | `8000` | | `MCP_GATEWAY_DOMAIN` | Gateway domain | `localhost` | -| `MCP_GATEWAY_API_KEY` | Informational only — not read directly by the binary; must be referenced in your config via `"${MCP_GATEWAY_API_KEY}"` to enable authentication | (disabled) | +| `MCP_GATEWAY_AGENT_ID` | Informational only — not read directly by the binary; must be referenced in your config via `"${MCP_GATEWAY_AGENT_ID}"` to enable auth matching | (disabled) | +| `MCP_GATEWAY_API_KEY` | Deprecated alias for `MCP_GATEWAY_AGENT_ID` (still accepted with warning) | (deprecated) | | `MCP_GATEWAY_LOG_DIR` | Log file directory (sets default for `--log-dir` flag) | `/tmp/gh-aw/mcp-logs` | | `MCP_GATEWAY_WASM_CACHE_DIR` | Disk-backed wazero compilation cache directory (sets default for `--wasm-cache-dir`; defaults to `/wazero-cache`, a sibling of the log directory) | `/tmp/gh-aw/wazero-cache` | | `MCP_GATEWAY_PAYLOAD_DIR` | Large payload storage directory (sets default for `--payload-dir` flag). Must be an absolute path. | `/tmp/jq-payloads` | diff --git a/example-http-config.json b/example-http-config.json index 5e562e8ef..930480bcb 100644 --- a/example-http-config.json +++ b/example-http-config.json @@ -18,6 +18,6 @@ "gateway": { "port": 3001, "domain": "localhost", - "apiKey": "gateway-api-key" + "agentId": "gateway-agent-id" } } diff --git a/internal/auth/header.go b/internal/auth/header.go index 01a122c2a..a95f93d8a 100644 --- a/internal/auth/header.go +++ b/internal/auth/header.go @@ -6,7 +6,7 @@ // without any scheme prefix (e.g., NOT "Bearer "). // // The package provides both full parsing with error handling (ParseAuthHeader) -// and convenience methods for specific use cases (ExtractAgentID, ValidateAPIKey). +// and convenience methods for specific use cases (ExtractAgentID, ValidateAgentID). // // Usage Guidelines: // @@ -16,7 +16,7 @@ // - Use ExtractAgentID() when you only need the agent ID and want automatic // fallback to "default" instead of error handling. // -// - Use ValidateAPIKey() to check if a provided key matches the expected value. +// - Use ValidateAgentID() to check if a provided identifier matches the expected value. // Automatically handles the case where authentication is disabled (no expected key). // // Example: @@ -26,8 +26,8 @@ // if err != nil { // return err // } -// if !auth.ValidateAPIKey(apiKey, expectedKey) { -// return errors.New("invalid API key") +// if !auth.ValidateAgentID(apiKey, expectedKey) { +// return errors.New("invalid agent ID") // } // // // Extract agent ID only (for context, not authentication) @@ -99,26 +99,31 @@ func ParseAuthHeader(authHeader string) (apiKey string, agentID string, error er // Per MCP spec 7.1: Authorization header contains API key directly // Use the entire header value as both API key and agent/session ID - log.Print("Using plain API key format (MCP spec 7.1)") + log.Print("Using plain agent ID format (MCP spec 7.1)") return authHeader, authHeader, nil } -// ValidateAPIKey checks if the provided API key matches the expected key. +// ValidateAgentID checks if the provided agent identifier matches the expected value. // Returns true if they match, false otherwise. -func ValidateAPIKey(provided, expected string) bool { - log.Printf("Validating API key: expected_configured=%t", expected != "") +func ValidateAgentID(provided, expected string) bool { + log.Printf("Validating agent ID: expected_configured=%t", expected != "") if expected == "" { - // No API key configured, authentication is disabled - log.Print("No API key configured, authentication disabled") + // No agent ID configured, authentication is disabled + log.Print("No agent ID configured, authentication disabled") return true } matches := provided == expected - log.Printf("API key validation result: matches=%t", matches) + log.Printf("Agent ID validation result: matches=%t", matches) return matches } +// ValidateAPIKey is a deprecated alias for ValidateAgentID. +func ValidateAPIKey(provided, expected string) bool { + return ValidateAgentID(provided, expected) +} + // ExtractAgentID extracts the agent ID from an Authorization header. // This is a convenience wrapper around ParseAuthHeader that only returns the agent ID. // Returns "default" if the header is empty or cannot be parsed. @@ -169,10 +174,25 @@ func ExtractSessionID(authHeader string) string { } // Plain format (per spec 7.1 - API key is session ID) - log.Print("Using plain API key as session ID") + log.Print("Using plain agent ID as session ID") return authHeader } +// ExtractSessionIDFromHeaders extracts session ID from X-Agent-ID and Authorization. +// X-Agent-ID takes precedence when present, otherwise Authorization is used. +func ExtractSessionIDFromHeaders(xAgentID, authHeader string) string { + if xAgentID != "" { + if IsMalformedHeader(xAgentID) { + return "" + } + return xAgentID + } + if IsMalformedHeader(authHeader) { + return "" + } + return ExtractSessionID(authHeader) +} + // IsMalformedHeader returns true if the header value contains characters // that are not valid in HTTP header values per RFC 7230: null bytes, control // characters below 0x20 (except horizontal tab 0x09), or DEL (0x7F). @@ -190,12 +210,12 @@ func IsMalformedHeader(header string) bool { // Per spec §7.3, the gateway SHOULD generate a random API key on startup // if none is provided. Returns a 32-byte hex-encoded string (64 chars). func GenerateRandomAPIKey() (string, error) { - logAPIKey.Print("Generating random API key") + logAPIKey.Print("Generating random agent ID") key, err := strutil.RandomHex(32) if err != nil { - logAPIKey.Printf("Random API key generation failed: %v", err) - return "", fmt.Errorf("failed to generate random API key: %w", err) + logAPIKey.Printf("Random agent ID generation failed: %v", err) + return "", fmt.Errorf("failed to generate random agent ID: %w", err) } - logAPIKey.Print("Random API key generated successfully") + logAPIKey.Print("Random agent ID generated successfully") return key, nil } diff --git a/internal/auth/header_test.go b/internal/auth/header_test.go index e3a88d860..65e8113f0 100644 --- a/internal/auth/header_test.go +++ b/internal/auth/header_test.go @@ -256,7 +256,7 @@ func TestParseAuthHeader(t *testing.T) { } } -func TestValidateAPIKey(t *testing.T) { +func TestValidateAgentID(t *testing.T) { assert := assert.New(t) tests := []struct { @@ -317,12 +317,17 @@ func TestValidateAPIKey(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := ValidateAPIKey(tt.provided, tt.expected) + got := ValidateAgentID(tt.provided, tt.expected) assert.Equal(tt.want, got) }) } } +func TestValidateAPIKeyAlias(t *testing.T) { + assert.True(t, ValidateAPIKey("same", "same")) + assert.False(t, ValidateAPIKey("a", "b")) +} + func TestExtractAgentID(t *testing.T) { assert := assert.New(t) @@ -444,6 +449,28 @@ func TestExtractSessionID(t *testing.T) { } } +func TestExtractSessionIDFromHeaders(t *testing.T) { + t.Run("X-Agent-ID takes precedence over Authorization", func(t *testing.T) { + got := ExtractSessionIDFromHeaders("agent-explicit", "auth-token") + assert.Equal(t, "agent-explicit", got) + }) + + t.Run("falls back to Authorization when X-Agent-ID missing", func(t *testing.T) { + got := ExtractSessionIDFromHeaders("", "auth-token") + assert.Equal(t, "auth-token", got) + }) + + t.Run("malformed X-Agent-ID returns empty", func(t *testing.T) { + got := ExtractSessionIDFromHeaders("bad\x00id", "auth-token") + assert.Equal(t, "", got) + }) + + t.Run("malformed Authorization returns empty when X-Agent-ID missing", func(t *testing.T) { + got := ExtractSessionIDFromHeaders("", "bad\x00token") + assert.Equal(t, "", got) + }) +} + func TestStripAuthScheme(t *testing.T) { assert := assert.New(t) diff --git a/internal/cmd/output.go b/internal/cmd/output.go index 5332fb42e..a8d9dcf6e 100644 --- a/internal/cmd/output.go +++ b/internal/cmd/output.go @@ -47,11 +47,11 @@ func writeGatewayConfig(cfg *config.Config, listenAddr, mode string, tlsEnabled debugLog.Printf("Resolved gateway address: host=%s, port=%s", host, port) - // Extract API key from gateway config (per spec section 7.1) - apiKey := cfg.GetAPIKey() - debugLog.Printf("Gateway config: auth_enabled=%v", apiKey != "") + // Extract agent ID from gateway config (per spec section 7.1) + agentID := cfg.GetAgentID() + debugLog.Printf("Gateway config: auth_enabled=%v", agentID != "") - debugLog.Printf("Gateway auth: apiKeyConfigured=%v", apiKey != "") + debugLog.Printf("Gateway auth: agentIDConfigured=%v", agentID != "") // Build output configuration outputConfig := map[string]interface{}{ @@ -82,9 +82,9 @@ func writeGatewayConfig(cfg *config.Config, listenAddr, mode string, tlsEnabled // Add auth headers per MCP Gateway Specification Section 5.4 // Authorization header contains API key directly (not Bearer scheme per spec 7.1) - if apiKey != "" { + if agentID != "" { serverConfig["headers"] = map[string]string{ - "Authorization": apiKey, + "Authorization": agentID, } } diff --git a/internal/cmd/root.go b/internal/cmd/root.go index e5be11795..9dc0da24e 100644 --- a/internal/cmd/root.go +++ b/internal/cmd/root.go @@ -270,16 +270,17 @@ func run(cmd *cobra.Command, args []string) error { debugLog.Printf("Server mode: %s, guards mode: %s", mode, cfg.DIFCMode) - // Per spec §7.3: generate a random API key on startup if none is configured. - // The generated key is set in the config so it propagates to both the HTTP + // Per spec §7.3: generate a random agent identifier on startup if none is configured. + // The generated value is set in the config so it propagates to both the HTTP // server authentication and the stdout configuration output (spec §5.4). - if cfg.GetAPIKey() == "" { + if cfg.GetAgentID() == "" { randomKey, err := auth.GenerateRandomAPIKey() if err != nil { - return fmt.Errorf("failed to generate random API key: %w", err) + return fmt.Errorf("failed to generate random agent ID: %w", err) } + cfg.Gateway.AgentID = randomKey cfg.Gateway.APIKey = randomKey - logger.StartupInfo("No API key configured — generated temporary random API key (spec §7.3)") + logger.StartupInfo("No agent ID configured — generated temporary random agent ID (spec §7.3)") } // Apply tracing flags: CLI flags and env var overrides take precedence over config values. @@ -363,18 +364,18 @@ func run(cmd *cobra.Command, args []string) error { logger.StartupInfo("Starting MCPG in ROUTED mode on %s", listenAddr) logger.StartupInfo("Routes: /mcp/ where is one of: %v", unifiedServer.GetServerIDs()) - // Extract API key from gateway config (spec 7.1) - apiKey := cfg.GetAPIKey() + // Extract agent ID from gateway config (spec 7.1) + agentID := cfg.GetAgentID() - httpServer = server.CreateHTTPServerForRoutedMode(listenAddr, unifiedServer, apiKey, hmacSecret) + httpServer = server.CreateHTTPServerForRoutedMode(listenAddr, unifiedServer, agentID, hmacSecret) } else { logger.StartupInfo("Starting MCPG in UNIFIED mode on %s", listenAddr) logger.StartupInfo("Endpoint: /mcp") - // Extract API key from gateway config (spec 7.1) - apiKey := cfg.GetAPIKey() + // Extract agent ID from gateway config (spec 7.1) + agentID := cfg.GetAgentID() - httpServer = server.CreateHTTPServerForMCP(listenAddr, unifiedServer, apiKey, hmacSecret) + httpServer = server.CreateHTTPServerForMCP(listenAddr, unifiedServer, agentID, hmacSecret) } // Set BaseContext so every incoming request inherits the startup context, // which carries the configured W3C parent span context (traceId/spanId). diff --git a/internal/config/config_core.go b/internal/config/config_core.go index 7c6fd7eb8..2ccaf0fdb 100644 --- a/internal/config/config_core.go +++ b/internal/config/config_core.go @@ -102,7 +102,10 @@ type GatewayConfig struct { // Port is the HTTP port to listen on Port int `toml:"port" json:"port,omitempty"` - // APIKey is the authentication key for the gateway + // AgentID is the gateway agent/session identifier. + AgentID string `toml:"agent_id" json:"agent_id,omitempty"` + + // APIKey is a deprecated alias for AgentID. APIKey string `toml:"api_key" json:"api_key,omitempty"` // Domain is the gateway domain for external access @@ -153,6 +156,10 @@ type GatewayConfig struct { // This key takes precedence over the legacy tracing key when both are present. // MUST use an HTTPS endpoint when configured. Opentelemetry *TracingConfig `toml:"opentelemetry" json:"opentelemetry,omitempty"` + + // agentIDExplicit tracks whether agent_id/agentId was explicitly provided + // (as opposed to being derived from deprecated api_key/apiKey aliases). + agentIDExplicit bool `toml:"-" json:"-"` } // HTTPKeepaliveInterval returns the keepalive interval as a time.Duration. @@ -167,12 +174,49 @@ func (g *GatewayConfig) HTTPKeepaliveInterval() time.Duration { return time.Duration(g.KeepaliveInterval) * time.Second } -// GetAPIKey returns the gateway API key, handling a nil Gateway safely. -func (c *Config) GetAPIKey() string { +// GetAgentID returns the gateway agent identifier, handling a nil Gateway safely. +func (c *Config) GetAgentID() string { if c.Gateway == nil { return "" } - return c.Gateway.APIKey + return c.Gateway.effectiveAgentID() +} + +// GetAPIKey is a deprecated alias for GetAgentID. +func (c *Config) GetAPIKey() string { + return c.GetAgentID() +} + +func (g *GatewayConfig) effectiveAgentID() string { + if g == nil { + return "" + } + if g.agentIDExplicit { + return g.AgentID + } + if g.AgentID != "" { + return g.AgentID + } + return g.APIKey +} + +func (g *GatewayConfig) normalizeAgentID(agentIDDefined, legacyAPIKeyDefined bool, source string) { + if g == nil { + return + } + + if legacyAPIKeyDefined { + logConfig.Printf("DEPRECATION: gateway.api_key is deprecated in %s config; use gateway.agent_id instead", source) + } + if legacyAPIKeyDefined && agentIDDefined && g.AgentID != g.APIKey { + logConfig.Printf("Both gateway.agent_id and deprecated gateway.api_key are set in %s config; using gateway.agent_id", source) + } + + g.agentIDExplicit = agentIDDefined + if !agentIDDefined && legacyAPIKeyDefined { + g.AgentID = g.APIKey + } + g.APIKey = g.effectiveAgentID() } // HTTPConnectTimeout returns the per-transport connect timeout as a Duration. @@ -456,6 +500,7 @@ func LoadFromFile(path string) (*Config, error) { if cfg.Gateway == nil { cfg.Gateway = &GatewayConfig{} } + cfg.Gateway.normalizeAgentID(md.IsDefined("gateway", "agent_id"), md.IsDefined("gateway", "api_key"), "TOML") // Validate trusted_bots per spec §4.1.3.4: must be non-empty array when present if err := validateTrustedBots(cfg.Gateway.TrustedBots); err != nil { diff --git a/internal/config/config_core_test.go b/internal/config/config_core_test.go index 343e79512..ee3304f70 100644 --- a/internal/config/config_core_test.go +++ b/internal/config/config_core_test.go @@ -197,7 +197,7 @@ args = ["run", "--rm", "-i", "ghcr.io/github/github-mcp-server:latest"] require.NoError(t, err) require.NotNil(t, cfg) assert.Equal(t, 8888, cfg.Gateway.Port) - assert.Equal(t, "my-secret", cfg.Gateway.APIKey) + assert.Equal(t, "my-secret", cfg.Gateway.AgentID) assert.Equal(t, 30, cfg.Gateway.StartupTimeout) assert.Equal(t, 60, cfg.Gateway.ToolTimeout) } @@ -437,24 +437,30 @@ func TestApplyGatewayDefaults_PartialZero(t *testing.T) { assert.Equal(t, DefaultToolTimeout, cfg.ToolTimeout) } -// TestGetAPIKey_NilGateway verifies that GetAPIKey returns an empty string +// TestGetAgentID_NilGateway verifies that GetAgentID returns an empty string // when the Config has a nil Gateway field. -func TestGetAPIKey_NilGateway(t *testing.T) { +func TestGetAgentID_NilGateway(t *testing.T) { cfg := &Config{Gateway: nil} - assert.Equal(t, "", cfg.GetAPIKey()) + assert.Equal(t, "", cfg.GetAgentID()) } -// TestGetAPIKey_EmptyKey verifies that GetAPIKey returns an empty string -// when the Gateway has an empty APIKey. -func TestGetAPIKey_EmptyKey(t *testing.T) { - cfg := &Config{Gateway: &GatewayConfig{APIKey: ""}} - assert.Equal(t, "", cfg.GetAPIKey()) +// TestGetAgentID_EmptyID verifies that GetAgentID returns an empty string +// when the Gateway has an empty AgentID. +func TestGetAgentID_EmptyID(t *testing.T) { + cfg := &Config{Gateway: &GatewayConfig{AgentID: ""}} + assert.Equal(t, "", cfg.GetAgentID()) } -// TestGetAPIKey_ReturnsKey verifies that GetAPIKey returns the configured API key. -func TestGetAPIKey_ReturnsKey(t *testing.T) { - cfg := &Config{Gateway: &GatewayConfig{APIKey: "super-secret-key"}} - assert.Equal(t, "super-secret-key", cfg.GetAPIKey()) +// TestGetAgentID_ReturnsID verifies that GetAgentID returns the configured agent ID. +func TestGetAgentID_ReturnsID(t *testing.T) { + cfg := &Config{Gateway: &GatewayConfig{AgentID: "agent-123"}} + assert.Equal(t, "agent-123", cfg.GetAgentID()) +} + +// TestGetAgentID_LegacyAPIKeyFallback verifies that GetAgentID falls back to APIKey alias. +func TestGetAgentID_LegacyAPIKeyFallback(t *testing.T) { + cfg := &Config{Gateway: &GatewayConfig{APIKey: "legacy-id"}} + assert.Equal(t, "legacy-id", cfg.GetAgentID()) } // TestLoadFromFile_OIDCAuthMissingEnvVar verifies that LoadFromFile returns an error @@ -824,7 +830,7 @@ func TestEnsureGatewayDefaults(t *testing.T) { StartupTimeout: 45, ToolTimeout: 90, KeepaliveInterval: 600, - APIKey: "my-api-key", + AgentID: "my-api-key", }, } cfg.EnsureGatewayDefaults() @@ -833,7 +839,7 @@ func TestEnsureGatewayDefaults(t *testing.T) { assert.Equal(t, 45, cfg.Gateway.StartupTimeout, "Explicit startup timeout should be preserved") assert.Equal(t, 90, cfg.Gateway.ToolTimeout, "Explicit tool timeout should be preserved") assert.Equal(t, 600, cfg.Gateway.KeepaliveInterval, "Explicit keepalive interval should be preserved") - assert.Equal(t, "my-api-key", cfg.Gateway.APIKey, "Explicit API key should be preserved") + assert.Equal(t, "my-api-key", cfg.Gateway.AgentID, "Explicit agent ID should be preserved") }) t.Run("calling EnsureGatewayDefaults twice is idempotent", func(t *testing.T) { diff --git a/internal/config/config_difc_test.go b/internal/config/config_difc_test.go index 1157a4c3c..6533e5d41 100644 --- a/internal/config/config_difc_test.go +++ b/internal/config/config_difc_test.go @@ -38,7 +38,7 @@ func TestStdinConfigWithGuards(t *testing.T) { "gateway": { "port": 3001, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }` @@ -71,7 +71,7 @@ func TestStdinConfigWithGuards(t *testing.T) { // Check gateway assert.Equal(t, 3001, *stdinCfg.Gateway.Port, "Port should be 3001") assert.Equal(t, "localhost", stdinCfg.Gateway.Domain, "Domain should be localhost") - assert.Equal(t, "test-api-key", stdinCfg.Gateway.APIKey, "API key mismatch") + assert.Equal(t, "test-api-key", stdinCfg.Gateway.AgentID, "Agent ID mismatch") } // TestStdinConfigMultipleGuards tests multiple guard configurations @@ -221,9 +221,9 @@ func TestConvertStdinConfigWithGuards(t *testing.T) { }, }, Gateway: &StdinGatewayConfig{ - Port: intPtrDIFC(3000), - Domain: "localhost", - APIKey: "test-key", + Port: intPtrDIFC(3000), + Domain: "localhost", + AgentID: "test-key", }, } @@ -293,7 +293,7 @@ func TestFullDIFCConfigParsing(t *testing.T) { "gateway": { "port": 3001, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }` @@ -321,7 +321,7 @@ func TestFullDIFCConfigParsing(t *testing.T) { // Verify gateway configuration assert.Equal(t, 3001, cfg.Gateway.Port) assert.Equal(t, "localhost", cfg.Gateway.Domain) - assert.Equal(t, "test-api-key", cfg.Gateway.APIKey) + assert.Equal(t, "test-api-key", cfg.Gateway.AgentID) } // TestLoadFromStdin_WithExtensionFields tests that LoadFromStdin accepts @@ -347,7 +347,7 @@ func TestLoadFromStdin_WithExtensionFields(t *testing.T) { "gateway": { "port": 3001, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }` diff --git a/internal/config/config_env.go b/internal/config/config_env.go index e92edd7c5..3d0e76cfe 100644 --- a/internal/config/config_env.go +++ b/internal/config/config_env.go @@ -55,15 +55,32 @@ func GetGatewayDomainFromEnv() string { return domain } -// GetGatewayAPIKeyFromEnv returns the MCP_GATEWAY_API_KEY value -func GetGatewayAPIKeyFromEnv() string { - key := envutil.GetEnvString("MCP_GATEWAY_API_KEY", "") - if key != "" { - logConfig.Print("MCP_GATEWAY_API_KEY found in environment") - } else { - logConfig.Print("MCP_GATEWAY_API_KEY not set in environment") +// GetGatewayAgentIDFromEnv returns the gateway agent identifier from environment. +// New name MCP_GATEWAY_AGENT_ID takes precedence over deprecated MCP_GATEWAY_API_KEY. +func GetGatewayAgentIDFromEnv() string { + agentID := envutil.GetEnvString("MCP_GATEWAY_AGENT_ID", "") + legacy := envutil.GetEnvString("MCP_GATEWAY_API_KEY", "") + + if agentID != "" { + if legacy != "" { + logConfig.Print("DEPRECATION: MCP_GATEWAY_API_KEY is set but ignored because MCP_GATEWAY_AGENT_ID is present") + } + logConfig.Print("MCP_GATEWAY_AGENT_ID found in environment") + return agentID + } + + if legacy != "" { + logConfig.Print("DEPRECATION: MCP_GATEWAY_API_KEY is deprecated; use MCP_GATEWAY_AGENT_ID") + return legacy } - return key + + logConfig.Print("MCP_GATEWAY_AGENT_ID not set in environment") + return "" +} + +// GetGatewayAPIKeyFromEnv is a deprecated alias for GetGatewayAgentIDFromEnv. +func GetGatewayAPIKeyFromEnv() string { + return GetGatewayAgentIDFromEnv() } // GetGatewayToolTimeoutFromEnv returns the MCP_GATEWAY_TOOL_TIMEOUT value, parsed as int. diff --git a/internal/config/config_guardpolicies_test.go b/internal/config/config_guardpolicies_test.go index cf8a72241..e00b18cdc 100644 --- a/internal/config/config_guardpolicies_test.go +++ b/internal/config/config_guardpolicies_test.go @@ -10,7 +10,7 @@ import ( // TestGuardPolicies_ReposAllFormat tests repos field with "all" value func TestGuardPolicies_ReposAllFormat(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "all", "min-integrity": "unapproved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "all", "min-integrity": "unapproved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -36,7 +36,7 @@ func TestGuardPolicies_ReposAllFormat(t *testing.T) { // TestGuardPolicies_ReposPublicFormat tests repos field with "public" value func TestGuardPolicies_ReposPublicFormat(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "public", "min-integrity": "none"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "public", "min-integrity": "none"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -62,7 +62,7 @@ func TestGuardPolicies_ReposPublicFormat(t *testing.T) { // TestGuardPolicies_ReposWithWildcards tests repos field with wildcard patterns func TestGuardPolicies_ReposWithWildcards(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["myorg/*", "partner/shared-repo", "docs/api-*"], "min-integrity": "approved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["myorg/*", "partner/shared-repo", "docs/api-*"], "min-integrity": "approved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -104,7 +104,7 @@ func TestGuardPolicies_AllMinIntegrityLevels(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "all", "min-integrity": "` + tc.minIntegrity + `"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": "all", "min-integrity": "` + tc.minIntegrity + `"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -216,7 +216,7 @@ min-integrity = "`+tc.minIntegrity+`" // TestGuardPolicies_ExactRepoPatterns tests exact repository pattern matching func TestGuardPolicies_ExactRepoPatterns(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["github/gh-aw-mcpg", "github/gh-aw", "frontend/ui-components"], "min-integrity": "merged"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["github/gh-aw-mcpg", "github/gh-aw", "frontend/ui-components"], "min-integrity": "merged"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -244,7 +244,7 @@ func TestGuardPolicies_ExactRepoPatterns(t *testing.T) { // TestGuardPolicies_MixedPatterns tests combination of exact matches and wildcards func TestGuardPolicies_MixedPatterns(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["github/gh-aw-mcpg", "myorg/*", "partner/shared-*", "docs/api-reference"], "min-integrity": "approved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {"github": {"repos": ["github/gh-aw-mcpg", "myorg/*", "partner/shared-*", "docs/api-reference"], "min-integrity": "approved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -272,7 +272,7 @@ func TestGuardPolicies_MixedPatterns(t *testing.T) { // TestGuardPolicies_EmptyGuardPolicies tests that empty guard-policies is allowed func TestGuardPolicies_EmptyGuardPolicies(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "guard-policies": {}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -295,7 +295,7 @@ func TestGuardPolicies_EmptyGuardPolicies(t *testing.T) { // TestGuardPolicies_MissingGuardPolicies tests that missing guard-policies is allowed func TestGuardPolicies_MissingGuardPolicies(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest"}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest"}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -318,7 +318,7 @@ func TestGuardPolicies_MissingGuardPolicies(t *testing.T) { // TestGuardPolicies_PreservesOtherServerConfig tests that guard policies don't interfere with other config func TestGuardPolicies_PreservesOtherServerConfig(t *testing.T) { - jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "", "DEBUG": "true"}, "guard-policies": {"github": {"repos": ["myorg/*"], "min-integrity": "unapproved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"github": {"type": "stdio", "container": "ghcr.io/github/github-mcp-server:latest", "env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "", "DEBUG": "true"}, "guard-policies": {"github": {"repos": ["myorg/*"], "min-integrity": "unapproved"}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin @@ -364,7 +364,7 @@ func TestGuardPolicies_PreservesOtherServerConfig(t *testing.T) { // TestGuardPolicies_WriteSink tests write-sink guard policy via JSON stdin func TestGuardPolicies_WriteSink(t *testing.T) { - jsonConfig := `{"mcpServers": {"safeoutputs": {"type": "stdio", "container": "ghcr.io/github/safe-outputs:latest", "guard-policies": {"write-sink": {"accept": ["private:github/gh-aw*"]}}}}, "gateway": {"port": 3000, "domain": "localhost", "apiKey": "test-key"}}` + jsonConfig := `{"mcpServers": {"safeoutputs": {"type": "stdio", "container": "ghcr.io/github/safe-outputs:latest", "guard-policies": {"write-sink": {"accept": ["private:github/gh-aw*"]}}}}, "gateway": {"port": 3000, "domain": "localhost", "agentId": "test-key"}}` r, w, _ := os.Pipe() oldStdin := os.Stdin diff --git a/internal/config/config_stdin.go b/internal/config/config_stdin.go index d179ca59a..7a67db630 100644 --- a/internal/config/config_stdin.go +++ b/internal/config/config_stdin.go @@ -33,6 +33,7 @@ type StdinConfig struct { // Uses pointers for optional fields to distinguish between unset and zero values. type StdinGatewayConfig struct { Port *int `json:"port,omitempty"` + AgentID string `json:"agentId,omitempty"` APIKey string `json:"apiKey,omitempty"` Domain string `json:"domain,omitempty"` StartupTimeout *int `json:"startupTimeout,omitempty"` @@ -43,6 +44,31 @@ type StdinGatewayConfig struct { PayloadSizeThreshold *int `json:"payloadSizeThreshold,omitempty"` TrustedBots []string `json:"trustedBots,omitempty"` OpenTelemetry *StdinOpenTelemetryConfig `json:"opentelemetry,omitempty"` + + agentIDSet bool `json:"-"` + legacyAPIKeySet bool `json:"-"` +} + +// UnmarshalJSON enables backward-compatible parsing for gateway.apiKey and +// tracks deprecated field usage for warning emission. +func (g *StdinGatewayConfig) UnmarshalJSON(data []byte) error { + type Alias StdinGatewayConfig + aux := &struct { + *Alias + }{ + Alias: (*Alias)(g), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + var rawFields map[string]json.RawMessage + if err := json.Unmarshal(data, &rawFields); err != nil { + return err + } + _, g.agentIDSet = rawFields["agentId"] + _, g.legacyAPIKeySet = rawFields["apiKey"] + return nil } // StdinOpenTelemetryConfig represents the OpenTelemetry configuration in stdin JSON format (spec §4.1.3.6). @@ -370,11 +396,13 @@ func convertStdinConfig(stdinCfg *StdinConfig) (*Config, error) { if stdinCfg.Gateway != nil { cfg.Gateway = &GatewayConfig{ Port: intPtrOrDefault(stdinCfg.Gateway.Port, DefaultPort), + AgentID: stdinCfg.Gateway.AgentID, APIKey: stdinCfg.Gateway.APIKey, Domain: stdinCfg.Gateway.Domain, StartupTimeout: intPtrOrDefault(stdinCfg.Gateway.StartupTimeout, DefaultStartupTimeout), KeepaliveInterval: intPtrOrDefault(stdinCfg.Gateway.KeepaliveInterval, DefaultKeepaliveInterval), } + cfg.Gateway.normalizeAgentID(stdinCfg.Gateway.agentIDSet, stdinCfg.Gateway.legacyAPIKeySet, "stdin JSON") if stdinCfg.Gateway.ToolTimeout != nil { cfg.Gateway.ToolTimeout = *stdinCfg.Gateway.ToolTimeout } else { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index bb8e725c3..56723635c 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -27,7 +27,7 @@ func TestLoadFromStdin_ValidJSON(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -105,7 +105,7 @@ func TestLoadFromStdin_WithGateway(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -129,7 +129,7 @@ func TestLoadFromStdin_WithGateway(t *testing.T) { require.NotNil(t, stdinCfg.Gateway, "Gateway not parsed") require.NotNil(t, stdinCfg.Gateway.Port, "Gateway port is nil") assert.Equal(t, port, *stdinCfg.Gateway.Port, "Gateway port not correct") - assert.Equal(t, "test-key", stdinCfg.Gateway.APIKey, "Gateway API key not correct") + assert.Equal(t, "test-key", stdinCfg.Gateway.AgentID, "Gateway agent ID not correct") } func TestLoadFromStdin_UnsupportedType(t *testing.T) { @@ -147,7 +147,7 @@ func TestLoadFromStdin_UnsupportedType(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -190,7 +190,7 @@ func TestLoadFromStdin_DirectCommand(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -251,7 +251,7 @@ func TestLoadFromStdin_StdioType(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -311,7 +311,7 @@ func TestLoadFromStdin_HttpType(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -355,7 +355,7 @@ func TestLoadFromStdin_LocalTypeBackwardCompatibility(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -397,7 +397,7 @@ func TestLoadFromStdin_GatewayWithAllFields(t *testing.T) { }, "gateway": { "port": 8080, - "apiKey": "test-key-123", + "agentId": "test-key-123", "domain": "localhost", "startupTimeout": 30, "toolTimeout": 60 @@ -426,7 +426,7 @@ func TestLoadFromStdin_GatewayWithAllFields(t *testing.T) { require.NotNil(t, stdinCfg.Gateway.Port, "Gateway port is nil") assert.Equal(t, port, *stdinCfg.Gateway.Port, "Expected gateway port") - assert.Equal(t, "test-key-123", stdinCfg.Gateway.APIKey, "Expected gateway API key 'test-key-123'") + assert.Equal(t, "test-key-123", stdinCfg.Gateway.AgentID, "Expected gateway agent ID 'test-key-123'") assert.Equal(t, "localhost", stdinCfg.Gateway.Domain, "Expected gateway domain 'localhost'") @@ -448,7 +448,7 @@ func TestLoadFromStdin_GatewayWithoutPayloadDir(t *testing.T) { }, "gateway": { "port": 8080, - "apiKey": "test-key-123", + "agentId": "test-key-123", "domain": "localhost" } }` @@ -481,7 +481,7 @@ func TestLoadFromStdin_GatewayWithPayloadPathPrefix(t *testing.T) { }, "gateway": { "port": 8080, - "apiKey": "test-key-123", + "agentId": "test-key-123", "domain": "localhost", "payloadPathPrefix": "/workspace/payloads" } @@ -522,7 +522,7 @@ func TestLoadFromStdin_ServerWithURL(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -572,7 +572,7 @@ func TestLoadFromStdin_MixedServerTypes(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -621,7 +621,7 @@ func TestLoadFromStdin_ContainerWithStdioType(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -691,7 +691,7 @@ func TestLoadFromStdin_WithEntrypoint(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -742,7 +742,7 @@ func TestLoadFromStdin_WithMounts(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -793,7 +793,7 @@ func TestLoadFromStdin_WithAllNewFields(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -909,7 +909,7 @@ func TestLoadFromStdin_InvalidMountFormat(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, tt.mounts) @@ -974,7 +974,7 @@ args = ["run", "--rm", "-i", "test/container:latest"] require.NotNil(t, cfg.Gateway, "Gateway config should not be nil") assert.Equal(t, 8080, cfg.Gateway.Port) - assert.Equal(t, "test-key-123", cfg.Gateway.APIKey) + assert.Equal(t, "test-key-123", cfg.Gateway.AgentID) assert.Equal(t, "localhost", cfg.Gateway.Domain) assert.Equal(t, 30, cfg.Gateway.StartupTimeout) assert.Equal(t, 60, cfg.Gateway.ToolTimeout) @@ -1182,7 +1182,7 @@ func TestLoadFromStdin_FilesystemServerConfig(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -1254,7 +1254,7 @@ func TestLoadFromStdin_PlaywrightServerConfig(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -1343,7 +1343,7 @@ func TestLoadFromStdin_WithRegistryField(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, serverName: "github", @@ -1364,7 +1364,7 @@ func TestLoadFromStdin_WithRegistryField(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, serverName: "markitdown", @@ -1384,7 +1384,7 @@ func TestLoadFromStdin_WithRegistryField(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, serverName: "custom", @@ -1510,35 +1510,40 @@ func TestApplyGatewayDefaults_AllFieldsSet(t *testing.T) { } // TestApplyGatewayDefaults_OtherFieldsUnaffected verifies that fields not managed by -// applyGatewayDefaults (APIKey, Domain, etc.) are not touched. +// applyGatewayDefaults (AgentID, Domain, etc.) are not touched. func TestApplyGatewayDefaults_OtherFieldsUnaffected(t *testing.T) { cfg := &GatewayConfig{ - APIKey: "my-api-key", - Domain: "example.com", + AgentID: "agent-123", + Domain: "example.com", } applyGatewayDefaults(cfg) - assert.Equal(t, "my-api-key", cfg.APIKey, "APIKey should not be modified by applyGatewayDefaults") + assert.Equal(t, "agent-123", cfg.AgentID, "AgentID should not be modified by applyGatewayDefaults") assert.Equal(t, "example.com", cfg.Domain, "Domain should not be modified by applyGatewayDefaults") // Defaults applied for the zero fields assert.Equal(t, DefaultPort, cfg.Port) } -// TestGetAPIKey verifies that GetAPIKey handles nil Gateway and returns the key when set. -func TestGetAPIKey(t *testing.T) { +// TestGetAgentID verifies that GetAgentID handles nil Gateway and returns the ID when set. +func TestGetAgentID(t *testing.T) { t.Run("nil Gateway returns empty string", func(t *testing.T) { cfg := &Config{} - assert.Equal(t, "", cfg.GetAPIKey()) + assert.Equal(t, "", cfg.GetAgentID()) }) - t.Run("Gateway with no key returns empty string", func(t *testing.T) { + t.Run("Gateway with no ID returns empty string", func(t *testing.T) { cfg := &Config{Gateway: &GatewayConfig{}} - assert.Equal(t, "", cfg.GetAPIKey()) + assert.Equal(t, "", cfg.GetAgentID()) }) - t.Run("Gateway with key returns key", func(t *testing.T) { - cfg := &Config{Gateway: &GatewayConfig{APIKey: "my-secret-key"}} - assert.Equal(t, "my-secret-key", cfg.GetAPIKey()) + t.Run("Gateway with ID returns ID", func(t *testing.T) { + cfg := &Config{Gateway: &GatewayConfig{AgentID: "agent-123"}} + assert.Equal(t, "agent-123", cfg.GetAgentID()) + }) + + t.Run("Legacy APIKey still maps to agent ID", func(t *testing.T) { + cfg := &Config{Gateway: &GatewayConfig{APIKey: "legacy-id"}} + assert.Equal(t, "legacy-id", cfg.GetAgentID()) }) } @@ -1611,7 +1616,7 @@ func TestLoadFromStdin_WithTrustedBots(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "trustedBots": ["github-actions[bot]", "copilot-swe-agent[bot]"] } }` @@ -1648,7 +1653,7 @@ func TestLoadFromStdin_WithEmptyTrustedBots(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "trustedBots": [] } }` @@ -1685,7 +1690,7 @@ func TestLoadFromStdin_HTTPServerWithToolTimeout(t *testing.T) { "gateway": { "port": 3000, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` @@ -1726,7 +1731,7 @@ func TestLoadFromStdin_HTTPServerToolTimeoutOverridesGlobal(t *testing.T) { "gateway": { "port": 3000, "domain": "localhost", -"apiKey": "test-key", +"agentId": "test-key", "toolTimeout": 60 } }` @@ -1772,7 +1777,7 @@ func TestLoadFromStdin_HTTPServerToolTimeoutBelowMinimum(t *testing.T) { "gateway": { "port": 3000, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` @@ -1804,7 +1809,7 @@ func TestLoadFromStdin_HTTPServerWithLegacySnakeCaseTimeoutFields(t *testing.T) "gateway": { "port": 3000, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` @@ -1839,7 +1844,7 @@ func TestLoadFromStdin_HTTPServerWithLegacySnakeCaseToolTimeoutBelowMinimum(t *t "gateway": { "port": 3000, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` diff --git a/internal/config/expand_raw_json_test.go b/internal/config/expand_raw_json_test.go index 5ea23509f..ae4e31b51 100644 --- a/internal/config/expand_raw_json_test.go +++ b/internal/config/expand_raw_json_test.go @@ -407,7 +407,7 @@ func TestExpandRawJSONVariables_RealWorldConfig(t *testing.T) { "gateway": { "port": 3000, "domain": "${MCP_GATEWAY_DOMAIN}", - "apiKey": "secret-key" + "agentId": "secret-key" } }` diff --git a/internal/config/load_from_stdin_coverage_test.go b/internal/config/load_from_stdin_coverage_test.go index cf52da556..ba61cdaa5 100644 --- a/internal/config/load_from_stdin_coverage_test.go +++ b/internal/config/load_from_stdin_coverage_test.go @@ -79,7 +79,7 @@ func TestLoadFromStdin_ValidateStringPatternsError(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -106,7 +106,7 @@ func TestLoadFromStdin_ValidateCustomSchemasError_ReservedStdioKey(t *testing.T) "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" }, "customSchemas": { "stdio": "https://example.com/schema.json" @@ -134,7 +134,7 @@ func TestLoadFromStdin_ValidateCustomSchemasError_ReservedHttpKey(t *testing.T) "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" }, "customSchemas": { "http": "https://example.com/schema.json" @@ -164,7 +164,7 @@ func TestLoadFromStdin_ValidateGatewayConfigError_AllZeroTraceId(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "opentelemetry": { "endpoint": "https://otel-collector.example.com", "traceId": "00000000000000000000000000000000" @@ -193,7 +193,7 @@ func TestLoadFromStdin_OpenTelemetryHeaders(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "opentelemetry": { "endpoint": "https://otel-collector.example.com", "headers": "X-Test=value" diff --git a/internal/config/schema/mcp-gateway-config.schema.json b/internal/config/schema/mcp-gateway-config.schema.json index 79f833f34..76b773dff 100644 --- a/internal/config/schema/mcp-gateway-config.schema.json +++ b/internal/config/schema/mcp-gateway-config.schema.json @@ -301,11 +301,17 @@ ], "description": "HTTP server port for the gateway. The gateway exposes endpoints at http://{domain}:{port}/. Can be an integer (1-65535) or a variable expression like '${MCP_GATEWAY_PORT}'." }, - "apiKey": { + "agentId": { "type": "string", - "description": "API key for authentication. When configured, clients must include 'Authorization: ' header in all RPC requests (the API key is used directly without Bearer or other scheme prefix). Per MCP Gateway Specification section 7.1, the authorization header format is 'Authorization: ' where the API key is the complete header value. API keys must not be logged in plaintext per section 7.2.", + "description": "Agent/session identifier for request routing and optional auth matching. When configured, clients include this value in Authorization and may also send X-Agent-ID for explicit session routing.", "minLength": 1 }, + "apiKey": { + "type": "string", + "description": "DEPRECATED alias for agentId. Use agentId instead.", + "minLength": 1, + "deprecated": true + }, "domain": { "oneOf": [ { @@ -371,10 +377,21 @@ }, "required": [ "port", - "domain", - "apiKey" + "domain" ], - "additionalProperties": false + "additionalProperties": false, + "anyOf": [ + { + "required": [ + "agentId" + ] + }, + { + "required": [ + "apiKey" + ] + } + ] }, "opentelemetryConfig": { "type": "object", @@ -436,7 +453,7 @@ "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "gateway-secret-token" + "agentId": "gateway-secret-token" } }, { @@ -483,7 +500,7 @@ "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "gateway-secret-token" + "agentId": "gateway-secret-token" } }, { @@ -507,7 +524,7 @@ "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "gateway-secret-token" + "agentId": "gateway-secret-token" }, "customSchemas": { "safeinputs": "https://docs.github.com/gh-aw/schemas/mcp-scripts-config.schema.json" diff --git a/internal/config/validation_env.go b/internal/config/validation_env.go index da3f36938..4fcfa3b0c 100644 --- a/internal/config/validation_env.go +++ b/internal/config/validation_env.go @@ -15,7 +15,7 @@ var logEnv = logger.New("config:validation_env") var RequiredEnvVars = []string{ "MCP_GATEWAY_PORT", "MCP_GATEWAY_DOMAIN", - "MCP_GATEWAY_API_KEY", + "MCP_GATEWAY_AGENT_ID", } // EnvValidationResult holds the result of environment validation. @@ -151,6 +151,14 @@ func ValidateContainerizedEnvironment(containerID string) *EnvValidationResult { func checkRequiredEnvVars() []string { var missing []string for _, envVar := range RequiredEnvVars { + if envVar == "MCP_GATEWAY_AGENT_ID" { + if os.Getenv("MCP_GATEWAY_AGENT_ID") != "" || os.Getenv("MCP_GATEWAY_API_KEY") != "" { + if os.Getenv("MCP_GATEWAY_AGENT_ID") == "" && os.Getenv("MCP_GATEWAY_API_KEY") != "" { + logEnv.Print("DEPRECATION: MCP_GATEWAY_API_KEY satisfies required agent identifier but should be renamed to MCP_GATEWAY_AGENT_ID") + } + continue + } + } if os.Getenv(envVar) == "" { missing = append(missing, envVar) } diff --git a/internal/config/validation_env_test.go b/internal/config/validation_env_test.go index 1f66b2ac0..4567a8c99 100644 --- a/internal/config/validation_env_test.go +++ b/internal/config/validation_env_test.go @@ -47,44 +47,53 @@ func TestCheckRequiredEnvVars(t *testing.T) { { name: "all set", envVars: map[string]string{ - "MCP_GATEWAY_PORT": "8080", - "MCP_GATEWAY_DOMAIN": "localhost", - "MCP_GATEWAY_API_KEY": "test-key", + "MCP_GATEWAY_PORT": "8080", + "MCP_GATEWAY_DOMAIN": "localhost", + "MCP_GATEWAY_AGENT_ID": "test-key", }, expected: nil, }, { name: "partial set - missing port", envVars: map[string]string{ - "MCP_GATEWAY_DOMAIN": "localhost", - "MCP_GATEWAY_API_KEY": "test-key", + "MCP_GATEWAY_DOMAIN": "localhost", + "MCP_GATEWAY_AGENT_ID": "test-key", }, expected: []string{"MCP_GATEWAY_PORT"}, }, { name: "partial set - missing domain", envVars: map[string]string{ - "MCP_GATEWAY_PORT": "8080", - "MCP_GATEWAY_API_KEY": "test-key", + "MCP_GATEWAY_PORT": "8080", + "MCP_GATEWAY_AGENT_ID": "test-key", }, expected: []string{"MCP_GATEWAY_DOMAIN"}, }, { - name: "partial set - missing api key", + name: "partial set - missing agent id", envVars: map[string]string{ "MCP_GATEWAY_PORT": "8080", "MCP_GATEWAY_DOMAIN": "localhost", }, - expected: []string{"MCP_GATEWAY_API_KEY"}, + expected: []string{"MCP_GATEWAY_AGENT_ID"}, }, { name: "empty string values are missing", envVars: map[string]string{ - "MCP_GATEWAY_PORT": "", + "MCP_GATEWAY_PORT": "", + "MCP_GATEWAY_DOMAIN": "localhost", + "MCP_GATEWAY_AGENT_ID": "test-key", + }, + expected: []string{"MCP_GATEWAY_PORT"}, + }, + { + name: "legacy api key env still satisfies agent id requirement", + envVars: map[string]string{ + "MCP_GATEWAY_PORT": "8080", "MCP_GATEWAY_DOMAIN": "localhost", "MCP_GATEWAY_API_KEY": "test-key", }, - expected: []string{"MCP_GATEWAY_PORT"}, + expected: nil, }, } @@ -150,7 +159,7 @@ func TestGetGatewayDomainFromEnv(t *testing.T) { } } -func TestGetGatewayAPIKeyFromEnv(t *testing.T) { +func TestGetGatewayAgentIDFromEnv(t *testing.T) { tests := []struct { name string envValue string @@ -174,13 +183,15 @@ func TestGetGatewayAPIKeyFromEnv(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + os.Unsetenv("MCP_GATEWAY_AGENT_ID") os.Unsetenv("MCP_GATEWAY_API_KEY") if tt.setEnv { - os.Setenv("MCP_GATEWAY_API_KEY", tt.envValue) + os.Setenv("MCP_GATEWAY_AGENT_ID", tt.envValue) } + defer os.Unsetenv("MCP_GATEWAY_AGENT_ID") defer os.Unsetenv("MCP_GATEWAY_API_KEY") - key := GetGatewayAPIKeyFromEnv() + key := GetGatewayAgentIDFromEnv() if tt.setEnv { assert.Equal(t, tt.envValue, key) @@ -191,6 +202,23 @@ func TestGetGatewayAPIKeyFromEnv(t *testing.T) { } } +func TestGetGatewayAgentIDFromEnv_LegacyFallback(t *testing.T) { + os.Unsetenv("MCP_GATEWAY_AGENT_ID") + os.Setenv("MCP_GATEWAY_API_KEY", "legacy-key") + defer os.Unsetenv("MCP_GATEWAY_API_KEY") + + assert.Equal(t, "legacy-key", GetGatewayAgentIDFromEnv()) +} + +func TestGetGatewayAgentIDFromEnv_NewTakesPrecedence(t *testing.T) { + os.Setenv("MCP_GATEWAY_AGENT_ID", "new-id") + os.Setenv("MCP_GATEWAY_API_KEY", "legacy-key") + defer os.Unsetenv("MCP_GATEWAY_AGENT_ID") + defer os.Unsetenv("MCP_GATEWAY_API_KEY") + + assert.Equal(t, "new-id", GetGatewayAgentIDFromEnv()) +} + func TestEnvValidationResultIsValid(t *testing.T) { tests := []struct { name string @@ -273,23 +301,36 @@ func TestValidateExecutionEnvironment(t *testing.T) { // Save original env vars origPort := os.Getenv("MCP_GATEWAY_PORT") origDomain := os.Getenv("MCP_GATEWAY_DOMAIN") - origAPIKey := os.Getenv("MCP_GATEWAY_API_KEY") + origAgentID, hadAgentID := os.LookupEnv("MCP_GATEWAY_AGENT_ID") + origLegacyAPIKey, hadLegacyAPIKey := os.LookupEnv("MCP_GATEWAY_API_KEY") defer func() { if origPort != "" { os.Setenv("MCP_GATEWAY_PORT", origPort) + } else { + os.Unsetenv("MCP_GATEWAY_PORT") } if origDomain != "" { os.Setenv("MCP_GATEWAY_DOMAIN", origDomain) + } else { + os.Unsetenv("MCP_GATEWAY_DOMAIN") + } + if hadAgentID { + os.Setenv("MCP_GATEWAY_AGENT_ID", origAgentID) + } else { + os.Unsetenv("MCP_GATEWAY_AGENT_ID") } - if origAPIKey != "" { - os.Setenv("MCP_GATEWAY_API_KEY", origAPIKey) + if hadLegacyAPIKey { + os.Setenv("MCP_GATEWAY_API_KEY", origLegacyAPIKey) + } else { + os.Unsetenv("MCP_GATEWAY_API_KEY") } }() t.Run("with all env vars set", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") + os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateExecutionEnvironment() @@ -300,6 +341,7 @@ func TestValidateExecutionEnvironment(t *testing.T) { t.Run("with missing env vars", func(t *testing.T) { os.Unsetenv("MCP_GATEWAY_PORT") os.Unsetenv("MCP_GATEWAY_DOMAIN") + os.Unsetenv("MCP_GATEWAY_AGENT_ID") os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateExecutionEnvironment() @@ -316,7 +358,8 @@ func TestValidateContainerizedEnvironment(t *testing.T) { // Save original env vars origPort := os.Getenv("MCP_GATEWAY_PORT") origDomain := os.Getenv("MCP_GATEWAY_DOMAIN") - origAPIKey := os.Getenv("MCP_GATEWAY_API_KEY") + origAgentID, hadAgentID := os.LookupEnv("MCP_GATEWAY_AGENT_ID") + origLegacyAPIKey, hadLegacyAPIKey := os.LookupEnv("MCP_GATEWAY_API_KEY") origLogDir := os.Getenv("MCP_GATEWAY_LOG_DIR") defer func() { if origPort != "" { @@ -329,8 +372,13 @@ func TestValidateContainerizedEnvironment(t *testing.T) { } else { os.Unsetenv("MCP_GATEWAY_DOMAIN") } - if origAPIKey != "" { - os.Setenv("MCP_GATEWAY_API_KEY", origAPIKey) + if hadAgentID { + os.Setenv("MCP_GATEWAY_AGENT_ID", origAgentID) + } else { + os.Unsetenv("MCP_GATEWAY_AGENT_ID") + } + if hadLegacyAPIKey { + os.Setenv("MCP_GATEWAY_API_KEY", origLegacyAPIKey) } else { os.Unsetenv("MCP_GATEWAY_API_KEY") } @@ -344,7 +392,8 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("empty container ID", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") + os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateContainerizedEnvironment("") @@ -357,7 +406,8 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("valid container ID with all env vars", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") + os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateContainerizedEnvironment("abcdef123456") @@ -370,6 +420,7 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("missing required env vars", func(t *testing.T) { os.Unsetenv("MCP_GATEWAY_PORT") os.Unsetenv("MCP_GATEWAY_DOMAIN") + os.Unsetenv("MCP_GATEWAY_AGENT_ID") os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateContainerizedEnvironment("abcdef123456") @@ -383,7 +434,8 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("port validation failure", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") + os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateContainerizedEnvironment("abcdef123456") @@ -395,7 +447,8 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("stdin interactive check", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") + os.Unsetenv("MCP_GATEWAY_API_KEY") result := ValidateContainerizedEnvironment("abcdef123456") @@ -407,7 +460,7 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("log directory mount check with default", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") os.Unsetenv("MCP_GATEWAY_LOG_DIR") result := ValidateContainerizedEnvironment("abcdef123456") @@ -422,7 +475,7 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("log directory mount check with custom dir", func(t *testing.T) { os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") os.Setenv("MCP_GATEWAY_LOG_DIR", "/custom/log/path") result := ValidateContainerizedEnvironment("abcdef123456") @@ -456,7 +509,7 @@ func TestValidateContainerizedEnvironment(t *testing.T) { os.Setenv("DOCKER_HOST", "unix:///nonexistent/docker.sock") os.Setenv("MCP_GATEWAY_PORT", "8080") os.Setenv("MCP_GATEWAY_DOMAIN", "localhost") - os.Setenv("MCP_GATEWAY_API_KEY", "test-key") + os.Setenv("MCP_GATEWAY_AGENT_ID", "test-key") result := ValidateContainerizedEnvironment("abcdef123456") @@ -476,7 +529,7 @@ func TestValidateContainerizedEnvironment(t *testing.T) { t.Run("validation result error message format", func(t *testing.T) { os.Unsetenv("MCP_GATEWAY_PORT") os.Unsetenv("MCP_GATEWAY_DOMAIN") - os.Unsetenv("MCP_GATEWAY_API_KEY") + os.Unsetenv("MCP_GATEWAY_AGENT_ID") result := ValidateContainerizedEnvironment("abcdef123456") diff --git a/internal/config/validation_schema_test.go b/internal/config/validation_schema_test.go index 20f0ce6fb..356d48b05 100644 --- a/internal/config/validation_schema_test.go +++ b/internal/config/validation_schema_test.go @@ -26,7 +26,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: false, @@ -48,7 +48,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "startupTimeout": 30, "toolTimeout": 60 } @@ -68,7 +68,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: false, @@ -79,7 +79,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -107,7 +107,7 @@ func TestValidateJSONSchema(t *testing.T) { }, "gateway": { "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -123,7 +123,7 @@ func TestValidateJSONSchema(t *testing.T) { }, "gateway": { "port": 8080, - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -156,7 +156,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -173,7 +173,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -190,7 +190,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 99999, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -207,7 +207,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 0, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -224,7 +224,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "startupTimeout": 0 } }`, @@ -242,7 +242,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" }, "unknownField": "value" }`, @@ -261,7 +261,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -280,7 +280,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -297,7 +297,7 @@ func TestValidateJSONSchema(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key", + "agentId": "test-key", "unknownField": "value" } }`, @@ -572,7 +572,7 @@ func TestEnhancedErrorMessages(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }`, expectInError: []string{ @@ -614,7 +614,7 @@ func TestEnhancedErrorMessages(t *testing.T) { "gateway": { "port": 99999, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }`, expectInError: []string{ @@ -664,7 +664,7 @@ func TestSchemaCaching(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` @@ -692,7 +692,7 @@ func TestSchemaConfiguration(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", -"apiKey": "test-key" +"agentId": "test-key" } }` @@ -716,7 +716,7 @@ func TestFixSchemaBytes_keepaliveInterval(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", -"apiKey": "test-key", +"agentId": "test-key", "keepaliveInterval": 300 } }` @@ -736,7 +736,7 @@ func TestFixSchemaBytes_keepaliveIntervalNegative(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", -"apiKey": "test-key", +"agentId": "test-key", "keepaliveInterval": -1 } }` diff --git a/internal/config/validation_test.go b/internal/config/validation_test.go index c168d009d..bb6df2768 100644 --- a/internal/config/validation_test.go +++ b/internal/config/validation_test.go @@ -572,7 +572,7 @@ func TestLoadFromStdin_WithVariableExpansion(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -600,7 +600,7 @@ func TestLoadFromStdin_UndefinedVariable(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -630,7 +630,7 @@ func TestLoadFromStdin_VariableExpansionInContainer(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }` @@ -663,7 +663,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -682,7 +682,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -700,7 +700,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 99999, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: true, @@ -724,7 +724,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: false, @@ -742,7 +742,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: false, @@ -759,7 +759,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" }, "guards": { "github-guard": { @@ -787,7 +787,7 @@ func TestLoadFromStdin_ValidationErrors(t *testing.T) { "gateway": { "port": 8080, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, shouldErr: false, diff --git a/internal/server/http_helpers_test.go b/internal/server/http_helpers_test.go index 12296fe1c..36eb6ecad 100644 --- a/internal/server/http_helpers_test.go +++ b/internal/server/http_helpers_test.go @@ -257,6 +257,7 @@ func TestExtractAndValidateSession(t *testing.T) { tests := []struct { name string authHeader string + xAgentID string expectedID string shouldBeEmpty bool }{ @@ -266,6 +267,19 @@ func TestExtractAndValidateSession(t *testing.T) { expectedID: "test-session-123", shouldBeEmpty: false, }, + { + name: "X-Agent-ID is used as session ID", + xAgentID: "agent-header-1", + expectedID: "agent-header-1", + shouldBeEmpty: false, + }, + { + name: "X-Agent-ID takes precedence over Authorization", + authHeader: "auth-id", + xAgentID: "agent-header-2", + expectedID: "agent-header-2", + shouldBeEmpty: false, + }, { name: "Valid Bearer token", authHeader: "Bearer my-token-456", @@ -290,6 +304,31 @@ func TestExtractAndValidateSession(t *testing.T) { expectedID: "very-long-session-id-with-many-characters-1234567890", shouldBeEmpty: false, }, + { + name: "Malformed X-Agent-ID rejects session", + authHeader: "auth-id", + xAgentID: "bad\x00id", + expectedID: "", + shouldBeEmpty: true, + }, + { + name: "Malformed Authorization rejects session", + authHeader: "bad\x00id", + expectedID: "", + shouldBeEmpty: true, + }, + { + name: "Path traversal session ID rejects session", + authHeader: "../escape", + expectedID: "", + shouldBeEmpty: true, + }, + { + name: "Session ID with separator rejects session", + xAgentID: "nested/session", + expectedID: "", + shouldBeEmpty: true, + }, } for _, tt := range tests { @@ -298,6 +337,9 @@ func TestExtractAndValidateSession(t *testing.T) { if tt.authHeader != "" { req.Header.Set("Authorization", tt.authHeader) } + if tt.xAgentID != "" { + req.Header.Set("X-Agent-ID", tt.xAgentID) + } sessionID := extractAndValidateSession(req) diff --git a/internal/server/middleware.go b/internal/server/middleware.go index 5f021d30b..ddd8c2982 100644 --- a/internal/server/middleware.go +++ b/internal/server/middleware.go @@ -191,8 +191,9 @@ func WithSDKLogging(handler http.Handler, mode string) http.Handler { startTime := time.Now() // Extract session info for logging context + agentIDHeader := r.Header.Get("X-Agent-ID") authHeader := r.Header.Get("Authorization") - sessionID := auth.ExtractSessionID(authHeader) + sessionID := auth.ExtractSessionIDFromHeaders(agentIDHeader, authHeader) mcpSessionID := r.Header.Get("Mcp-Session-Id") // Log incoming request diff --git a/internal/server/session.go b/internal/server/session.go index 974285ecc..d199e364c 100644 --- a/internal/server/session.go +++ b/internal/server/session.go @@ -6,6 +6,7 @@ import ( "net/http" "os" "path/filepath" + "strings" "time" "github.com/github/gh-aw-mcpg/internal/auth" @@ -115,17 +116,23 @@ func (us *UnifiedServer) getSessionKeys() []string { return keys } -// extractAndValidateSession extracts the session ID from the Authorization header +// extractAndValidateSession extracts the session ID from request headers. // and logs connection details. Returns empty string if validation fails. func extractAndValidateSession(r *http.Request) string { logSession.Printf("Extracting session from request: remote=%s, path=%s", r.RemoteAddr, r.URL.Path) + agentIDHeader := r.Header.Get("X-Agent-ID") authHeader := r.Header.Get("Authorization") - sessionID := auth.ExtractSessionID(authHeader) + sessionID := auth.ExtractSessionIDFromHeaders(agentIDHeader, authHeader) if sessionID == "" { - logSession.Printf("Session extraction failed: missing or invalid Authorization header, remote=%s", r.RemoteAddr) - logger.LogError("client", "Rejected MCP client connection: missing or invalid Authorization header, remote=%s, path=%s", r.RemoteAddr, r.URL.Path) + logSession.Printf("Session extraction failed: missing or invalid X-Agent-ID/Authorization header, remote=%s", r.RemoteAddr) + logger.LogError("client", "Rejected MCP client connection: missing or invalid X-Agent-ID/Authorization header, remote=%s, path=%s", r.RemoteAddr, r.URL.Path) + return "" + } + if !isSinglePathSegmentSessionID(sessionID) { + logSession.Printf("Session extraction failed: invalid session identifier format, remote=%s", r.RemoteAddr) + logger.LogError("client", "Rejected MCP client connection: invalid session identifier format, remote=%s, path=%s", r.RemoteAddr, r.URL.Path) return "" } @@ -133,6 +140,22 @@ func extractAndValidateSession(r *http.Request) string { return sessionID } +func isSinglePathSegmentSessionID(sessionID string) bool { + if sessionID == "" || sessionID == "." || sessionID == ".." { + return false + } + if filepath.IsAbs(sessionID) || filepath.VolumeName(sessionID) != "" { + return false + } + if strings.Contains(sessionID, "/") || strings.Contains(sessionID, "\\") { + return false + } + if filepath.Base(sessionID) != sessionID { + return false + } + return filepath.Clean(sessionID) == sessionID +} + // injectSessionContext stores the session ID and optional backend ID into the request context. // If backendID is empty, only session ID is injected (unified mode). // Returns the modified request with updated context. diff --git a/internal/server/session_auto_init.go b/internal/server/session_auto_init.go index 4a8f6bc4c..699808c8c 100644 --- a/internal/server/session_auto_init.go +++ b/internal/server/session_auto_init.go @@ -35,8 +35,9 @@ const autoInitClientInfo = `{"name":"mcpg-auto-init","version":"1.0"}` // // The handler argument must be the SDK's StreamableHTTPHandler BEFORE any // authentication or HMAC middleware is applied. The internal initialization requests -// copy the Authorization header from the original request, so authentication is -// preserved without going through the outer middleware stack again. +// copy the Authorization and X-Agent-ID headers from the original request, so +// authentication/session routing is preserved without going through the outer +// middleware stack again. func WrapWithSessionAutoInit(streamableHandler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Only handle POST requests that have no established session. @@ -144,4 +145,7 @@ func copyAutoInitHeaders(dst, src http.Header) { if a := src.Get("Authorization"); a != "" { dst.Set("Authorization", a) } + if agentID := src.Get("X-Agent-ID"); agentID != "" { + dst.Set("X-Agent-ID", agentID) + } } diff --git a/internal/server/session_auto_init_test.go b/internal/server/session_auto_init_test.go index 0d8f88ebc..7dac23688 100644 --- a/internal/server/session_auto_init_test.go +++ b/internal/server/session_auto_init_test.go @@ -368,6 +368,7 @@ func TestPerformSessionAutoInit_Success(t *testing.T) { // initialize request so that authentication is preserved. func TestPerformSessionAutoInit_AuthHeaderCopied(t *testing.T) { var capturedInitAuth string + var capturedInitAgentID string handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { bodyBytes, _ := peekRequestBody(r) @@ -379,6 +380,7 @@ func TestPerformSessionAutoInit_AuthHeaderCopied(t *testing.T) { switch rpcReq.Method { case "initialize": capturedInitAuth = r.Header.Get("Authorization") + capturedInitAgentID = r.Header.Get("X-Agent-ID") w.Header().Set("Mcp-Session-Id", "auth-test-session") w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) @@ -392,11 +394,14 @@ func TestPerformSessionAutoInit_AuthHeaderCopied(t *testing.T) { req := httptest.NewRequest(http.MethodPost, "/mcp", nil) req.Header.Set("Authorization", "my-secret-api-key") + req.Header.Set("X-Agent-ID", "agent-session-42") _, err := performSessionAutoInit(req, handler) require.NoError(t, err) assert.Equal(t, "my-secret-api-key", capturedInitAuth, "Authorization header must be forwarded to the auto-init initialize request") + assert.Equal(t, "agent-session-42", capturedInitAgentID, + "X-Agent-ID header must be forwarded to the auto-init initialize request") } func TestCopyAutoInitHeaders(t *testing.T) { @@ -406,16 +411,19 @@ func TestCopyAutoInitHeaders(t *testing.T) { wantCT string wantAccept string wantAuth string + wantAgent string }{ { name: "with authorization", src: http.Header{ "Authorization": {"Bearer token123"}, + "X-Agent-Id": {"agent-a"}, "X-Custom": {"ignored"}, }, wantCT: "application/json", wantAccept: "application/json, text/event-stream", wantAuth: "Bearer token123", + wantAgent: "agent-a", }, { name: "without authorization", @@ -423,6 +431,7 @@ func TestCopyAutoInitHeaders(t *testing.T) { wantCT: "application/json", wantAccept: "application/json, text/event-stream", wantAuth: "", + wantAgent: "", }, } @@ -434,6 +443,7 @@ func TestCopyAutoInitHeaders(t *testing.T) { assert.Equal(t, tt.wantCT, dst.Get("Content-Type")) assert.Equal(t, tt.wantAccept, dst.Get("Accept")) assert.Equal(t, tt.wantAuth, dst.Get("Authorization")) + assert.Equal(t, tt.wantAgent, dst.Get("X-Agent-ID")) // Custom headers should not be copied. assert.Empty(t, dst.Get("X-Custom")) }) diff --git a/scripts/_inject_local_build.py b/scripts/_inject_local_build.py new file mode 100644 index 000000000..81d775c44 --- /dev/null +++ b/scripts/_inject_local_build.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +"""Inject a local Docker build step into a smoke test lock file. + +Called by scripts/patch-smoke-local-build.sh — not intended for direct use. +Exits 0 on success, 1 if no insertion point was found. +""" +import sys + +BUILD_STEP = """\ + - name: Build MCP Gateway from source (local) + env: + BUILD_VERSION: ${{ github.sha }} + run: | + # Install Rust with WASM target for the guard + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable -t wasm32-wasip1 + source "$HOME/.cargo/env" + # Build WASM guard + make -C guards/github-guard build + # Build gateway Docker image, overwriting the pulled :latest + docker build -t ghcr.io/github/gh-aw-mcpg:latest \\ + --build-arg VERSION="$BUILD_VERSION" . + echo "Built local gateway image from $(git rev-parse --short HEAD)" +""" + +lockfile = sys.argv[1] + +with open(lockfile, "r") as f: + lines = f.readlines() + +result = [] +found_download = False +injected = False + +for line in lines: + if "name: Download container images" in line: + found_download = True + elif found_download and not injected and line.strip().startswith("- name:"): + result.append(BUILD_STEP) + injected = True + result.append(line) + +if injected: + with open(lockfile, "w") as f: + f.writelines(result) + +sys.exit(0 if injected else 1) diff --git a/scripts/patch-smoke-local-build.sh b/scripts/patch-smoke-local-build.sh new file mode 100755 index 000000000..145d0a97d --- /dev/null +++ b/scripts/patch-smoke-local-build.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# +# patch-smoke-local-build.sh — Post-compilation script for local-build smoke testing +# +# The smoke test .md files use sandbox.mcp.version: "latest" so that +# gh aw compile produces valid lock files that pull from the registry. +# This script patches the compiled .lock.yml files to: +# +# 1. Build a Docker image from the current checkout (with WASM guard) +# 2. Tag it as ghcr.io/github/gh-aw-mcpg:latest (overwriting the pulled image) +# +# The build step is injected AFTER the "Download container images" step +# so our locally-built image overwrites whatever was pulled from the registry. +# +# Usage: +# gh aw compile smoke-copilot && scripts/patch-smoke-local-build.sh +# gh aw compile && scripts/patch-smoke-local-build.sh # patches all smoke workflows +# +# To revert, simply re-run: gh aw compile +# +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +cd "$REPO_ROOT" + +PATCHED=0 +SKIPPED=0 + +for lockfile in .github/workflows/smoke-*.lock.yml; do + [ -f "$lockfile" ] || continue + + # Skip if already patched + if grep -q "Build MCP Gateway from source (local)" "$lockfile" 2>/dev/null; then + echo "SKIP $lockfile (already patched)" + SKIPPED=$((SKIPPED + 1)) + continue + fi + + # Skip if no mcpg image reference + if ! grep -q "gh-aw-mcpg" "$lockfile" 2>/dev/null; then + echo "SKIP $lockfile (no mcpg reference)" + SKIPPED=$((SKIPPED + 1)) + continue + fi + + # Use Python for reliable multi-line insertion with correct indentation. + python3 "$REPO_ROOT/scripts/_inject_local_build.py" "$lockfile" + + if [ $? -eq 0 ]; then + echo "PATCHED $lockfile" + PATCHED=$((PATCHED + 1)) + else + echo "SKIP $lockfile (no insertion point found)" + SKIPPED=$((SKIPPED + 1)) + fi +done + +echo "" +echo "Done: $PATCHED patched, $SKIPPED skipped" +if [ "$PATCHED" -gt 0 ]; then + echo "" + echo "The patched lock files will now build the gateway from source." + echo "To revert: gh aw compile" +fi diff --git a/test/integration/auth_config_test.go b/test/integration/auth_config_test.go index 78447a0f1..1590ac750 100644 --- a/test/integration/auth_config_test.go +++ b/test/integration/auth_config_test.go @@ -43,9 +43,9 @@ func TestOutputConfigWithAuthHeaders(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": port, - "domain": "localhost", - "apiKey": apiKey, + "port": port, + "domain": "localhost", + "agentId": apiKey, }, } configBytes, err := json.Marshal(configJSON) @@ -257,9 +257,9 @@ func TestOutputConfigUnifiedMode(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": port, - "domain": "localhost", - "apiKey": apiKey, + "port": port, + "domain": "localhost", + "agentId": apiKey, }, } configBytes, err := json.Marshal(configJSON) diff --git a/test/integration/binary_test.go b/test/integration/binary_test.go index 2a61c0105..ce5b87e50 100644 --- a/test/integration/binary_test.go +++ b/test/integration/binary_test.go @@ -50,9 +50,9 @@ func TestBinaryInvocation_RoutedMode(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13001, - "domain": "localhost", - "apiKey": "test-token", + "port": 13001, + "domain": "localhost", + "agentId": "test-token", }, } configBytes, _ := json.Marshal(configJSON) @@ -164,9 +164,9 @@ func TestBinaryInvocation_UnifiedMode(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13002, - "domain": "localhost", - "apiKey": "test-token", + "port": 13002, + "domain": "localhost", + "agentId": "test-token", }, } configBytes, _ := json.Marshal(configJSON) @@ -255,9 +255,9 @@ func TestBinaryInvocation_ConfigStdin(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13003, - "domain": "localhost", - "apiKey": "test-key", + "port": 13003, + "domain": "localhost", + "agentId": "test-key", }, } configBytes, _ := json.Marshal(configJSON) @@ -327,9 +327,9 @@ func TestBinaryInvocation_PipeOutput(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13004, - "domain": "localhost", - "apiKey": "test-pipe-key", + "port": 13004, + "domain": "localhost", + "agentId": "test-pipe-key", }, } configBytes, err := json.Marshal(configJSON) @@ -451,9 +451,9 @@ func TestBinaryInvocation_PipeInputOutput(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13005, - "domain": "localhost", - "apiKey": "test-key", + "port": 13005, + "domain": "localhost", + "agentId": "test-key", }, } configBytes, err := json.Marshal(configJSON) diff --git a/test/integration/difc_config_test.go b/test/integration/difc_config_test.go index 17aa9b786..747c79502 100644 --- a/test/integration/difc_config_test.go +++ b/test/integration/difc_config_test.go @@ -139,7 +139,7 @@ func TestDIFCEnvironmentVariables(t *testing.T) { }, "gateway": { "port": %d, - "apiKey": "test-key" + "agentId": "test-key" } }`, port) @@ -224,7 +224,7 @@ func TestDIFCConfigWithGuards(t *testing.T) { "gateway": { "port": %d, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }`, port) @@ -286,7 +286,7 @@ func TestDIFCModeFilterViaEnv(t *testing.T) { "gateway": { "port": %d, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, port) @@ -343,7 +343,7 @@ func TestDIFCModePropagateViaEnv(t *testing.T) { "gateway": { "port": %d, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, port) @@ -415,7 +415,7 @@ func TestFullDIFCConfigFromJSON(t *testing.T) { "gateway": { "port": %d, "domain": "localhost", - "apiKey": "test-key" + "agentId": "test-key" } }`, port) diff --git a/test/integration/github_test.go b/test/integration/github_test.go index 30d351237..6aa857493 100644 --- a/test/integration/github_test.go +++ b/test/integration/github_test.go @@ -43,7 +43,7 @@ func TestGitHubMCPMockBackend(t *testing.T) { "gateway": { "port": 13110, "domain": "localhost", - "apiKey": "test-github-key" + "agentId": "test-github-key" } }` @@ -273,7 +273,7 @@ func TestGitHubMCPRealBackend(t *testing.T) { "gateway": { "port": 13111, "domain": "localhost", - "apiKey": "test-github-key" + "agentId": "test-github-key" } }` diff --git a/test/integration/playwright_test.go b/test/integration/playwright_test.go index ec37531ef..1348ac7a6 100644 --- a/test/integration/playwright_test.go +++ b/test/integration/playwright_test.go @@ -68,9 +68,9 @@ func TestPlaywrightMCPServer(t *testing.T) { }, }, "gateway": map[string]interface{}{ - "port": 13100, - "domain": "localhost", - "apiKey": "test-playwright-key", + "port": 13100, + "domain": "localhost", + "agentId": "test-playwright-key", }, } @@ -420,9 +420,9 @@ CMD ["node", "mock-mcp-server.js"] }, }, "gateway": map[string]interface{}{ - "port": 13109, - "domain": "localhost", - "apiKey": "test-mock-key", + "port": 13109, + "domain": "localhost", + "agentId": "test-mock-key", }, } diff --git a/test/integration/safeinputs_http_test.go b/test/integration/safeinputs_http_test.go index 7460254b7..dd1e6e25c 100644 --- a/test/integration/safeinputs_http_test.go +++ b/test/integration/safeinputs_http_test.go @@ -151,7 +151,7 @@ func TestSafeinputsHTTPBackend(t *testing.T) { "gateway": { "port": 3001, "domain": "localhost", - "apiKey": "test-gateway-key" + "agentId": "test-gateway-key" } }`, safeinputsServer.URL) diff --git a/test/integration/tavily_test.go b/test/integration/tavily_test.go index e3b07b6d1..53686c07a 100644 --- a/test/integration/tavily_test.go +++ b/test/integration/tavily_test.go @@ -102,7 +102,7 @@ func TestTavilyHTTPBackend(t *testing.T) { "gateway": { "port": 13099, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }` @@ -252,7 +252,7 @@ func TestTavilyAuthFailure(t *testing.T) { "gateway": { "port": 13098, "domain": "localhost", - "apiKey": "test-gateway-key" + "agentId": "test-gateway-key" } }` @@ -320,7 +320,7 @@ func TestTavilyAuthFailure(t *testing.T) { "gateway": { "port": 13097, "domain": "localhost", - "apiKey": "test-gateway-key" + "agentId": "test-gateway-key" } }` @@ -485,7 +485,7 @@ func TestRealTavilyConnection(t *testing.T) { "gateway": { "port": 13099, "domain": "localhost", - "apiKey": "test-api-key" + "agentId": "test-api-key" } }` diff --git a/test/integration/tools_json_test.go b/test/integration/tools_json_test.go index 8d7b43885..574617cdc 100644 --- a/test/integration/tools_json_test.go +++ b/test/integration/tools_json_test.go @@ -101,7 +101,7 @@ func TestToolsJSONLogging(t *testing.T) { "gateway": { "port": 13120, "domain": "localhost", - "apiKey": "test-tools-key" + "agentId": "test-tools-key" } }`, mockBackend.URL, mockBackend.URL)