diff --git a/.github/workflows/test-coverage-improver.lock.yml b/.github/workflows/test-coverage-improver.lock.yml
index 21183d5ad..fb70b8cda 100644
--- a/.github/workflows/test-coverage-improver.lock.yml
+++ b/.github/workflows/test-coverage-improver.lock.yml
@@ -1,5 +1,5 @@
-# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"73c07969cb1951cf335f814f20b8ecd04537d9bbc91ab324bfd95cf93405b4eb","compiler_version":"v0.76.1","strict":true,"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/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"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:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
+# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"07d1365e42a101fbfb8e189a652aaa260496359f17ddeb41104fec5041d4dadc","body_hash":"ce1e16c1f324887176d0d9c058cd2a265c18b5bd70720376ddb0db425bb1c24a","compiler_version":"v0.77.5","strict":true,"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/checkout","sha":"de0fac2e4500dabe0009e67214ff5f5447ce83dd","version":"v6.0.2"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"3ea13c02d765410340d533515cb31a7eef2baaf0","version":"v0.77.5"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.58"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.22"},{"image":"ghcr.io/github/github-mcp-server:v1.1.0","digest":"sha256:71b07d9abecb83b4a2595bcd8ccb35f9a0166361a12335f9e16da1ef07172029","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.0@sha256:71b07d9abecb83b4a2595bcd8ccb35f9a0166361a12335f9e16da1ef07172029"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]}
# ___ _ _
# / _ \ | | (_)
# | |_| | __ _ ___ _ __ | |_ _ ___
@@ -14,7 +14,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
-# This file was automatically generated by gh-aw (v0.76.1). DO NOT EDIT.
+# This file was automatically generated by gh-aw (v0.77.5). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -40,14 +40,14 @@
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
-# - github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+# - github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
#
# Container images used:
-# - 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
+# - ghcr.io/github/gh-aw-firewall/agent:0.25.58
+# - ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58
+# - ghcr.io/github/gh-aw-firewall/squid:0.25.58
+# - ghcr.io/github/gh-aw-mcpg:v0.3.22
+# - ghcr.io/github/github-mcp-server:v1.1.0@sha256:71b07d9abecb83b4a2595bcd8ccb35f9a0166361a12335f9e16da1ef07172029
# - node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
name: "Test Coverage Improver"
@@ -94,7 +94,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+ uses: github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -103,25 +103,25 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/test-coverage-improver.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.52"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_ENGINE_ID: "copilot"
- 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 || '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.76.1"
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AGENT_VERSION: "1.0.55"
+ GH_AW_INFO_CLI_VERSION: "v0.77.5"
GH_AW_INFO_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_INFO_EXPERIMENTAL: "false"
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
GH_AW_INFO_STAGED: "false"
GH_AW_INFO_ALLOWED_DOMAINS: '["github"]'
GH_AW_INFO_FIREWALL_ENABLED: "true"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
@@ -164,7 +164,7 @@ jobs:
- name: Check compile-agentic version
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
- GH_AW_COMPILED_VERSION: "v0.76.1"
+ GH_AW_COMPILED_VERSION: "v0.77.5"
with:
script: |
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
@@ -187,28 +187,29 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_STEPS_TARGET_OUTPUTS_SOURCE_CONTENT: ${{ steps.target.outputs.SOURCE_CONTENT }}
GH_AW_STEPS_TARGET_OUTPUTS_TARGET_FILE: ${{ steps.target.outputs.TARGET_FILE }}
+ GH_AW_STEPS_TARGET_OUTPUTS_TARGET_TEST_FILE: ${{ steps.target.outputs.TARGET_TEST_FILE }}
GH_AW_STEPS_TARGET_OUTPUTS_TEST_CONTENT: ${{ steps.target.outputs.TEST_CONTENT }}
# poutine:ignore untrusted_checkout_exec
run: |
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
{
- cat << 'GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF'
+ cat << 'GH_AW_PROMPT_7fc07581d5fceee1_EOF'
- GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF
+ GH_AW_PROMPT_7fc07581d5fceee1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
- cat << 'GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF'
+ cat << 'GH_AW_PROMPT_7fc07581d5fceee1_EOF'
Tools: add_comment, create_pull_request, missing_tool, missing_data, noop
- GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF
+ GH_AW_PROMPT_7fc07581d5fceee1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
- cat << 'GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF'
+ cat << 'GH_AW_PROMPT_7fc07581d5fceee1_EOF'
- GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF
+ GH_AW_PROMPT_7fc07581d5fceee1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
- cat << 'GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF'
+ cat << 'GH_AW_PROMPT_7fc07581d5fceee1_EOF'
The following GitHub context information is available for this workflow:
{{#if github.actor}}
@@ -237,12 +238,12 @@ jobs:
{{/if}}
- GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF
+ GH_AW_PROMPT_7fc07581d5fceee1_EOF
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
- cat << 'GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF'
+ cat << 'GH_AW_PROMPT_7fc07581d5fceee1_EOF'
{{#runtime-import .github/workflows/test-coverage-improver.md}}
- GH_AW_PROMPT_bd2a9a8ce5f5c390_EOF
+ GH_AW_PROMPT_7fc07581d5fceee1_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
@@ -254,6 +255,7 @@ jobs:
GH_AW_EXPR_998C0DF8: ${{ steps.low-coverage.outputs.LOW_COVERAGE }}
GH_AW_STEPS_TARGET_OUTPUTS_SOURCE_CONTENT: ${{ steps.target.outputs.SOURCE_CONTENT }}
GH_AW_STEPS_TARGET_OUTPUTS_TARGET_FILE: ${{ steps.target.outputs.TARGET_FILE }}
+ GH_AW_STEPS_TARGET_OUTPUTS_TARGET_TEST_FILE: ${{ steps.target.outputs.TARGET_TEST_FILE }}
GH_AW_STEPS_TARGET_OUTPUTS_TEST_CONTENT: ${{ steps.target.outputs.TEST_CONTENT }}
with:
script: |
@@ -279,6 +281,7 @@ jobs:
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
GH_AW_STEPS_TARGET_OUTPUTS_SOURCE_CONTENT: ${{ steps.target.outputs.SOURCE_CONTENT }}
GH_AW_STEPS_TARGET_OUTPUTS_TARGET_FILE: ${{ steps.target.outputs.TARGET_FILE }}
+ GH_AW_STEPS_TARGET_OUTPUTS_TARGET_TEST_FILE: ${{ steps.target.outputs.TARGET_TEST_FILE }}
GH_AW_STEPS_TARGET_OUTPUTS_TEST_CONTENT: ${{ steps.target.outputs.TEST_CONTENT }}
with:
script: |
@@ -305,6 +308,7 @@ jobs:
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
GH_AW_STEPS_TARGET_OUTPUTS_SOURCE_CONTENT: process.env.GH_AW_STEPS_TARGET_OUTPUTS_SOURCE_CONTENT,
GH_AW_STEPS_TARGET_OUTPUTS_TARGET_FILE: process.env.GH_AW_STEPS_TARGET_OUTPUTS_TARGET_FILE,
+ GH_AW_STEPS_TARGET_OUTPUTS_TARGET_TEST_FILE: process.env.GH_AW_STEPS_TARGET_OUTPUTS_TARGET_TEST_FILE,
GH_AW_STEPS_TARGET_OUTPUTS_TEST_CONTENT: process.env.GH_AW_STEPS_TARGET_OUTPUTS_TEST_CONTENT
}
});
@@ -326,6 +330,7 @@ jobs:
include-hidden-files: true
path: |
/tmp/gh-aw/aw_info.json
+ /tmp/gh-aw/model_multipliers.json
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw-prompts/prompt-template.txt
/tmp/gh-aw/aw-prompts/prompt-import-tree.json
@@ -346,6 +351,7 @@ jobs:
pull-requests: read
concurrency:
group: "gh-aw-copilot-${{ github.workflow }}"
+ queue: max
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
GH_AW_ASSETS_ALLOWED_EXTS: ""
@@ -371,7 +377,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+ uses: github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -380,8 +386,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/test-coverage-improver.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.52"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Set runtime paths
id: set-runtime-paths
@@ -435,6 +441,7 @@ jobs:
echo "EOF"
} >> "$GITHUB_OUTPUT"
TEST_FILE="${TARGET%.ts}.test.ts"
+ echo "TARGET_TEST_FILE=$TEST_FILE" >> "$GITHUB_OUTPUT"
{
echo "TEST_CONTENT</dev/null || echo "(test file does not exist yet)"
@@ -443,6 +450,15 @@ jobs:
- id: low-coverage
name: List files below 80% coverage
run: "{\n echo \"LOW_COVERAGE< k !== 'total' && v.statements.pct < 80)\n .sort((a, b) => a[1].statements.pct - b[1].statements.pct);\n if (low.length === 0) { console.log('All files are above 80% coverage.'); }\n else { low.forEach(([k, v]) => console.log(k + ' \\u2014 ' + v.statements.pct + '%')); }\n \" 2>/dev/null || echo \"(coverage summary not available)\"\n echo \"EOF\"\n} >> \"$GITHUB_OUTPUT\"\n"
+ - env:
+ COVERAGE_MD: ${{ steps.coverage-md.outputs.COVERAGE_MD }}
+ LOW_COVERAGE: ${{ steps.low-coverage.outputs.LOW_COVERAGE }}
+ SOURCE_CONTENT: ${{ steps.target.outputs.SOURCE_CONTENT }}
+ TARGET_FILE: ${{ steps.target.outputs.TARGET_FILE }}
+ TARGET_TEST_FILE: ${{ steps.target.outputs.TARGET_TEST_FILE }}
+ TEST_CONTENT: ${{ steps.target.outputs.TEST_CONTENT }}
+ name: Verify injected context
+ run: "echo \"TARGET_FILE: $TARGET_FILE\"\necho \"TARGET_TEST_FILE: $TARGET_TEST_FILE\"\n[ -n \"$TARGET_FILE\" ] || { echo \"::error::TARGET_FILE empty\"; exit 1; }\n[ -n \"$TARGET_TEST_FILE\" ] || { echo \"::error::TARGET_TEST_FILE empty\"; exit 1; }\n[ -n \"$SOURCE_CONTENT\" ] || { echo \"::error::SOURCE_CONTENT empty\"; exit 1; }\n[ -n \"$TEST_CONTENT\" ] || { echo \"::error::TEST_CONTENT empty\"; exit 1; }\n[ -n \"$COVERAGE_MD\" ] || { echo \"::error::COVERAGE_MD empty\"; exit 1; }\n[ -n \"$LOW_COVERAGE\" ] || { echo \"::error::LOW_COVERAGE empty\"; exit 1; }\n"
- name: Configure Git credentials
env:
@@ -472,7 +488,7 @@ jobs:
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Install GitHub Copilot CLI
- run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.52
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.55
env:
GH_HOST: github.com
- name: Install awf dependencies
@@ -531,15 +547,15 @@ jobs:
GH_AW_SKILL_DIR: ".github/skills"
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
- name: Download container images
- run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.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:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
+ run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.58 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.58 ghcr.io/github/gh-aw-firewall/squid:0.25.58 ghcr.io/github/gh-aw-mcpg:v0.3.22 ghcr.io/github/github-mcp-server:v1.1.0@sha256:71b07d9abecb83b4a2595bcd8ccb35f9a0166361a12335f9e16da1ef07172029 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f
- 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_1ee996852a2f6172_EOF'
+ cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_c592ad9523d00176_EOF'
{"add_comment":{"max":1,"target":"*"},"create_pull_request":{"draft":true,"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":"[Test Coverage] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}}
- GH_AW_SAFE_OUTPUTS_CONFIG_1ee996852a2f6172_EOF
+ GH_AW_SAFE_OUTPUTS_CONFIG_c592ad9523d00176_EOF
- name: Generate Safe Outputs Tools
env:
GH_AW_TOOLS_META_JSON: |
@@ -771,21 +787,21 @@ 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.19'
+ 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.22'
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_d499424d3c10f5ee_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
+ cat << GH_AW_MCP_CONFIG_af540deedce009f8_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
{
"mcpServers": {
"github": {
"type": "stdio",
- "container": "ghcr.io/github/github-mcp-server:v1.0.4",
+ "container": "ghcr.io/github/github-mcp-server:v1.1.0@sha256:71b07d9abecb83b4a2595bcd8ccb35f9a0166361a12335f9e16da1ef07172029",
"env": {
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
"GITHUB_READ_ONLY": "1",
- "GITHUB_TOOLSETS": "repos,pull_requests"
+ "GITHUB_TOOLSETS": "repos"
},
"guard-policies": {
"allow-only": {
@@ -816,7 +832,7 @@ jobs:
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
}
}
- GH_AW_MCP_CONFIG_d499424d3c10f5ee_EOF
+ GH_AW_MCP_CONFIG_af540deedce009f8_EOF
- name: Mount MCP servers as CLIs
id: mount-mcp-clis
continue-on-error: true
@@ -883,26 +899,36 @@ 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.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","codeload.github.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","lfs.github.com","objects.githubusercontent.com","patch-diff.githubusercontent.com","raw.githubusercontent.com","registry.npmjs.org","telemetry.enterprise.githubcopilot.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"
+ printf '%s\n' '{"$schema":"https://github.com/github/gh-aw-firewall/releases/download/v0.25.58/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","codeload.github.com","docs.github.com","github-cloud.githubusercontent.com","github-cloud.s3.amazonaws.com","github.blog","github.com","github.githubassets.com","host.docker.internal","lfs.github.com","objects.githubusercontent.com","patch-diff.githubusercontent.com","raw.githubusercontent.com","registry.npmjs.org","telemetry.enterprise.githubcopilot.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-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.58"}}' > "${RUNNER_TEMP}/gh-aw/awf-config.json"
+ GH_AW_MODEL_MULTIPLIERS_PATH="/tmp/gh-aw/model_multipliers.json" node "${RUNNER_TEMP}/gh-aw/actions/merge_awf_model_multipliers.cjs"
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
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
fi
+ GH_AW_TOOL_CACHE_MOUNT=""
+ GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
+ if [ -d "$GH_AW_TOOL_CACHE" ]; then
+ if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
+ GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
+ fi
+ elif [ -d "/home/runner/work/_tool" ]; then
+ GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
+ fi
# shellcheck disable=SC1003
- sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --session-state-dir /tmp/gh-aw/sandbox/agent/session-state --enable-host-access --allow-host-ports 80,443,8080 --build-local \
- -- /bin/bash -c 'export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(./node_modules/.bin/eslint:*)'\'' --allow-tool '\''shell(./node_modules/.bin/jest:*)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cat:jest.config.js)'\'' --allow-tool '\''shell(cat:jest.config.ts)'\'' --allow-tool '\''shell(cat:src/*.test.ts)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(node:*)'\'' --allow-tool '\''shell(npm run lint)'\'' --allow-tool '\''shell(npm run test)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
+ sudo -E awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --session-state-dir /tmp/gh-aw/sandbox/agent/session-state --enable-host-access --allow-host-ports 80,443,8080 --build-local \
+ -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-tool github --allow-tool safeoutputs --allow-tool '\''shell(./node_modules/.bin/eslint:*)'\'' --allow-tool '\''shell(./node_modules/.bin/jest:*)'\'' --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(cat:jest.config.js)'\'' --allow-tool '\''shell(cat:jest.config.ts)'\'' --allow-tool '\''shell(cat:src/*.test.ts)'\'' --allow-tool '\''shell(date)'\'' --allow-tool '\''shell(echo)'\'' --allow-tool '\''shell(git add:*)'\'' --allow-tool '\''shell(git branch:*)'\'' --allow-tool '\''shell(git checkout:*)'\'' --allow-tool '\''shell(git commit:*)'\'' --allow-tool '\''shell(git merge:*)'\'' --allow-tool '\''shell(git rm:*)'\'' --allow-tool '\''shell(git status)'\'' --allow-tool '\''shell(git switch:*)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(node:*)'\'' --allow-tool '\''shell(npm run lint)'\'' --allow-tool '\''shell(npm run test)'\'' --allow-tool '\''shell(printf)'\'' --allow-tool '\''shell(pwd)'\'' --allow-tool '\''shell(safeoutputs:*)'\'' --allow-tool '\''shell(sort)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(uniq)'\'' --allow-tool '\''shell(wc)'\'' --allow-tool '\''shell(yq)'\'' --allow-tool write --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
AWF_REFLECT_ENABLED: 1
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'claude-sonnet-4.6' }}
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
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.76.1
+ GH_AW_VERSION: v0.77.5
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
@@ -916,6 +942,7 @@ jobs:
GIT_AUTHOR_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
+ RUNNER_TEMP: ${{ runner.temp }}
XDG_CONFIG_HOME: /home/runner
- name: Detect agent errors
if: always()
@@ -1111,7 +1138,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+ uses: github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1120,8 +1147,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/test-coverage-improver.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.52"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1236,15 +1263,15 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+ uses: github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
env:
GH_AW_SETUP_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/test-coverage-improver.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.52"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Check team membership for workflow
id: check_membership
@@ -1289,7 +1316,7 @@ jobs:
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
GH_AW_ENGINE_ID: "copilot"
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
- GH_AW_ENGINE_VERSION: "1.0.52"
+ GH_AW_ENGINE_VERSION: "1.0.55"
GH_AW_WORKFLOW_ID: "test-coverage-improver"
GH_AW_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/test-coverage-improver.md"
@@ -1307,7 +1334,7 @@ jobs:
steps:
- name: Setup Scripts
id: setup
- uses: github/gh-aw-actions/setup@46d564922b082d0db93244972e8005ea6904ee5f # v0.76.1
+ uses: github/gh-aw-actions/setup@3ea13c02d765410340d533515cb31a7eef2baaf0 # v0.77.5
with:
destination: ${{ runner.temp }}/gh-aw/actions
job-name: ${{ github.job }}
@@ -1316,8 +1343,8 @@ jobs:
env:
GH_AW_SETUP_WORKFLOW_NAME: "Test Coverage Improver"
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/test-coverage-improver.lock.yml@${{ github.ref }}
- GH_AW_INFO_VERSION: "1.0.52"
- GH_AW_INFO_AWF_VERSION: "v0.25.55"
+ GH_AW_INFO_VERSION: "1.0.55"
+ GH_AW_INFO_AWF_VERSION: "v0.25.58"
GH_AW_INFO_ENGINE_ID: "copilot"
- name: Download agent output artifact
id: download-agent-output
@@ -1342,26 +1369,13 @@ jobs:
- name: Extract base branch from agent output
id: extract-base-branch
if: steps.download-agent-output.outcome == 'success'
- shell: bash
- run: |
- if [ -f "/tmp/gh-aw/agent_output.json" ]; then
- GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node)
- BASE_BRANCH=$("$GH_AW_NODE" -e "
- try {
- const data = JSON.parse(require('fs').readFileSync('/tmp/gh-aw/agent_output.json', 'utf8'));
- const item = (data.items || []).find(i =>
- (i.type === 'create_pull_request' || i.type === 'push_to_pull_request_branch') &&
- i.base_branch
- );
- if (item) process.stdout.write(item.base_branch);
- } catch(e) {}
- " 2>/dev/null || true)
- # Validate: only allow safe git branch name characters
- if [[ "$BASE_BRANCH" =~ ^[a-zA-Z0-9/_.-]+$ ]] && [ ${#BASE_BRANCH} -le 255 ]; then
- printf 'base-branch=%s\n' "$BASE_BRANCH" >> "$GITHUB_OUTPUT"
- echo "Extracted base branch from safe output: $BASE_BRANCH"
- fi
- fi
+ uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
+ setupGlobals(core, github, context, exec, io, getOctokit);
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/extract_base_branch_from_agent_output.cjs');
+ await main();
- name: Checkout repository (trusted default branch for comment events)
if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') && (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
diff --git a/.github/workflows/test-coverage-improver.md b/.github/workflows/test-coverage-improver.md
index a6f7fae23..05ea87d25 100644
--- a/.github/workflows/test-coverage-improver.md
+++ b/.github/workflows/test-coverage-improver.md
@@ -27,7 +27,7 @@ network:
tools:
github:
- toolsets: [repos, pull_requests]
+ toolsets: [repos]
bash:
- "npm run test"
- "npm run lint"
@@ -88,6 +88,7 @@ steps:
echo "EOF"
} >> "$GITHUB_OUTPUT"
TEST_FILE="${TARGET%.ts}.test.ts"
+ echo "TARGET_TEST_FILE=$TEST_FILE" >> "$GITHUB_OUTPUT"
{
echo "TEST_CONTENT</dev/null || echo "(test file does not exist yet)"
@@ -110,6 +111,24 @@ steps:
echo "EOF"
} >> "$GITHUB_OUTPUT"
+ - name: Verify injected context
+ env:
+ COVERAGE_MD: ${{ steps.coverage-md.outputs.COVERAGE_MD }}
+ LOW_COVERAGE: ${{ steps.low-coverage.outputs.LOW_COVERAGE }}
+ SOURCE_CONTENT: ${{ steps.target.outputs.SOURCE_CONTENT }}
+ TARGET_FILE: ${{ steps.target.outputs.TARGET_FILE }}
+ TARGET_TEST_FILE: ${{ steps.target.outputs.TARGET_TEST_FILE }}
+ TEST_CONTENT: ${{ steps.target.outputs.TEST_CONTENT }}
+ run: |
+ echo "TARGET_FILE: $TARGET_FILE"
+ echo "TARGET_TEST_FILE: $TARGET_TEST_FILE"
+ [ -n "$TARGET_FILE" ] || { echo "::error::TARGET_FILE empty"; exit 1; }
+ [ -n "$TARGET_TEST_FILE" ] || { echo "::error::TARGET_TEST_FILE empty"; exit 1; }
+ [ -n "$SOURCE_CONTENT" ] || { echo "::error::SOURCE_CONTENT empty"; exit 1; }
+ [ -n "$TEST_CONTENT" ] || { echo "::error::TEST_CONTENT empty"; exit 1; }
+ [ -n "$COVERAGE_MD" ] || { echo "::error::COVERAGE_MD empty"; exit 1; }
+ [ -n "$LOW_COVERAGE" ] || { echo "::error::LOW_COVERAGE empty"; exit 1; }
+
---
# Test Coverage Improver
@@ -127,24 +146,27 @@ This is **gh-aw-firewall**, a network firewall for GitHub Copilot CLI that provi
## Turn Budget
-**Complete this task in ≤ 10 tool calls.** The target file and its current tests are already injected below — do not re-read them. The coverage summary is already provided. Jump directly to writing tests.
+**Complete this task in ≤ 10 tool calls.** The target file and its current tests are already injected below — do not re-read them unless the injected section is unexpectedly empty. The coverage summary is already provided. Jump directly to writing tests.
Expected sequence:
1. Write the new/updated test file (1 call)
-2. `npm run test` (1 call) — fix any failures in ≤ 2 more calls
-3. `npm run lint` (1 call) — fix any issues in ≤ 1 more call
-4. Create PR (1 call)
+2. Targeted rerun only when needed: `./node_modules/.bin/jest --testPathPattern= --no-coverage 2>&1 | tail -60`
+3. `npm run test` (1 call, final verification only)
+4. `npm run lint` (1 call) — fix any issues in ≤ 1 more call
+5. Create PR (1 call)
## Your Task
The target file is pre-selected below. Write Jest unit tests that:
- Cover uncovered functions and branches identified in the coverage data
- Use `jest.mock()` for Docker/iptables/fs dependencies — no real Docker or iptables calls
-- Follow the style of existing `src/*.test.ts` files
+- Follow the style of `${{ steps.target.outputs.TARGET_TEST_FILE }}` when it exists. Do not glob-read `src/*.test.ts` for style reference.
- Focus on error-handling paths and edge cases (empty input, malformed domains, failures)
- Do NOT modify or remove existing passing tests
-Run `npm run test` then `npm run lint`, fix any issues, then open a draft PR titled `[Test Coverage] `.
+If the injected target section below is unexpectedly empty, use `cat` to read `${{ steps.target.outputs.TARGET_FILE }}` directly before writing tests.
+
+Run targeted Jest reruns only when fixing failures, run full `npm run test` at most once for final verification, then run `npm run lint` and open a draft PR titled `[Test Coverage] `.
## Target File (pre-selected)
diff --git a/scripts/ci/test-coverage-improver-workflow.test.ts b/scripts/ci/test-coverage-improver-workflow.test.ts
index 97238571d..904ecba48 100644
--- a/scripts/ci/test-coverage-improver-workflow.test.ts
+++ b/scripts/ci/test-coverage-improver-workflow.test.ts
@@ -9,20 +9,30 @@ describe('test coverage improver workflow token optimization config', () => {
it('preselects target file and trims prompt/tool surface in source workflow', () => {
const source = fs.readFileSync(sourcePath, 'utf-8');
+ expect(source).toContain('toolsets: [repos]');
+ expect(source).not.toContain('toolsets: [repos, pull_requests]');
expect(source).toContain('cat:src/*.test.ts');
expect(source).toContain('node:*');
expect(source).toContain('./node_modules/.bin/jest:*');
expect(source).toContain('./node_modules/.bin/eslint:*');
expect(source).toContain('Select target file and inject content');
expect(source).toContain('TARGET_FILE=$TARGET');
+ expect(source).toContain('TARGET_TEST_FILE=$TEST_FILE');
expect(source).toContain('SOURCE_CONTENT< --no-coverage 2>&1 | tail -60');
expect(source).toContain('## Target File (pre-selected)');
expect(source).toContain('${{ steps.target.outputs.TARGET_FILE }}');
+ expect(source).toContain('${{ steps.target.outputs.TARGET_TEST_FILE }}');
expect(source).toContain('${{ steps.target.outputs.SOURCE_CONTENT }}');
expect(source).toContain('${{ steps.target.outputs.TEST_CONTENT }}');
+ expect(source).toContain('Do not glob-read `src/*.test.ts` for style reference.');
+ expect(source).toContain('Run targeted Jest reruns only when fixing failures');
expect(source).not.toContain('cat:src/docker-manager.ts');
expect(source).not.toContain('cat:src/cli.ts');
@@ -49,9 +59,19 @@ describe('test coverage improver workflow token optimization config', () => {
expect(lock).toContain("shell(./node_modules/.bin/eslint:*)");
expect(lock).toContain('name: Select target file and inject content');
expect(lock).toContain('TARGET_FILE=$TARGET');
+ expect(lock).toContain('TARGET_TEST_FILE=$TEST_FILE');
expect(lock).toContain('SOURCE_CONTENT<