diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index a42bf8bf11..fc8fc0dd84 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -932,6 +932,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "ACE Editor Session" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} with: github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 69573f91fc..f044b9ee27 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -1168,6 +1168,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Archie" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ“Š *Diagram rendered by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"footerWorkflowRecompile\":\"\\u003e ๐Ÿ”ง *Workflow sync report by [{workflow_name}]({run_url}) for {repository}*\",\"footerWorkflowRecompileComment\":\"\\u003e ๐Ÿ”„ *Update from [{workflow_name}]({run_url}) for {repository}*\",\"runStarted\":\"๐Ÿ“ [{workflow_name}]({run_url}) is analyzing the architecture for this {event_type}...\",\"runSuccess\":\"๐ŸŽจ [{workflow_name}]({run_url}) has completed the architecture visualization. โœ…\",\"runFailure\":\"๐Ÿ“ [{workflow_name}]({run_url}) encountered an issue and could not complete the architecture diagram. Check the [run logs]({run_url}) for details.\"}" diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 61a60f4d5d..2c85c23cf6 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -1120,6 +1120,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Brave Web Search Agent" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿฆ *Search results brought to you by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"footerWorkflowRecompile\":\"\\u003e ๐Ÿ”„ *Maintenance report by [{workflow_name}]({run_url}) for {repository}*\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) is searching the web on this {event_type}.\",\"runSuccess\":\"โœ… Research complete. [{workflow_name}]({run_url}) has returned with results.\",\"runFailure\":\"โŒ Search failed. [{workflow_name}]({run_url}) {status}. Unable to retrieve web sources.\"}" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index f289f32dc5..eab83077ef 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -1330,6 +1330,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "CI Failure Doctor" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿฉบ *Diagnosis provided by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿฅ CI Doctor reporting for duty! [{workflow_name}]({run_url}) is examining the patient on this {event_type}...\",\"runSuccess\":\"๐Ÿฉบ Examination complete! [{workflow_name}]({run_url}) has delivered the diagnosis. Prescription issued! ๐Ÿ’Š\",\"runFailure\":\"๐Ÿฅ Medical emergency! [{workflow_name}]({run_url}) {status}. Doctor needs assistance...\"}" diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 72e899ee46..126bf56b2d 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -1474,6 +1474,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "/cloclo" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐ŸŽค *Magnifique! Performance by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐ŸŽต Comme d'habitude! [{workflow_name}]({run_url}) takes the stage on this {event_type}...\",\"runSuccess\":\"๐ŸŽค Bravo! [{workflow_name}]({run_url}) has delivered a stunning performance! Standing ovation! ๐ŸŒŸ\",\"runFailure\":\"๐ŸŽต Intermission... [{workflow_name}]({run_url}) {status}. Check the [run logs]({run_url}) for details.\"}" diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 9a62524381..da783d1e57 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -1119,6 +1119,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Workflow Craft Agent" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e โš’๏ธ *Crafted with care by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ› ๏ธ Master Crafter at work! [{workflow_name}]({run_url}) is forging a new workflow on this {event_type}...\",\"runSuccess\":\"โš’๏ธ Masterpiece complete! [{workflow_name}]({run_url}) has crafted your workflow. May it serve you well! ๐ŸŽ–๏ธ\",\"runFailure\":\"๐Ÿ› ๏ธ Forge cooling down! [{workflow_name}]({run_url}) {status}. The anvil awaits another attempt...\"}" diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index fcef366bee..1bd2966bc9 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -1047,6 +1047,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Dev" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} with: diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 03fe0d8dcd..3619e26577 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -1214,6 +1214,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Grumpy Code Reviewer ๐Ÿ”ฅ" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ˜ค *Reluctantly reviewed by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ˜ค *sigh* [{workflow_name}]({run_url}) is begrudgingly looking at this {event_type}... This better be worth my time.\",\"runSuccess\":\"๐Ÿ˜ค Fine. [{workflow_name}]({run_url}) finished the review. It wasn't completely terrible. I guess. ๐Ÿ™„\",\"runFailure\":\"๐Ÿ˜ค Great. [{workflow_name}]({run_url}) {status}. As if my day couldn't get any worse...\"}" @@ -1370,18 +1371,18 @@ jobs: DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 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 /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 CODEX_HOME -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' - cat > "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" << GH_AW_MCP_CONFIG_b8a1f34f4ae5266f_EOF + cat > "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" << GH_AW_MCP_CONFIG_33fb30495dfdd08c_EOF [history] persistence = "none" [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "HOME", "OPENAI_API_KEY", "PATH"] - GH_AW_MCP_CONFIG_b8a1f34f4ae5266f_EOF + GH_AW_MCP_CONFIG_33fb30495dfdd08c_EOF # Generate JSON config for MCP gateway GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_1adc1e72cba56c66_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_f7ffab7f474c9e26_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { }, @@ -1392,11 +1393,11 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_1adc1e72cba56c66_EOF + GH_AW_MCP_CONFIG_f7ffab7f474c9e26_EOF # Sync converter output to writable CODEX_HOME for Codex mkdir -p /tmp/gh-aw/mcp-config - cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_9c859e275d0d3c71_EOF + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_d3877b54128a0dd7_EOF model_provider = "openai-proxy" [model_providers.openai-proxy] name = "OpenAI AWF proxy" @@ -1406,7 +1407,7 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "HOME", "OPENAI_API_KEY", "PATH"] - GH_AW_CODEX_SHELL_POLICY_9c859e275d0d3c71_EOF + GH_AW_CODEX_SHELL_POLICY_d3877b54128a0dd7_EOF awk ' BEGIN { skip_openai_proxy = 0 } /^[[:space:]]*model_provider[[:space:]]*=/ { next } diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 4eaf436ce0..4d11a24471 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -1133,6 +1133,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Mergefest" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} with: diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index d885f289bd..2b01169072 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -1219,6 +1219,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Resource Summarizer Agent" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ“„ *Summary compiled by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ“– Page by page! [{workflow_name}]({run_url}) is reading through this {event_type}...\",\"runSuccess\":\"๐Ÿ“š TL;DR ready! [{workflow_name}]({run_url}) has distilled the essence. Knowledge condensed! โœจ\",\"runFailure\":\"๐Ÿ“– Reading interrupted! [{workflow_name}]({run_url}) {status}. The document remains unsummarized...\"}" diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 17e9ce57e1..ec505c3e97 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -1133,6 +1133,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Plan Command" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} with: diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 4bcb89d667..70593d99fa 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -1488,6 +1488,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Poem Bot - A Creative Agentic Workflow" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿชถ *Verses penned by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐ŸŽญ Hear ye! The muse stirs! [{workflow_name}]({run_url}) takes quill in hand for this {event_type}...\",\"runSuccess\":\"๐Ÿชถ The poem is writ! [{workflow_name}]({run_url}) has composed verses most fair. Applause! ๐Ÿ‘\",\"runFailure\":\"๐ŸŽญ Alas! [{workflow_name}]({run_url}) {status}. The muse has fled, leaving verses unsung...\"}" diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index a6902a8e23..80c576fdc6 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -1212,6 +1212,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "PR Nitpick Reviewer ๐Ÿ”" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ” *Meticulously inspected by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ฌ Adjusting monocle... [{workflow_name}]({run_url}) is scrutinizing every pixel of this {event_type}...\",\"runSuccess\":\"๐Ÿ” Nitpicks catalogued! [{workflow_name}]({run_url}) has documented all the tiny details. Perfection awaits! โœ…\",\"runFailure\":\"๐Ÿ”ฌ Lens cracked! [{workflow_name}]({run_url}) {status}. Some nitpicks remain undetected...\"}" diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 8442103928..ac1601c039 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -1381,6 +1381,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Q" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐ŸŽฉ *Equipped by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ง Pay attention, 007! [{workflow_name}]({run_url}) is preparing your gadgets for this {event_type}...\",\"runSuccess\":\"๐ŸŽฉ Mission equipment ready! [{workflow_name}]({run_url}) has optimized your workflow. Use wisely, 007! ๐Ÿ”ซ\",\"runFailure\":\"๐Ÿ”ง Technical difficulties! [{workflow_name}]({run_url}) {status}. Even Q Branch has bad days...\"}" diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 131bd1a0cc..ae41b2a18c 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -1394,6 +1394,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Scout" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”ญ *Intelligence gathered by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ•๏ธ Scout on patrol! [{workflow_name}]({run_url}) is blazing trails through this {event_type}...\",\"runSuccess\":\"๐Ÿ”ญ Recon complete! [{workflow_name}]({run_url}) has charted the territory. Map ready! ๐Ÿ—บ๏ธ\",\"runFailure\":\"๐Ÿ•๏ธ Lost in the wilderness! [{workflow_name}]({run_url}) {status}. Sending search party...\"}" diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index ab0645c645..356026c173 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -1258,6 +1258,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Security Review Agent ๐Ÿ”’" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”’ *Security review by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) is analyzing this {event_type} for security implications...\",\"runSuccess\":\"๐Ÿ”’ [{workflow_name}]({run_url}) completed the security review.\",\"runFailure\":\"โš ๏ธ [{workflow_name}]({run_url}) {status} during security review.\"}" diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index b41b985444..62e641ab27 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -1157,6 +1157,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Agent: all/merged" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿค– *Guard policy smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) testing guard policy: `repos=all, min-integrity=merged`...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed guard policy test.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) {status}. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 43d8e214cb..477bcf8422 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -1157,6 +1157,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Agent: all/none" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿค– *Guard policy smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) testing guard policy: `repos=all, min-integrity=none`...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed guard policy test.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) {status}. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 7fc08f596c..039cb55900 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -1191,6 +1191,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Agent: public/approved" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_ASSIGNMENT_ERROR_COUNT: ${{ needs.safe_outputs.outputs.assign_to_agent_assignment_error_count }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 4717cb9cb9..f84dab62b3 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -1157,6 +1157,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Agent: public/none" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿค– *Guard policy smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) testing guard policy: `repos=public, min-integrity=none`...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed guard policy test.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) {status}. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index c8c7bfd7d0..727fd1d73c 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -1164,6 +1164,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Agent: scoped/approved" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿค– *Guard policy smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ” [{workflow_name}]({run_url}) testing guard policy: `repos=[github/gh-aw, github/*], min-integrity=approved`...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed guard policy test.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) {status}. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 90f2369e3e..b7190ba711 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2653,6 +2653,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Claude" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ’ฅ *[THE END] โ€” Illustrated by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ’ฅ **WHOOSH!** [{workflow_name}]({run_url}) springs into action on this {event_type}! *[Panel 1 begins...]*\",\"runSuccess\":\"๐ŸŽฌ **THE END** โ€” [{workflow_name}]({run_url}) **MISSION: ACCOMPLISHED!** The hero saves the day! โœจ\",\"runFailure\":\"๐Ÿ’ซ **TO BE CONTINUED...** [{workflow_name}]({run_url}) {status}! Our hero faces unexpected challenges...\"}" diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 6a2ff55245..6316c39ba8 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1662,6 +1662,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Codex" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”ฎ *The oracle has spoken through [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ฎ The ancient spirits stir... [{workflow_name}]({run_url}) awakens to divine this {event_type}...\",\"runSuccess\":\"โœจ The prophecy is fulfilled... [{workflow_name}]({run_url}) has completed its mystical journey. The stars align. ๐ŸŒŸ\",\"runFailure\":\"๐ŸŒ‘ The shadows whisper... [{workflow_name}]({run_url}) {status}. The oracle requires further meditation...\"}" @@ -1818,18 +1819,18 @@ jobs: DOCKER_SOCK_GID=$(stat -c '%g' /var/run/docker.sock 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 /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 CODEX_HOME -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' - cat > "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" << GH_AW_MCP_CONFIG_94a77813d4bad05e_EOF + cat > "${RUNNER_TEMP}/gh-aw/mcp-config/config.toml" << GH_AW_MCP_CONFIG_4d13921d00dbdc33_EOF [history] persistence = "none" [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "HOME", "OPENAI_API_KEY", "PATH"] - GH_AW_MCP_CONFIG_94a77813d4bad05e_EOF + GH_AW_MCP_CONFIG_4d13921d00dbdc33_EOF # Generate JSON config for MCP gateway GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_fc0daa387f5c3ba3_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_c35bc37f77a22946_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { }, @@ -1840,11 +1841,11 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_fc0daa387f5c3ba3_EOF + GH_AW_MCP_CONFIG_c35bc37f77a22946_EOF # Sync converter output to writable CODEX_HOME for Codex mkdir -p /tmp/gh-aw/mcp-config - cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_b63107afce308251_EOF + cat > "/tmp/gh-aw/mcp-config/config.toml" << GH_AW_CODEX_SHELL_POLICY_2072aeba9b6741df_EOF model_provider = "openai-proxy" [model_providers.openai-proxy] name = "OpenAI AWF proxy" @@ -1854,7 +1855,7 @@ jobs: [shell_environment_policy] inherit = "core" include_only = ["CODEX_API_KEY", "HOME", "OPENAI_API_KEY", "PATH"] - GH_AW_CODEX_SHELL_POLICY_b63107afce308251_EOF + GH_AW_CODEX_SHELL_POLICY_2072aeba9b6741df_EOF awk ' BEGIN { skip_openai_proxy = 0 } /^[[:space:]]*model_provider[[:space:]]*=/ { next } diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index d651401f0e..c51b0e025f 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -2071,6 +2071,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Copilot ARM64" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ“ฐ *BREAKING: Report filed by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"appendOnlyComments\":true,\"runStarted\":\"๐Ÿ“ฐ BREAKING: [{workflow_name}]({run_url}) is now investigating this {event_type}. Sources say the story is developing...\",\"runSuccess\":\"๐Ÿ“ฐ VERDICT: [{workflow_name}]({run_url}) has concluded. All systems operational. This is a developing story. ๐ŸŽค\",\"runFailure\":\"๐Ÿ“ฐ DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident...\"}" diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 249f8ba8ea..ef06ee0377 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -2173,6 +2173,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Copilot" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ“ฐ *BREAKING: Report filed by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"appendOnlyComments\":true,\"runStarted\":\"๐Ÿ“ฐ BREAKING: [{workflow_name}]({run_url}) is now investigating this {event_type}. Sources say the story is developing...\",\"runSuccess\":\"๐Ÿ“ฐ VERDICT: [{workflow_name}]({run_url}) has concluded. All systems operational. This is a developing story. ๐ŸŽค\",\"runFailure\":\"๐Ÿ“ฐ DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident...\"}" diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 1cd16a432a..ea9e1566ea 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -1213,6 +1213,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Create Cross-Repo PR" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”ฌ *Cross-repo smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ฌ [{workflow_name}]({run_url}) is testing cross-repo PR creation in github/gh-aw-side-repo...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) successfully created a cross-repo PR in github/gh-aw-side-repo!\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) failed to create a cross-repo PR: {status}\"}" diff --git a/.github/workflows/smoke-crush.lock.yml b/.github/workflows/smoke-crush.lock.yml index cb41cc7bd1..fbaa830d43 100644 --- a/.github/workflows/smoke-crush.lock.yml +++ b/.github/workflows/smoke-crush.lock.yml @@ -1248,6 +1248,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Crush" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e โšก *[{workflow_name}]({run_url}) โ€” Powered by Crush*\",\"runStarted\":\"โšก Crush initializing... [{workflow_name}]({run_url}) begins on this {event_type}...\",\"runSuccess\":\"๐ŸŽฏ [{workflow_name}]({run_url}) **MISSION COMPLETE!** Crush has delivered. โšก\",\"runFailure\":\"โš ๏ธ [{workflow_name}]({run_url}) {status}. Crush encountered unexpected challenges...\"}" diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 6801f39530..ceebb24abd 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -1344,6 +1344,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Gemini" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e โœจ *[{workflow_name}]({run_url}) โ€” Powered by Gemini*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"โœจ Gemini awakens... [{workflow_name}]({run_url}) begins its journey on this {event_type}...\",\"runSuccess\":\"๐Ÿš€ [{workflow_name}]({run_url}) **MISSION COMPLETE!** Gemini has spoken. โœจ\",\"runFailure\":\"โš ๏ธ [{workflow_name}]({run_url}) {status}. Gemini encountered unexpected challenges...\"}" diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index fa7238a589..3239595814 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -1201,6 +1201,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Multi PR" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿงช *Multi PR smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"appendOnlyComments\":true,\"runStarted\":\"๐Ÿงช [{workflow_name}]({run_url}) is now testing multiple PR creation...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) successfully created multiple PRs.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) failed to create multiple PRs. Check the logs.\"}" diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 2d5cfed020..df97cbd656 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -1285,6 +1285,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke OpenCode" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”ฅ *[{workflow_name}]({run_url}) โ€” Powered by OpenCode*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ฅ OpenCode initializing... [{workflow_name}]({run_url}) begins on this {event_type}...\",\"runSuccess\":\"๐Ÿš€ [{workflow_name}]({run_url}) **MISSION COMPLETE!** OpenCode delivered. ๐Ÿ”ฅ\",\"runFailure\":\"โš ๏ธ [{workflow_name}]({run_url}) {status}. OpenCode encountered unexpected challenges...\"}" diff --git a/.github/workflows/smoke-pi.lock.yml b/.github/workflows/smoke-pi.lock.yml index a3af37097b..f23de7b8e5 100644 --- a/.github/workflows/smoke-pi.lock.yml +++ b/.github/workflows/smoke-pi.lock.yml @@ -1278,6 +1278,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Pi" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿฅง *[{workflow_name}]({run_url}) โ€” Powered by Pi*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿฅง Pi initializing... [{workflow_name}]({run_url}) begins on this {event_type}...\",\"runSuccess\":\"๐Ÿš€ [{workflow_name}]({run_url}) **MISSION COMPLETE!** Pi delivered. ๐Ÿฅง\",\"runFailure\":\"โš ๏ธ [{workflow_name}]({run_url}) {status}. Pi encountered unexpected challenges...\"}" diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index e46a140a68..362489f52a 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -1336,6 +1336,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Project" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿงช *Project smoke test report by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"appendOnlyComments\":true,\"runStarted\":\"๐Ÿงช [{workflow_name}]({run_url}) is now testing project operations...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed successfully. All project operations validated.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) encountered failures. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index e1cba47e86..b00f07a6a8 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -1093,6 +1093,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Service Ports" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”Œ *Service ports validation by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”Œ Starting service ports validation... [{workflow_name}]({run_url}) is testing Redis connectivity...\",\"runSuccess\":\"โœ… Service ports validation passed! [{workflow_name}]({run_url}) confirms agent can reach Redis.\",\"runFailure\":\"โŒ Service ports validation failed! [{workflow_name}]({run_url}) could not reach Redis: {status}\"}" diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index 17c84d377b..bdec1e2d0a 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -1180,6 +1180,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Temporary ID" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿงช *Temporary ID smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"appendOnlyComments\":true,\"runStarted\":\"๐Ÿงช [{workflow_name}]({run_url}) is now testing temporary ID functionality...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) completed successfully. Temporary ID validation passed.\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) encountered failures. Check the logs for details.\"}" diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 0a99f8c58b..958a4d2b1a 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -1140,6 +1140,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Agent Container Smoke Test" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ”ง *Tool validation by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ”ง Starting tool validation... [{workflow_name}]({run_url}) is checking the agent container tools...\",\"runSuccess\":\"โœ… All tools validated successfully! [{workflow_name}]({run_url}) confirms agent container is ready.\",\"runFailure\":\"โŒ Tool validation failed! [{workflow_name}]({run_url}) detected missing tools: {status}\"}" diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 968a214fd2..3b0bc9983d 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -1235,6 +1235,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Smoke Update Cross-Repo PR" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ“œ *Cross-repo PR update smoke test by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ“œ [{workflow_name}]({run_url}) is adding the next Odyssey line to github/gh-aw-side-repo PR #1...\",\"runSuccess\":\"โœ… [{workflow_name}]({run_url}) successfully updated the cross-repo PR with a new Odyssey line!\",\"runFailure\":\"โŒ [{workflow_name}]({run_url}) failed to update the cross-repo PR: {status}\"}" diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 1ff012ac4b..21a4330ced 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -1192,6 +1192,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Tidy" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} with: diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 5038bd37c6..44340c6ee3 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -1376,6 +1376,7 @@ jobs: GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} GH_AW_WORKFLOW_NAME: "Documentation Unbloat" GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }} + GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }} GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }} GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }} GH_AW_SAFE_OUTPUT_MESSAGES: "{\"footer\":\"\\u003e ๐Ÿ—œ๏ธ *Compressed by [{workflow_name}]({run_url})*{effective_tokens_suffix}{history_link}\",\"runStarted\":\"๐Ÿ“ฆ Time to slim down! [{workflow_name}]({run_url}) is trimming the excess from this {event_type}...\",\"runSuccess\":\"๐Ÿ—œ๏ธ Docs on a diet! [{workflow_name}]({run_url}) has removed the bloat. Lean and mean! ๐Ÿ’ช\",\"runFailure\":\"๐Ÿ“ฆ Unbloating paused! [{workflow_name}]({run_url}) {status}. The docs remain... fluffy.\"}" diff --git a/actions/setup/js/notify_comment_error.cjs b/actions/setup/js/notify_comment_error.cjs index 19b31d69da..17f6fe0f06 100644 --- a/actions/setup/js/notify_comment_error.cjs +++ b/actions/setup/js/notify_comment_error.cjs @@ -88,10 +88,13 @@ async function tryAddNeedsReviewLabel(commentRepo) { * Map agent conclusion and assignment error count to a run-failure status string. * @param {string} agentConclusion - The agent job conclusion value * @param {number} assignToAgentErrorCount - Number of assign-to-agent errors + * @param {string|undefined} safeOutputsResult - The safe_outputs job result value * @returns {string} Human-readable status text for use in failure messages */ -function getRunFailureStatusText(agentConclusion, assignToAgentErrorCount) { - if (agentConclusion === "success" && assignToAgentErrorCount > 0) { +function getRunFailureStatusText(agentConclusion, assignToAgentErrorCount, safeOutputsResult) { + if (safeOutputsResult === "failure") { + return "failed to deliver outputs"; + } else if (agentConclusion === "success" && assignToAgentErrorCount > 0) { return "failed to assign the coding agent"; } else if (agentConclusion === "cancelled") { return "was cancelled"; @@ -113,6 +116,7 @@ async function main() { const detectionConclusion = process.env.GH_AW_DETECTION_CONCLUSION; const detectionReason = process.env.GH_AW_DETECTION_REASON || ""; const assignToAgentErrorCount = parseInt(process.env.GH_AW_ASSIGNMENT_ERROR_COUNT || "0", 10); + const safeOutputsResult = process.env.GH_AW_SAFE_OUTPUTS_RESULT; const messagesConfig = getMessages(); const appendOnlyComments = messagesConfig?.appendOnlyComments === true; @@ -134,6 +138,9 @@ async function main() { if (assignToAgentErrorCount > 0) { core.info(`Assignment Error Count: ${assignToAgentErrorCount}`); } + if (safeOutputsResult) { + core.info(`Safe Outputs Result: ${safeOutputsResult}`); + } // Load agent output to check for noop messages let noopMessages = []; @@ -196,7 +203,7 @@ async function main() { } else if (detectionConclusion && detectionConclusion === "warning") { // Detection job produced a warning (continue-on-error mode) // Show success message but append caution section with progressive disclosure - if (agentConclusion === "success" && assignToAgentErrorCount === 0) { + if (agentConclusion === "success" && assignToAgentErrorCount === 0 && safeOutputsResult !== "failure") { message = getRunSuccessMessage({ workflowName, runUrl, @@ -205,7 +212,7 @@ async function main() { message = getRunFailureMessage({ workflowName, runUrl, - status: getRunFailureStatusText(agentConclusion, assignToAgentErrorCount), + status: getRunFailureStatusText(agentConclusion, assignToAgentErrorCount, safeOutputsResult), }); } // Build the caution section for detection warning @@ -214,7 +221,7 @@ async function main() { runUrl, reason: detectionReason, }); - } else if (agentConclusion === "success" && assignToAgentErrorCount === 0) { + } else if (agentConclusion === "success" && assignToAgentErrorCount === 0 && safeOutputsResult !== "failure") { message = getRunSuccessMessage({ workflowName, runUrl, @@ -223,7 +230,7 @@ async function main() { message = getRunFailureMessage({ workflowName, runUrl, - status: getRunFailureStatusText(agentConclusion, assignToAgentErrorCount), + status: getRunFailureStatusText(agentConclusion, assignToAgentErrorCount, safeOutputsResult), }); } diff --git a/actions/setup/js/notify_comment_error.test.cjs b/actions/setup/js/notify_comment_error.test.cjs index 5482caba27..3d376e4367 100644 --- a/actions/setup/js/notify_comment_error.test.cjs +++ b/actions/setup/js/notify_comment_error.test.cjs @@ -55,6 +55,7 @@ const mockCore = { GH_AW_ASSIGNMENT_ERROR_COUNT: process.env.GH_AW_ASSIGNMENT_ERROR_COUNT, GH_AW_SAFE_OUTPUT_MESSAGES: process.env.GH_AW_SAFE_OUTPUT_MESSAGES, GH_AW_SAFE_OUTPUT_JOBS: process.env.GH_AW_SAFE_OUTPUT_JOBS, + GH_AW_SAFE_OUTPUTS_RESULT: process.env.GH_AW_SAFE_OUTPUTS_RESULT, GH_AW_OUTPUT_CREATE_ISSUE_ISSUE_URL: process.env.GH_AW_OUTPUT_CREATE_ISSUE_ISSUE_URL, GH_AW_OUTPUT_ADD_COMMENT_COMMENT_URL: process.env.GH_AW_OUTPUT_ADD_COMMENT_COMMENT_URL, GH_AW_OUTPUT_CREATE_PULL_REQUEST_PULL_REQUEST_URL: process.env.GH_AW_OUTPUT_CREATE_PULL_REQUEST_PULL_REQUEST_URL, @@ -341,5 +342,36 @@ const mockCore = { const callArgs = mockGithub.request.mock.calls[0][1]; expect(callArgs.body).toMatch(/completed successfully!$/); })); + }), + describe("when safe_outputs job fails", () => { + (it("should show failure message when agent succeeds but safe_outputs fails", async () => { + ((process.env.GH_AW_COMMENT_ID = "123456"), + (process.env.GH_AW_RUN_URL = "https://github.com/owner/repo/actions/runs/123"), + (process.env.GH_AW_WORKFLOW_NAME = "test-workflow"), + (process.env.GH_AW_AGENT_CONCLUSION = "success"), + (process.env.GH_AW_SAFE_OUTPUTS_RESULT = "failure"), + await eval(`(async () => { ${notifyCommentScript}; await main(); })()`), + expect(mockGithub.request).toHaveBeenCalledWith("PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}", expect.objectContaining({ body: expect.stringContaining("failed to deliver outputs. Please review the logs") })), + expect(mockGithub.request).not.toHaveBeenCalledWith("PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}", expect.objectContaining({ body: expect.stringContaining("completed successfully!") }))); + }), + it("should show failure message when agent succeeds, safe_outputs fails, and detection warns", async () => { + ((process.env.GH_AW_COMMENT_ID = "123456"), + (process.env.GH_AW_RUN_URL = "https://github.com/owner/repo/actions/runs/123"), + (process.env.GH_AW_WORKFLOW_NAME = "test-workflow"), + (process.env.GH_AW_AGENT_CONCLUSION = "success"), + (process.env.GH_AW_SAFE_OUTPUTS_RESULT = "failure"), + (process.env.GH_AW_DETECTION_CONCLUSION = "warning"), + await eval(`(async () => { ${notifyCommentScript}; await main(); })()`), + expect(mockGithub.request).toHaveBeenCalledWith("PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}", expect.objectContaining({ body: expect.stringContaining("failed to deliver outputs. Please review the logs") }))); + }), + it("should show success message when agent succeeds and safe_outputs succeeds", async () => { + ((process.env.GH_AW_COMMENT_ID = "123456"), + (process.env.GH_AW_RUN_URL = "https://github.com/owner/repo/actions/runs/123"), + (process.env.GH_AW_WORKFLOW_NAME = "test-workflow"), + (process.env.GH_AW_AGENT_CONCLUSION = "success"), + (process.env.GH_AW_SAFE_OUTPUTS_RESULT = "success"), + await eval(`(async () => { ${notifyCommentScript}; await main(); })()`), + expect(mockGithub.request).toHaveBeenCalledWith("PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}", expect.objectContaining({ body: expect.stringContaining("completed successfully!") }))); + })); })); })); diff --git a/docs/public/ai/service.json b/docs/public/ai/service.json index a820d203ed..3609b13383 100644 --- a/docs/public/ai/service.json +++ b/docs/public/ai/service.json @@ -20,15 +20,7 @@ { "id": "codex", "name": "OpenAI Codex" }, { "id": "custom", "name": "Custom engine" } ], - "integrations": [ - "GitHub Actions", - "GitHub CLI", - "MCP (Model Context Protocol)", - "Playwright", - "GitHub Issues", - "GitHub Pull Requests", - "GitHub Discussions" - ], + "integrations": ["GitHub Actions", "GitHub CLI", "MCP (Model Context Protocol)", "Playwright", "GitHub Issues", "GitHub Pull Requests", "GitHub Discussions"], "install": "gh extension install github/gh-aw", "docs": "https://github.github.com/gh-aw/", "source": "https://github.com/github/gh-aw", diff --git a/pkg/workflow/notify_comment.go b/pkg/workflow/notify_comment.go index 7b97a79371..c00cc1cca4 100644 --- a/pkg/workflow/notify_comment.go +++ b/pkg/workflow/notify_comment.go @@ -415,6 +415,13 @@ func (c *Compiler) buildConclusionJob(data *WorkflowData, mainJobName string, sa } customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_AGENT_CONCLUSION: ${{ needs.%s.result }}\n", mainJobName)) + // Pass safe_outputs job result so the conclusion script can detect when safe outputs failed + // to deliver even if the agent succeeded (e.g. a 422 error during PR review submission). + if slices.Contains(safeOutputJobNames, string(constants.SafeOutputsJobName)) { + customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.%s.result }}\n", constants.SafeOutputsJobName)) + notifyCommentLog.Print("Added safe_outputs job result environment variable to conclusion job") + } + // Pass detection conclusion and reason if threat detection is enabled (in separate detection job) if IsDetectionJobEnabled(data.SafeOutputs) { customEnvVars = append(customEnvVars, fmt.Sprintf(" GH_AW_DETECTION_CONCLUSION: ${{ needs.%s.outputs.detection_conclusion }}\n", constants.DetectionJobName)) diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index b9cd69e2db..36b7c59638 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -320,6 +320,64 @@ func TestConclusionJobIntegration(t *testing.T) { } } +func TestConclusionJobSafeOutputsResult(t *testing.T) { + // Test that GH_AW_SAFE_OUTPUTS_RESULT env var is emitted when safe_outputs is in safeOutputJobNames + compiler := NewCompiler() + statusCommentTrue := true + workflowData := &WorkflowData{ + Name: "Test Workflow", + AIReaction: "eyes", + StatusComment: &statusCommentTrue, + SafeOutputs: &SafeOutputsConfig{ + AddComments: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: strPtr("1"), + }, + }, + }, + } + + tests := []struct { + name string + safeOutputJobNames []string + expectEnvVar bool + }{ + { + name: "GH_AW_SAFE_OUTPUTS_RESULT present when safe_outputs is in job list", + safeOutputJobNames: []string{"safe_outputs", "add_comment"}, + expectEnvVar: true, + }, + { + name: "GH_AW_SAFE_OUTPUTS_RESULT absent when safe_outputs is not in job list", + safeOutputJobNames: []string{"add_comment"}, + expectEnvVar: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + job, err := compiler.buildConclusionJob(workflowData, string(constants.AgentJobName), tt.safeOutputJobNames) + if err != nil { + t.Fatalf("Failed to build conclusion job: %v", err) + } + if job == nil { + t.Fatal("Expected conclusion job to be created") + } + + jobYAML := strings.Join(job.Steps, "") + envVarDeclaration := "GH_AW_SAFE_OUTPUTS_RESULT: ${{ needs.safe_outputs.result }}" + hasEnvVar := strings.Contains(jobYAML, envVarDeclaration) + + if tt.expectEnvVar && !hasEnvVar { + t.Errorf("Expected GH_AW_SAFE_OUTPUTS_RESULT env var when safe_outputs is in job list, but it was missing") + } + if !tt.expectEnvVar && hasEnvVar { + t.Errorf("Did not expect GH_AW_SAFE_OUTPUTS_RESULT env var when safe_outputs is not in job list, but it was present") + } + }) + } +} + func TestConclusionJobWithMessages(t *testing.T) { // Test that the conclusion job includes custom messages when configured compiler := NewCompiler()