From 7b8a46daf58b2f8aa0b5c8cfa805dd1d928f565e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 08:30:09 +0000 Subject: [PATCH 1/3] Initial plan From b0e9742f88f6a7ceae1a8cb9bb7e3fc4d3de9d7f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 08:54:49 +0000 Subject: [PATCH 2/3] fix: correct Squid access.log path and add presence detection - daily-observability-report.md: fix canonical path from sandbox/firewall/logs/access.log to sandbox/firewall/logs/squid-logs/access.log (current AWF layout), keep legacy path as fallback, and replace the native Squid format description with the AWF custom 10-field format - generate_observability_summary.cjs: add squidAccessLogPresent field (checks both current squid-logs/ and legacy path) and emit a warning line in the step summary when the access.log is missing on a firewall-enabled run - generate_observability_summary.test.cjs: add 4 tests covering present (squid-logs/ path), present (legacy path), missing, and firewall- disabled cases - print_firewall_logs.sh: after chown/chmod, probe both access.log paths and emit a stderr WARNING when neither is found so operators can spot the gap directly in the job log Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../daily-observability-report.lock.yml | 2 +- .../workflows/daily-observability-report.md | 8 ++-- .../js/generate_observability_summary.cjs | 21 ++++++++- .../generate_observability_summary.test.cjs | 46 +++++++++++++++++++ actions/setup/sh/print_firewall_logs.sh | 15 ++++++ 5 files changed, 87 insertions(+), 5 deletions(-) diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index 5e0387ca45f..0b1fae88caf 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8eff6279f5da2ba7608a503707e2d33445ee0f296b248a1d9a6871a379620e84","body_hash":"ca1cef62a86074fb44791b0a09bd6e04a1bfa8694ab055d64fee6d54c053b32e","strict":true,"agent_id":"codex","agent_model":"gpt-5.4","engine_versions":{"codex":"0.146.0"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"8eff6279f5da2ba7608a503707e2d33445ee0f296b248a1d9a6871a379620e84","body_hash":"072111f09bd0d42e786abf987fea3cb9949c7775f67ad573502c68e8e211c575","strict":true,"agent_id":"codex","agent_model":"gpt-5.4","engine_versions":{"codex":"0.146.0"}} # gh-aw-manifest: {"version":1,"secrets":["CODEX_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN","OPENAI_API_KEY"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-go","sha":"b7ad1dad31e06c5925ef5d2fc7ad053ef454303e","version":"v7.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"docker/build-push-action","sha":"53b7df96c91f9c12dcc8a07bcb9ccacbed38856a","version":"v7.3.0"},{"repo":"docker/setup-buildx-action","sha":"bb05f3f5519dd87d3ba754cc423b652a5edd6d2c","version":"v4.2.0"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.43","digest":"sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.43@sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.43","digest":"sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.43@sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.43","digest":"sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab","pinned_image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.27.43@sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.43","digest":"sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.43@sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.7","digest":"sha256:7545220a9aca134b71e51193ee0eaf4c50756ebf8fbd25a63ae7556e62815c00","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.7@sha256:7545220a9aca134b71e51193ee0eaf4c50756ebf8fbd25a63ae7556e62815c00"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.8.0","digest":"sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520","pinned_image":"ghcr.io/github/github-mcp-server:v1.8.0@sha256:d5a18c04b92714c309eb46a2305087e91a4dbd80420f6e462656699f95093520"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # diff --git a/.github/workflows/daily-observability-report.md b/.github/workflows/daily-observability-report.md index e53d15230e4..49bea609cdd 100644 --- a/.github/workflows/daily-observability-report.md +++ b/.github/workflows/daily-observability-report.md @@ -141,14 +141,16 @@ The AWF Firewall uses Squid proxy for egress control. The key log file is `acces For each firewall-enabled workflow run, check: 1. **access.log existence**: Search recursively inside each run folder for firewall access logs - - Canonical path: `/tmp/gh-aw/aw-mcp/logs/run-/sandbox/firewall/logs/access.log` + - Canonical path (current AWF layout): `run-/sandbox/firewall/logs/squid-logs/access.log` + - Also accept the legacy path: `run-/sandbox/firewall/logs/access.log` (older AWF layout) - Also accept equivalent paths nested under artifact-prefixed directories (workflow_call) - Do not assume a fixed top-level location; use recursive discovery 2. **access.log content quality**: - Are there log entries present? - - Do entries follow squid format: `timestamp duration client status size method url user hierarchy type` - - Are both allowed and blocked requests logged? + - Do entries follow AWF custom format: `timestamp client_ip:port domain dest_ip:port proto method status decision url user_agent` + - Example entry: `1761332530.474 172.30.0.20:35288 api.github.com:443 140.82.112.22:443 1.1 CONNECT 200 TCP_TUNNEL:HIER_DIRECT api.github.com:443 "-"` + - Are both allowed (TCP_TUNNEL) and blocked (TCP_DENIED) requests logged? 3. **Firewall configuration**: - Check `aw_info.json` for firewall settings: diff --git a/actions/setup/js/generate_observability_summary.cjs b/actions/setup/js/generate_observability_summary.cjs index 680a56440dc..73aaa27d70d 100644 --- a/actions/setup/js/generate_observability_summary.cjs +++ b/actions/setup/js/generate_observability_summary.cjs @@ -8,6 +8,8 @@ const AGENT_OUTPUT_PATH = "/tmp/gh-aw/agent_output.json"; const OTLP_EXPORT_ERRORS_PATH = "/tmp/gh-aw/otlp-export-errors.count"; const OTLP_EXPORT_ERROR_DETAILS_PATH = "/tmp/gh-aw/otlp-export-errors.jsonl"; const gatewayEventPaths = ["/tmp/gh-aw/mcp-logs/gateway.jsonl", "/tmp/gh-aw/mcp-logs/rpc-messages.jsonl"]; +// Squid access log paths: current AWF layout (squid-logs/ subdirectory) and legacy layout (directly under logs/). +const squidAccessLogPaths = ["/tmp/gh-aw/sandbox/firewall/logs/squid-logs/access.log", "/tmp/gh-aw/sandbox/firewall/logs/access.log"]; function readJSONIfExists(path) { if (!fs.existsSync(path)) { @@ -63,6 +65,15 @@ function uniqueCreatedItemTypes(items) { return [...types].sort(); } +function checkSquidAccessLogPresent() { + for (const path of squidAccessLogPaths) { + if (fs.existsSync(path)) { + return true; + } + } + return false; +} + function readOTLPExportErrorCount() { if (!fs.existsSync(OTLP_EXPORT_ERRORS_PATH)) { return 0; @@ -117,12 +128,14 @@ function collectObservabilityData() { // Do NOT fall back to workflow_call_id — it is not a valid OTLP trace ID. const traceId = process.env.GITHUB_AW_OTEL_TRACE_ID || (awInfo.context ? awInfo.context.otel_trace_id || "" : ""); + const firewallEnabled = awInfo.firewall_enabled === true; return { workflowName: awInfo.workflow_name || "", engineId: awInfo.engine_id || "", traceId, staged: awInfo.staged === true, - firewallEnabled: awInfo.firewall_enabled === true, + firewallEnabled, + squidAccessLogPresent: firewallEnabled ? checkSquidAccessLogPresent() : null, createdItemCount: items.length, createdItemTypes: uniqueCreatedItemTypes(items), outputErrorCount: errors.length, @@ -156,6 +169,12 @@ function buildObservabilitySummary(data) { lines.push(`- **agent output errors**: ${data.outputErrorCount}`); lines.push(`- **otlp export errors**: ${data.otlpExportErrors}`); lines.push(`- **firewall enabled**: ${data.firewallEnabled}`); + if (data.firewallEnabled && data.squidAccessLogPresent !== null) { + lines.push(`- **squid access.log present**: ${data.squidAccessLogPresent}`); + if (!data.squidAccessLogPresent) { + lines.push("- Squid access.log not found; egress traffic for this run cannot be audited."); + } + } lines.push(`- **staged**: ${data.staged}`); if (data.otlpExportErrors > 0) { diff --git a/actions/setup/js/generate_observability_summary.test.cjs b/actions/setup/js/generate_observability_summary.test.cjs index d8e9585ebc1..ade5d1d8ffd 100644 --- a/actions/setup/js/generate_observability_summary.test.cjs +++ b/actions/setup/js/generate_observability_summary.test.cjs @@ -28,6 +28,8 @@ describe("generate_observability_summary.cjs", () => { "/tmp/gh-aw/otlp-export-errors.jsonl", "/tmp/gh-aw/mcp-logs/gateway.jsonl", "/tmp/gh-aw/mcp-logs/rpc-messages.jsonl", + "/tmp/gh-aw/sandbox/firewall/logs/squid-logs/access.log", + "/tmp/gh-aw/sandbox/firewall/logs/access.log", ]) { if (fs.existsSync(path)) { fs.unlinkSync(path); @@ -133,4 +135,48 @@ describe("generate_observability_summary.cjs", () => { expect(mockCore.summary.addRaw).toHaveBeenCalledTimes(1); expect(mockCore.summary.write).toHaveBeenCalledTimes(1); }); + + it("reports squid access.log present when firewall enabled and file exists at squid-logs path", async () => { + fs.mkdirSync("/tmp/gh-aw/sandbox/firewall/logs/squid-logs", { recursive: true }); + fs.writeFileSync("/tmp/gh-aw/sandbox/firewall/logs/squid-logs/access.log", '1761332530.474 172.30.0.20:35288 api.github.com:443 140.82.112.22:443 1.1 CONNECT 200 TCP_TUNNEL:HIER_DIRECT api.github.com:443 "-"\n'); + fs.writeFileSync("/tmp/gh-aw/aw_info.json", JSON.stringify({ workflow_name: "firewall-workflow", firewall_enabled: true })); + + await module.main(mockCore); + + const summary = mockCore.summary.addRaw.mock.calls[0][0]; + expect(summary).toContain("- **squid access.log present**: true"); + expect(summary).not.toContain("egress traffic for this run cannot be audited"); + }); + + it("reports squid access.log present when firewall enabled and file exists at legacy path", async () => { + fs.mkdirSync("/tmp/gh-aw/sandbox/firewall/logs", { recursive: true }); + fs.writeFileSync("/tmp/gh-aw/sandbox/firewall/logs/access.log", '1761332530.474 172.30.0.20:35288 api.github.com:443 140.82.112.22:443 1.1 CONNECT 200 TCP_TUNNEL:HIER_DIRECT api.github.com:443 "-"\n'); + fs.writeFileSync("/tmp/gh-aw/aw_info.json", JSON.stringify({ workflow_name: "firewall-workflow", firewall_enabled: true })); + + await module.main(mockCore); + + const summary = mockCore.summary.addRaw.mock.calls[0][0]; + expect(summary).toContain("- **squid access.log present**: true"); + expect(summary).not.toContain("egress traffic for this run cannot be audited"); + }); + + it("warns when firewall enabled but squid access.log is missing", async () => { + fs.writeFileSync("/tmp/gh-aw/aw_info.json", JSON.stringify({ workflow_name: "firewall-workflow", firewall_enabled: true })); + + await module.main(mockCore); + + const summary = mockCore.summary.addRaw.mock.calls[0][0]; + expect(summary).toContain("- **squid access.log present**: false"); + expect(summary).toContain("Squid access.log not found; egress traffic for this run cannot be audited."); + }); + + it("omits squid access.log status when firewall is disabled", async () => { + fs.writeFileSync("/tmp/gh-aw/aw_info.json", JSON.stringify({ workflow_name: "no-firewall-workflow", firewall_enabled: false })); + + await module.main(mockCore); + + const summary = mockCore.summary.addRaw.mock.calls[0][0]; + expect(summary).not.toContain("squid access.log"); + expect(summary).not.toContain("egress traffic for this run cannot be audited"); + }); }); diff --git a/actions/setup/sh/print_firewall_logs.sh b/actions/setup/sh/print_firewall_logs.sh index 66cc637db68..341798cf4e0 100755 --- a/actions/setup/sh/print_firewall_logs.sh +++ b/actions/setup/sh/print_firewall_logs.sh @@ -50,3 +50,18 @@ if command -v awf &> /dev/null; then else echo 'AWF binary not installed, skipping firewall log summary' fi + +# Warn if Squid access.log is missing (current layout: squid-logs/; legacy layout: directly under logs/). +# A missing access.log means egress traffic for this run cannot be audited. +ACCESS_LOG_FOUND=false +for candidate in \ + "${AWF_LOGS_DIR}/squid-logs/access.log" \ + "${AWF_LOGS_DIR}/access.log"; do + if [[ -f "${candidate}" ]]; then + ACCESS_LOG_FOUND=true + break + fi +done +if [[ "${ACCESS_LOG_FOUND}" == "false" ]]; then + echo "WARNING: Squid access.log not found under ${AWF_LOGS_DIR}; egress traffic for this run cannot be audited." >&2 +fi From 3fc686d0ea96a7d726aa4c30a0a36b8545d107e8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 1 Aug 2026 22:01:24 +0000 Subject: [PATCH 3/3] fix: normalize Copilot version in wasm golden tests Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../testdata/TestWasmGolden_AllEngines/copilot.golden | 10 +++++----- pkg/workflow/wasm_golden_test.go | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden b/pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden index 9ed37af4ab4..4a1288a536f 100644 --- a/pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden +++ b/pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden @@ -62,7 +62,7 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "engine-copilot-test" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/workflow.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.75" + GH_AW_INFO_VERSION: "COPILOT_VERSION" GH_AW_INFO_AWF_VERSION: "vAWF_VERSION" GH_AW_INFO_ENGINE_ID: "copilot" - name: Generate agentic run info @@ -71,8 +71,8 @@ jobs: GH_AW_INFO_ENGINE_ID: "copilot" GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI" GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'default' }} - GH_AW_INFO_VERSION: "1.0.75" - GH_AW_INFO_AGENT_VERSION: "1.0.75" + GH_AW_INFO_VERSION: "COPILOT_VERSION" + GH_AW_INFO_AGENT_VERSION: "COPILOT_VERSION" GH_AW_INFO_WORKFLOW_NAME: "engine-copilot-test" GH_AW_INFO_EXPERIMENTAL: "false" GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true" @@ -367,7 +367,7 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "engine-copilot-test" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/workflow.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.75" + GH_AW_INFO_VERSION: "COPILOT_VERSION" GH_AW_INFO_AWF_VERSION: "vAWF_VERSION" GH_AW_INFO_ENGINE_ID: "copilot" - name: Checkout repository @@ -714,7 +714,7 @@ jobs: env: GH_AW_SETUP_WORKFLOW_NAME: "engine-copilot-test" GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/workflow.lock.yml@${{ github.ref }} - GH_AW_INFO_VERSION: "1.0.75" + GH_AW_INFO_VERSION: "COPILOT_VERSION" GH_AW_INFO_AWF_VERSION: "vAWF_VERSION" GH_AW_INFO_ENGINE_ID: "copilot" - name: Check team membership for workflow diff --git a/pkg/workflow/wasm_golden_test.go b/pkg/workflow/wasm_golden_test.go index 178dc53a1f0..4dea5899ee2 100644 --- a/pkg/workflow/wasm_golden_test.go +++ b/pkg/workflow/wasm_golden_test.go @@ -33,6 +33,8 @@ var testDefaultAWFSchemaURLRE = regexp.MustCompile(`(releases/download/)` + rege var testDefaultAWFImageTagRE = regexp.MustCompile(`("imageTag"\s*:\s*")(?:v)?` + regexp.QuoteMeta(strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v")) + `"`) var testDefaultMCPGImageRE = regexp.MustCompile(`(ghcr\.io/github/gh-aw-mcpg:)` + regexp.QuoteMeta(string(constants.DefaultMCPGatewayVersion)) + `\b`) var testDefaultGitHubMCPServerImageRE = regexp.MustCompile(`(ghcr\.io/github/github-mcp-server:)` + regexp.QuoteMeta(string(constants.DefaultGitHubMCPServerVersion)) + `\b`) +var testDefaultCopilotInfoVersionRE = regexp.MustCompile(`GH_AW_INFO_VERSION: "` + regexp.QuoteMeta(string(constants.DefaultCopilotVersion)) + `"`) +var testDefaultCopilotAgentInfoVersionRE = regexp.MustCompile(`GH_AW_INFO_AGENT_VERSION: "` + regexp.QuoteMeta(string(constants.DefaultCopilotVersion)) + `"`) var testDefaultCodexInfoVersionRE = regexp.MustCompile(`GH_AW_INFO_VERSION: "` + regexp.QuoteMeta(string(constants.DefaultCodexVersion)) + `"`) var testDefaultCodexAgentInfoVersionRE = regexp.MustCompile(`GH_AW_INFO_AGENT_VERSION: "` + regexp.QuoteMeta(string(constants.DefaultCodexVersion)) + `"`) var testDefaultCodexInstallVersionRE = regexp.MustCompile(`(@openai/codex@)` + regexp.QuoteMeta(string(constants.DefaultCodexVersion)) + `\b`) @@ -48,6 +50,8 @@ func normalizeDefaultRuntimeVersions(content string) string { normalized = testDefaultAWFImageRE.ReplaceAllString(normalized, `${1}AWF_VERSION`) normalized = testDefaultAWFSchemaURLRE.ReplaceAllString(normalized, `${1}vAWF_VERSION$2`) normalized = testDefaultAWFImageTagRE.ReplaceAllString(normalized, `${1}AWF_VERSION"`) + normalized = testDefaultCopilotInfoVersionRE.ReplaceAllString(normalized, `GH_AW_INFO_VERSION: "COPILOT_VERSION"`) + normalized = testDefaultCopilotAgentInfoVersionRE.ReplaceAllString(normalized, `GH_AW_INFO_AGENT_VERSION: "COPILOT_VERSION"`) normalized = testDefaultCodexInfoVersionRE.ReplaceAllString(normalized, `GH_AW_INFO_VERSION: "CODEX_VERSION"`) normalized = testDefaultCodexAgentInfoVersionRE.ReplaceAllString(normalized, `GH_AW_INFO_AGENT_VERSION: "CODEX_VERSION"`) normalized = testDefaultCodexInstallVersionRE.ReplaceAllString(normalized, `${1}CODEX_VERSION`) @@ -94,6 +98,8 @@ func TestNormalizeOutput_DefaultRuntimeVersions(t *testing.T) { `run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:` + strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v") + ` ghcr.io/github/gh-aw-firewall/api-proxy:` + strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v") + ` ghcr.io/github/gh-aw-mcpg:` + string(constants.DefaultMCPGatewayVersion), `{"schema":"https://github.com/github/gh-aw-firewall/releases/download/` + string(constants.DefaultFirewallVersion) + `/awf-config.schema.json","imageTag":"` + string(constants.DefaultFirewallVersion) + `"}`, `GH_AW_MODEL_DETECTION_CLAUDE: ${{ vars.GH_AW_MODEL_DETECTION_CLAUDE || vars.GH_AW_DEFAULT_MODEL_CLAUDE || '` + constants.SonnetDefaultModel + `' }}`, + `GH_AW_INFO_VERSION: "` + string(constants.DefaultCopilotVersion) + `"`, + `GH_AW_INFO_AGENT_VERSION: "` + string(constants.DefaultCopilotVersion) + `"`, `GH_AW_INFO_VERSION: "` + string(constants.DefaultCodexVersion) + `"`, `GH_AW_INFO_AGENT_VERSION: "` + string(constants.DefaultCodexVersion) + `"`, `GH_AW_INFO_VERSION: "` + string(constants.DefaultPiVersion) + `"`, @@ -114,6 +120,8 @@ func TestNormalizeOutput_DefaultRuntimeVersions(t *testing.T) { require.Contains(t, normalized, `releases/download/vAWF_VERSION/awf-config.schema.json`) require.Contains(t, normalized, `"imageTag":"AWF_VERSION"`) require.Contains(t, normalized, `GH_AW_MODEL_DETECTION_CLAUDE: ${{ vars.GH_AW_MODEL_DETECTION_CLAUDE || vars.GH_AW_DEFAULT_MODEL_CLAUDE || 'default' }}`) + require.Contains(t, normalized, `GH_AW_INFO_VERSION: "COPILOT_VERSION"`) + require.Contains(t, normalized, `GH_AW_INFO_AGENT_VERSION: "COPILOT_VERSION"`) require.Contains(t, normalized, `GH_AW_INFO_VERSION: "CODEX_VERSION"`) require.Contains(t, normalized, `GH_AW_INFO_AGENT_VERSION: "CODEX_VERSION"`) require.Contains(t, normalized, `GH_AW_INFO_VERSION: "PI_VERSION"`) @@ -126,6 +134,7 @@ func TestNormalizeOutput_DefaultRuntimeVersions(t *testing.T) { require.NotContains(t, normalized, string(constants.DefaultFirewallVersion)) require.NotContains(t, normalized, string(constants.DefaultMCPGatewayVersion)) require.NotContains(t, normalized, constants.SonnetDefaultModel) + require.NotContains(t, normalized, string(constants.DefaultCopilotVersion)) require.NotContains(t, normalized, string(constants.DefaultCodexVersion)) require.NotContains(t, normalized, string(constants.DefaultPiVersion)) }