diff --git a/.github/workflows/auto-triage-issues.lock.yml b/.github/workflows/auto-triage-issues.lock.yml index dee80b3908e..75e04625d43 100644 --- a/.github/workflows/auto-triage-issues.lock.yml +++ b/.github/workflows/auto-triage-issues.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"25ba385233ac59f16b778a09c4c4c4b85d046210322ff53ddd44d988cb26caa5","strict":true,"agent_id":"copilot","agent_model":"gpt-5-mini"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"44ee7fb4de16d0d981ae932dfa32c8560c65a9fade7a3563dde246dcd7e4c9c6","strict":true,"agent_id":"copilot","agent_model":"gpt-5-mini"} # gh-aw-manifest: {"version":1,"secrets":["GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","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"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.42"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) @@ -213,20 +213,20 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_22c0a58162bb6a9d_EOF' + cat << 'GH_AW_PROMPT_11cff80b0d29c151_EOF' - GH_AW_PROMPT_22c0a58162bb6a9d_EOF + GH_AW_PROMPT_11cff80b0d29c151_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_22c0a58162bb6a9d_EOF' + cat << 'GH_AW_PROMPT_11cff80b0d29c151_EOF' Tools: create_discussion, add_labels(max:10), missing_tool, missing_data, noop - GH_AW_PROMPT_22c0a58162bb6a9d_EOF + GH_AW_PROMPT_11cff80b0d29c151_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_22c0a58162bb6a9d_EOF' + cat << 'GH_AW_PROMPT_11cff80b0d29c151_EOF' The following GitHub context information is available for this workflow: {{#if __GH_AW_GITHUB_ACTOR__ }} @@ -255,16 +255,16 @@ jobs: {{/if}} - GH_AW_PROMPT_22c0a58162bb6a9d_EOF + GH_AW_PROMPT_11cff80b0d29c151_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_22c0a58162bb6a9d_EOF' + cat << 'GH_AW_PROMPT_11cff80b0d29c151_EOF' {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/observability-otlp.md}} {{#runtime-import .github/workflows/shared/noop-reminder.md}} {{#runtime-import .github/workflows/auto-triage-issues.md}} - GH_AW_PROMPT_22c0a58162bb6a9d_EOF + GH_AW_PROMPT_11cff80b0d29c151_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -500,9 +500,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_ad7601bdf062f098_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_2243e03bdea2bf84_EOF' {"add_labels":{"max":10},"create_discussion":{"category":"audits","close_older_discussions":true,"expires":24,"fallback_to_issue":true,"max":1,"title_prefix":"[Auto-Triage] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_ad7601bdf062f098_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_2243e03bdea2bf84_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -714,7 +714,7 @@ jobs: 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_565c3d3852153a7c_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_dc1e7d443e156803_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "safeoutputs": { @@ -745,7 +745,7 @@ jobs: } } } - GH_AW_MCP_CONFIG_565c3d3852153a7c_EOF + GH_AW_MCP_CONFIG_dc1e7d443e156803_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/auto-triage-issues.md b/.github/workflows/auto-triage-issues.md index ed0c3669e09..d94eb79520b 100644 --- a/.github/workflows/auto-triage-issues.md +++ b/.github/workflows/auto-triage-issues.md @@ -53,6 +53,7 @@ safe-outputs: category: "audits" close-older-discussions: true max: 1 + noop: timeout-minutes: 15 features: copilot-requests: true @@ -97,9 +98,13 @@ When running on schedule: When triggered manually as a backfill pass: 1. **Fetch ALL open issues without any labels** using GitHub tools — do not limit to a fixed count -2. **Process up to 10 unlabeled issues** in this run (respecting safe-output limits); if more exist, note the remainder in the report -3. **Apply labels** to each issue based on classification rules below, using title/body heuristics and existing triage rules -4. **Create a summary report** as a discussion listing every issue processed, the labels applied, and how many unlabeled issues (if any) still remain for the next pass +2. **If there are no unlabeled issues**, call `noop` with "No unlabeled issues found during manual backfill — no action needed" and stop. Do not create a discussion. + +When unlabeled issues exist: + +3. **Process up to 10 unlabeled issues** in this run (respecting safe-output limits); if more exist, note the remainder in the report +4. **Apply labels** to each issue based on classification rules below, using title/body heuristics and existing triage rules +5. **Create a summary report** as a discussion listing every issue processed, the labels applied, and how many unlabeled issues (if any) still remain for the next pass ## Classification Rules @@ -287,6 +292,16 @@ When running on schedule, create a discussion report following these formatting - **Learn from patterns** - Over time, notice which types of issues are frequently unlabeled - **Human override** - Maintainers can change labels; this is automation assistance, not replacement +## Mandatory Completion Rule + +**Before finishing, check whether you called any safe-output tool in this run.** If you did NOT call `add_labels` or `create_discussion`, you MUST call `noop`. Every run MUST end with at least one safe-output call — failing to do so causes the workflow to fail with a safe-output compliance error. + +Situations that require a `noop` call: +- No unlabeled issues were found (all trigger types) +- The triggering issue already had appropriate labels +- All issues analyzed were already labeled or had been processed +- You were uncertain and chose not to label rather than guess incorrectly + ## Success Metrics - Reduce unlabeled issue percentage from 8.6% to <5% diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 49acd0434cb..97cda0479c1 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"74cfec818687614eb034b1fcb3b261722ba9804a51ecc2ed6cef09ac0e0c6515","strict":true,"agent_id":"claude"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"7f58bc4a3041899fa0a0d8e5845e1b89e4f77795d39e817841e96332573b3e0e","strict":true,"agent_id":"claude"} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","GH_AW_CI_TRIGGER_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_ENDPOINT","GH_AW_OTEL_HEADERS","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"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"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.42"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.25.42"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.6","digest":"sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c"},{"image":"ghcr.io/github/github-mcp-server:v1.0.3","digest":"sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959","pinned_image":"ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959"},{"image":"node:lts-alpine","digest":"sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f","pinned_image":"node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f"}]} # ___ _ _ # / _ \ | | (_) @@ -256,27 +256,27 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_4c45bf75252ca186_EOF' + cat << 'GH_AW_PROMPT_9189f0a2e98a4f36_EOF' - GH_AW_PROMPT_4c45bf75252ca186_EOF + GH_AW_PROMPT_9189f0a2e98a4f36_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/playwright_prompt.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_4c45bf75252ca186_EOF' + cat << 'GH_AW_PROMPT_9189f0a2e98a4f36_EOF' Tools: add_comment, create_pull_request, upload_asset(max:10), missing_tool, missing_data, noop - GH_AW_PROMPT_4c45bf75252ca186_EOF + GH_AW_PROMPT_9189f0a2e98a4f36_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md" - cat << 'GH_AW_PROMPT_4c45bf75252ca186_EOF' + cat << 'GH_AW_PROMPT_9189f0a2e98a4f36_EOF' upload_asset: provide a file path; returns a URL; assets are published after the workflow completes (safeoutputs). - GH_AW_PROMPT_4c45bf75252ca186_EOF + GH_AW_PROMPT_9189f0a2e98a4f36_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_4c45bf75252ca186_EOF' + cat << 'GH_AW_PROMPT_9189f0a2e98a4f36_EOF' The following GitHub context information is available for this workflow: {{#if __GH_AW_GITHUB_ACTOR__ }} @@ -305,9 +305,9 @@ jobs: {{/if}} - GH_AW_PROMPT_4c45bf75252ca186_EOF + GH_AW_PROMPT_9189f0a2e98a4f36_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/cli_proxy_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_4c45bf75252ca186_EOF' + cat << 'GH_AW_PROMPT_9189f0a2e98a4f36_EOF' {{#runtime-import .github/workflows/shared/docs-server-lifecycle.md}} {{#runtime-import .github/workflows/shared/observability-otlp.md}} @@ -315,7 +315,7 @@ jobs: {{#runtime-import .github/workflows/shared/reporting.md}} {{#runtime-import .github/workflows/shared/noop-reminder.md}} {{#runtime-import .github/workflows/unbloat-docs.md}} - GH_AW_PROMPT_4c45bf75252ca186_EOF + GH_AW_PROMPT_9189f0a2e98a4f36_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -567,11 +567,11 @@ jobs: - name: Pre-flight checks run: "mkdir -p /tmp/gh-aw/agent\n\n# Check 1: verify docs directory structure exists\nDIR_COUNT=$(find docs/src/content/docs -maxdepth 1 -type d 2>/dev/null | wc -l)\nif [ \"$DIR_COUNT\" -eq 0 ]; then\n echo '{\"pass\":false,\"reason\":\"Pre-flight failed: docs/src/content/docs directory not found — documentation structure is missing or repository is not set up correctly.\"}' \\\n > /tmp/gh-aw/agent/preflight.json\n exit 0\nfi\n\n# Check 2: count editable markdown files\nTOTAL=$(find docs/src/content/docs -path '*/blog*' -prune \\\n -o -name '*.md' -type f ! -name 'frontmatter-full.md' -print \\\n | xargs grep -rL 'disable-agentic-editing: true' 2>/dev/null \\\n | wc -l)\nif [ \"$TOTAL\" -eq 0 ]; then\n echo '{\"pass\":false,\"reason\":\"Pre-flight failed: no editable markdown files found in docs/src/content/docs (all files may be protected or excluded).\"}' \\\n > /tmp/gh-aw/agent/preflight.json\n exit 0\nfi\n\n# Check 3: count uncleaned candidates (not cleaned in the past 7 days)\nRECENT_CUTOFF=$(date -d '7 days ago' '+%Y-%m-%d' 2>/dev/null \\\n || date -v-7d '+%Y-%m-%d' 2>/dev/null \\\n || echo \"0000-00-00\")\nCLEANED=$(awk -v cutoff=\"$RECENT_CUTOFF\" \\\n 'NF>0 && $1>=cutoff{count++} END{print count+0}' \\\n /tmp/gh-aw/cache-memory/cleaned-files.txt 2>/dev/null || echo \"0\")\nUNCLEANED=$(( TOTAL - CLEANED ))\nif [ \"$UNCLEANED\" -le 0 ]; then\n echo '{\"pass\":false,\"reason\":\"Pre-flight check: all eligible documentation files were cleaned recently — nothing to do this run.\"}' \\\n > /tmp/gh-aw/agent/preflight.json\n exit 0\nfi\n\n# All checks passed — write candidate file list and preflight result\nfind docs/src/content/docs -path '*/blog*' -prune \\\n -o -name '*.md' -type f ! -name 'frontmatter-full.md' -print \\\n | xargs grep -rL 'disable-agentic-editing: true' 2>/dev/null \\\n > /tmp/gh-aw/agent/candidate-files.txt\nprintf '{\"pass\":true,\"reason\":\"All pre-flight checks passed. %d uncleaned candidates available.\",\"uncleaned\":%d,\"total\":%d}\\n' \\\n \"$UNCLEANED\" \"$UNCLEANED\" \"$TOTAL\" \\\n > /tmp/gh-aw/agent/preflight.json\n\necho \"Pre-flight passed: $UNCLEANED uncleaned candidates out of $TOTAL eligible files\"\necho \"Candidate files written to /tmp/gh-aw/agent/candidate-files.txt\"\n" - name: Start documentation dev server - run: "mkdir -p /tmp/gh-aw\ncd docs\nnohup npm run dev -- --host 0.0.0.0 --port 4321 > /tmp/gh-aw/preview.log 2>&1 &\nPID=$!\necho $PID > /tmp/gh-aw/server.pid\necho \"Dev server started (PID: $PID)\"\n" + run: "# Skip if pre-flight check failed — no need to start the server\nif [ \"$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)\" != \"true\" ]; then\n echo \"Pre-flight check failed, skipping server startup\"\n exit 0\nfi\nmkdir -p /tmp/gh-aw\ncd docs\nnohup npm run dev -- --host 0.0.0.0 --port 4321 > /tmp/gh-aw/preview.log 2>&1 &\nPID=$!\necho $PID > /tmp/gh-aw/server.pid\necho \"Dev server started (PID: $PID)\"\n" - name: Wait for documentation server readiness - run: "URL=\"http://localhost:4321/gh-aw/\"\nSTATUS=\"\"\necho \"Readiness check target: $URL\"\necho \"Preview log: /tmp/gh-aw/preview.log\"\nfor i in $(seq 1 45); do\n STATUS=$(curl -sS -o /dev/null -w \"%{http_code}\" --connect-timeout 5 --max-time 5 \"$URL\" || true)\n [ \"$STATUS\" = \"200\" ] && echo \"Server ready at $URL\" && break\n if [ -z \"$STATUS\" ]; then STATUS=\"curl_error\"; fi\n echo \"Waiting for server... ($i/45) (status: $STATUS)\"\n sleep 3\ndone\nif [ \"$STATUS\" != \"200\" ]; then\n echo \"Dev server failed to start after 135 seconds:\"\n echo \"Final readiness status: $STATUS\"\n cat /tmp/gh-aw/preview.log || true\n exit 1\nfi\n" + run: "# Skip if pre-flight check failed — server was not started\nif [ \"$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)\" != \"true\" ]; then\n echo \"Pre-flight check failed, skipping server readiness check\"\n exit 0\nfi\nURL=\"http://localhost:4321/gh-aw/\"\nSTATUS=\"\"\necho \"Readiness check target: $URL\"\necho \"Preview log: /tmp/gh-aw/preview.log\"\nfor i in $(seq 1 45); do\n STATUS=$(curl -sS -o /dev/null -w \"%{http_code}\" --connect-timeout 5 --max-time 5 \"$URL\" || true)\n [ \"$STATUS\" = \"200\" ] && echo \"Server ready at $URL\" && break\n if [ -z \"$STATUS\" ]; then STATUS=\"curl_error\"; fi\n echo \"Waiting for server... ($i/45) (status: $STATUS)\"\n sleep 3\ndone\nif [ \"$STATUS\" != \"200\" ]; then\n echo \"Dev server failed to start after 135 seconds:\"\n echo \"Final readiness status: $STATUS\"\n cat /tmp/gh-aw/preview.log || true\n exit 1\nfi\n" - name: Write Playwright base URL - run: "mkdir -p /tmp/gh-aw/agent\necho \"http://localhost:4321/gh-aw/\" > /tmp/gh-aw/agent/playwright-base-url.txt\necho \"Playwright base URL: http://localhost:4321/gh-aw/\"\n" + run: "# Skip if pre-flight check failed — server was not started\nif [ \"$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)\" != \"true\" ]; then\n echo \"Pre-flight check failed, skipping Playwright base URL setup\"\n exit 0\nfi\nmkdir -p /tmp/gh-aw/agent\necho \"http://localhost:4321/gh-aw/\" > /tmp/gh-aw/agent/playwright-base-url.txt\necho \"Playwright base URL: http://localhost:4321/gh-aw/\"\n" - name: Download container images run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.25.42 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.42 ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.42 ghcr.io/github/gh-aw-firewall/squid:0.25.42 ghcr.io/github/gh-aw-mcpg:v0.3.6@sha256:2bb8eef86006a4c5963c55616a9c51c32f27bfdecb023b8aa6f91f6718d9171c ghcr.io/github/github-mcp-server:v1.0.3@sha256:2ac27ef03461ef2b877031b838a7d1fd7f12b12d4ace7796d8cad91446d55959 node:lts-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f @@ -582,9 +582,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_f296a80275c5ed4e_EOF + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << GH_AW_SAFE_OUTPUTS_CONFIG_1b9d75dd88ccaf40_EOF {"add_comment":{"max":1},"create_pull_request":{"auto_merge":true,"draft":true,"expires":48,"fallback_as_issue":false,"labels":["documentation","automation","doc-unbloat"],"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","CLAUDE.md","AGENTS.md"],"reviewers":["copilot"],"title_prefix":"[docs] "},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"report_incomplete":{},"upload_asset":{"allowed-exts":[".png",".jpg",".jpeg",".svg"],"branch":"assets/${GITHUB_WORKFLOW}","max":10,"max-size":10240}} - GH_AW_SAFE_OUTPUTS_CONFIG_f296a80275c5ed4e_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_1b9d75dd88ccaf40_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -826,7 +826,7 @@ jobs: 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 /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 -e GITHUB_AW_OTEL_TRACE_ID -e GITHUB_AW_OTEL_PARENT_SPAN_ID -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.6' GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_4d4edb42845b5641_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_370d51e4f92ff7c4_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "safeoutputs": { @@ -857,7 +857,7 @@ jobs: } } } - GH_AW_MCP_CONFIG_4d4edb42845b5641_EOF + GH_AW_MCP_CONFIG_370d51e4f92ff7c4_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/unbloat-docs.md b/.github/workflows/unbloat-docs.md index 3212773ee04..ed7cf9f6e87 100644 --- a/.github/workflows/unbloat-docs.md +++ b/.github/workflows/unbloat-docs.md @@ -172,6 +172,11 @@ pre-agent-steps: - name: Start documentation dev server run: | + # Skip if pre-flight check failed — no need to start the server + if [ "$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)" != "true" ]; then + echo "Pre-flight check failed, skipping server startup" + exit 0 + fi mkdir -p /tmp/gh-aw cd docs nohup npm run dev -- --host 0.0.0.0 --port 4321 > /tmp/gh-aw/preview.log 2>&1 & @@ -181,6 +186,11 @@ pre-agent-steps: - name: Wait for documentation server readiness run: | + # Skip if pre-flight check failed — server was not started + if [ "$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)" != "true" ]; then + echo "Pre-flight check failed, skipping server readiness check" + exit 0 + fi URL="http://localhost:4321/gh-aw/" STATUS="" echo "Readiness check target: $URL" @@ -201,6 +211,11 @@ pre-agent-steps: - name: Write Playwright base URL run: | + # Skip if pre-flight check failed — server was not started + if [ "$(jq -r '.pass' /tmp/gh-aw/agent/preflight.json 2>/dev/null)" != "true" ]; then + echo "Pre-flight check failed, skipping Playwright base URL setup" + exit 0 + fi mkdir -p /tmp/gh-aw/agent echo "http://localhost:4321/gh-aw/" > /tmp/gh-aw/agent/playwright-base-url.txt echo "Playwright base URL: http://localhost:4321/gh-aw/" @@ -237,7 +252,7 @@ You are a technical documentation editor focused on **clarity and conciseness**. ## 0. Pre-flight Validation -Read `/tmp/gh-aw/agent/preflight.json`. If `"pass"` is `false`, call `noop` with the `"reason"` value and stop. +Read `/tmp/gh-aw/agent/preflight.json`. If `"pass"` is `false`, **immediately** call `noop` with the `"reason"` value and stop — do not read any other files beyond `preflight.json`, do not proceed with any further steps. This is mandatory: failing to call `noop` when preflight fails causes a safe-output compliance error. Only proceed if `"pass"` is `true`. The list of candidate files is already available at `/tmp/gh-aw/agent/candidate-files.txt` (one path per line).