From bb4a86eb524e49b1936b8b281220b0d56030b2ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 13:44:25 +0000 Subject: [PATCH 1/6] Initial plan From 61d02727fab7acd670108247356d54b2a20426fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 13:54:43 +0000 Subject: [PATCH 2/6] Add safe-inputs gh CLI testing to all smoke workflows Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/smoke-claude.lock.yml | 11 +- .github/workflows/smoke-claude.md | 11 +- .github/workflows/smoke-codex.lock.yml | 11 +- .github/workflows/smoke-codex.md | 11 +- .github/workflows/smoke-copilot.lock.yml | 153 +++++++++++++++++++++- .github/workflows/smoke-copilot.md | 10 +- .github/workflows/smoke-opencode.lock.yml | 133 ++++++++++++++++++- .github/workflows/smoke-opencode.md | 25 +++- 8 files changed, 325 insertions(+), 40 deletions(-) diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index a0cfefd78e3..3b6b75837af 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -1051,11 +1051,12 @@ jobs: ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in __GH_AW_GITHUB_REPOSITORY__ - 2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) - 3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" - 4. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item - 5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-claude-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Claude at $(date)" (create the directory if it doesn't exist) - 6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) + 2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from __GH_AW_GITHUB_REPOSITORY__ (use args: "pr list --repo __GH_AW_GITHUB_REPOSITORY__ --limit 2 --json number,title,author") + 3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) + 4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" + 5. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item + 6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-claude-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Claude at $(date)" (create the directory if it doesn't exist) + 7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output diff --git a/.github/workflows/smoke-claude.md b/.github/workflows/smoke-claude.md index 3ddce723b46..6fe2aa79805 100644 --- a/.github/workflows/smoke-claude.md +++ b/.github/workflows/smoke-claude.md @@ -70,11 +70,12 @@ timeout-minutes: 10 ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in ${{ github.repository }} -2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) -3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" -4. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item -5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-claude-${{ github.run_id }}.txt` with content "Smoke test passed for Claude at $(date)" (create the directory if it doesn't exist) -6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from ${{ github.repository }} (use args: "pr list --repo ${{ github.repository }} --limit 2 --json number,title,author") +3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) +4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" +5. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item +6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-claude-${{ github.run_id }}.txt` with content "Smoke test passed for Claude at $(date)" (create the directory if it doesn't exist) +7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 508712bc237..250b3b4f0fa 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1033,11 +1033,12 @@ jobs: ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in __GH_AW_GITHUB_REPOSITORY__ - 2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) - 3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" - 4. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item - 5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) - 6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) + 2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from __GH_AW_GITHUB_REPOSITORY__ (use args: "pr list --repo __GH_AW_GITHUB_REPOSITORY__ --limit 2 --json number,title,author") + 3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) + 4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" + 5. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item + 6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) + 7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output diff --git a/.github/workflows/smoke-codex.md b/.github/workflows/smoke-codex.md index 0697bf988b4..b6c21ab088b 100644 --- a/.github/workflows/smoke-codex.md +++ b/.github/workflows/smoke-codex.md @@ -67,11 +67,12 @@ timeout-minutes: 10 ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in ${{ github.repository }} -2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) -3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" -4. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item -5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-${{ github.run_id }}.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) -6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from ${{ github.repository }} (use args: "pr list --repo ${{ github.repository }} --limit 2 --json number,title,author") +3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) +4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" +5. **Tavily Web Search Testing**: Use the Tavily MCP server to perform a web search for "GitHub Agentic Workflows" and verify that results are returned with at least one item +6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-${{ github.run_id }}.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) +7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 12af0ab195a..98ba1147d95 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -23,6 +23,7 @@ # # Resolved workflow manifest: # Imports: +# - shared/gh.md # - shared/reporting.md name: "Smoke Copilot" @@ -518,12 +519,116 @@ jobs: bash /opt/gh-aw/actions/start_safe_outputs_server.sh + - name: Setup Safe Inputs Config + run: | + mkdir -p /opt/gh-aw/safe-inputs/logs + cat > /opt/gh-aw/safe-inputs/tools.json << 'EOF_TOOLS_JSON' + { + "serverName": "safeinputs", + "version": "1.0.0", + "logDir": "/opt/gh-aw/safe-inputs/logs", + "tools": [ + { + "name": "gh", + "description": "Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh \u003cargs\u003e. Use single quotes ' for complex args to avoid shell interpretation issues.", + "inputSchema": { + "properties": { + "args": { + "description": "Arguments to pass to gh CLI (without the 'gh' prefix). Examples: 'pr list --limit 5', 'issue view 123', 'api repos/{owner}/{repo}'", + "type": "string" + } + }, + "required": [ + "args" + ], + "type": "object" + }, + "handler": "gh.sh", + "env": { + "GH_AW_GH_TOKEN": "GH_AW_GH_TOKEN", + "GH_DEBUG": "GH_DEBUG" + }, + "timeout": 60 + } + ] + } + EOF_TOOLS_JSON + cat > /opt/gh-aw/safe-inputs/mcp-server.cjs << 'EOFSI' + const path = require("path"); + const { startHttpServer } = require("./safe_inputs_mcp_server_http.cjs"); + const configPath = path.join(__dirname, "tools.json"); + const port = parseInt(process.env.GH_AW_SAFE_INPUTS_PORT || "3000", 10); + const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; + startHttpServer(configPath, { + port: port, + stateless: false, + logDir: "/opt/gh-aw/safe-inputs/logs" + }).catch(error => { + console.error("Failed to start safe-inputs HTTP server:", error); + process.exit(1); + }); + EOFSI + chmod +x /opt/gh-aw/safe-inputs/mcp-server.cjs + + - name: Setup Safe Inputs Tool Files + run: | + cat > /opt/gh-aw/safe-inputs/gh.sh << 'EOFSH_gh' + #!/bin/bash + # Auto-generated safe-input tool: gh + # Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh . Use single quotes ' for complex args to avoid shell interpretation issues. + + set -euo pipefail + + echo "gh $INPUT_ARGS" + echo " token: ${GH_AW_GH_TOKEN:0:6}..." + GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS + + EOFSH_gh + chmod +x /opt/gh-aw/safe-inputs/gh.sh + + - name: Generate Safe Inputs MCP Server Config + id: safe-inputs-config + run: | + # Generate a secure random API key (360 bits of entropy, 40+ chars) + API_KEY="" + API_KEY=$(openssl rand -base64 45 | tr -d '/+=') + PORT=3000 + + # Register API key as secret to mask it from logs + echo "::add-mask::${API_KEY}" + + # Set outputs for next steps + { + echo "safe_inputs_api_key=${API_KEY}" + echo "safe_inputs_port=${PORT}" + } >> "$GITHUB_OUTPUT" + + echo "Safe Inputs MCP server will run on port ${PORT}" + + - name: Start Safe Inputs MCP HTTP Server + id: safe-inputs-start + env: + GH_AW_SAFE_INPUTS_PORT: ${{ steps.safe-inputs-config.outputs.safe_inputs_port }} + GH_AW_SAFE_INPUTS_API_KEY: ${{ steps.safe-inputs-config.outputs.safe_inputs_api_key }} + GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_DEBUG: 1 + run: | + # Environment variables are set above to prevent template injection + export GH_AW_SAFE_INPUTS_PORT + export GH_AW_SAFE_INPUTS_API_KEY + + bash /opt/gh-aw/actions/start_safe_inputs_server.sh + - name: Start MCP gateway id: start-mcp-gateway env: + GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_AW_SAFE_INPUTS_API_KEY: ${{ steps.safe-inputs-start.outputs.api_key }} + GH_AW_SAFE_INPUTS_PORT: ${{ steps.safe-inputs-start.outputs.port }} GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} + GH_DEBUG: 1 GITHUB_MCP_LOCKDOWN: ${{ steps.determine-automatic-lockdown.outputs.lockdown == 'true' && '1' || '0' }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -541,7 +646,7 @@ jobs: # Register API key as secret to mask it from logs echo "::add-mask::${MCP_GATEWAY_API_KEY}" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e 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_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/githubnext/gh-aw-mcpg:v0.0.76' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e 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_LOCKDOWN -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_INPUTS_PORT -e GH_AW_SAFE_INPUTS_API_KEY -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GH_AW_GH_TOKEN -e GH_DEBUG -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/githubnext/gh-aw-mcpg:v0.0.76' mkdir -p /home/runner/.copilot cat << MCPCONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh @@ -574,6 +679,13 @@ jobs: "entrypointArgs": ["--output-dir", "/tmp/gh-aw/mcp-logs/playwright", "--allowed-hosts", "localhost;localhost:*;127.0.0.1;127.0.0.1:*;github.com", "--allowed-origins", "localhost;localhost:*;127.0.0.1;127.0.0.1:*;github.com"], "mounts": ["/tmp/gh-aw/mcp-logs:/tmp/gh-aw/mcp-logs:rw"] }, + "safeinputs": { + "type": "http", + "url": "http://host.docker.internal:$GH_AW_SAFE_INPUTS_PORT", + "headers": { + "Authorization": "\${GH_AW_SAFE_INPUTS_API_KEY}" + } + }, "safeoutputs": { "type": "http", "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", @@ -624,7 +736,7 @@ jobs: event_name: context.eventName, staged: false, network_mode: "defaults", - allowed_domains: ["defaults","node","github","playwright"], + allowed_domains: ["api.github.com","defaults","github","node","playwright"], firewall_enabled: true, awf_version: "v0.10.0", awmg_version: "v0.0.76", @@ -736,6 +848,23 @@ jobs: PROMPT_EOF cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" + **IMPORTANT**: Always use the `safeinputs-gh` tool for GitHub CLI commands instead of running `gh` directly via bash. The `safeinputs-gh` tool has proper authentication configured with `GITHUB_TOKEN`, while bash commands do not have GitHub CLI authentication by default. + + **Correct**: + ``` + Use the safeinputs-gh tool with args: "pr list --limit 5" + Use the safeinputs-gh tool with args: "issue view 123" + ``` + + **Incorrect**: + ``` + Use the gh safe-input tool with args: "pr list --limit 5" ❌ (Wrong tool name - use safeinputs-gh) + Run: gh pr list --limit 5 ❌ (No authentication in bash) + Execute bash: gh issue view 123 ❌ (No authentication in bash) + ``` + + + ## Report Structure Guidelines ### 1. Header Levels @@ -813,10 +942,11 @@ jobs: ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in __GH_AW_GITHUB_REPOSITORY__ - 2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) - 3. **Playwright Testing**: Use playwright to navigate to and verify the page title contains "GitHub" - 4. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) - 5. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) + 2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from __GH_AW_GITHUB_REPOSITORY__ (use args: "pr list --repo __GH_AW_GITHUB_REPOSITORY__ --limit 2 --json number,title,author") + 3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) + 4. **Playwright Testing**: Use playwright to navigate to and verify the page title contains "GitHub" + 5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) + 6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output @@ -910,6 +1040,7 @@ jobs: GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }} GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} + GH_DEBUG: 1 GITHUB_HEAD_REF: ${{ github.head_ref }} GITHUB_REF_NAME: ${{ github.ref_name }} GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }} @@ -1003,6 +1134,15 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('/opt/gh-aw/actions/parse_copilot_log.cjs'); await main(); + - name: Parse safe-inputs logs for step summary + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('/opt/gh-aw/actions/parse_safe_inputs_logs.cjs'); + await main(); - name: Parse MCP gateway logs for step summary if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 @@ -1038,6 +1178,7 @@ jobs: /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/aw_info.json /tmp/gh-aw/mcp-logs/ + /tmp/gh-aw/safe-inputs/logs/ /tmp/gh-aw/sandbox/firewall/logs/ /tmp/gh-aw/agent-stdio.log if-no-files-found: ignore diff --git a/.github/workflows/smoke-copilot.md b/.github/workflows/smoke-copilot.md index 3eb153ca5ee..07a2d35b828 100644 --- a/.github/workflows/smoke-copilot.md +++ b/.github/workflows/smoke-copilot.md @@ -15,6 +15,7 @@ permissions: name: Smoke Copilot engine: copilot imports: + - shared/gh.md - shared/reporting.md network: allowed: @@ -70,10 +71,11 @@ strict: true ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in ${{ github.repository }} -2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) -3. **Playwright Testing**: Use playwright to navigate to and verify the page title contains "GitHub" -4. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-${{ github.run_id }}.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) -5. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from ${{ github.repository }} (use args: "pr list --repo ${{ github.repository }} --limit 2 --json number,title,author") +3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) +4. **Playwright Testing**: Use playwright to navigate to and verify the page title contains "GitHub" +5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-${{ github.run_id }}.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) +6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index af648908b42..762144f94b0 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -474,12 +474,117 @@ jobs: bash /opt/gh-aw/actions/start_safe_outputs_server.sh + - name: Setup Safe Inputs Config + run: | + mkdir -p /opt/gh-aw/safe-inputs/logs + cat > /opt/gh-aw/safe-inputs/tools.json << 'EOF_TOOLS_JSON' + { + "serverName": "safeinputs", + "version": "1.0.0", + "logDir": "/opt/gh-aw/safe-inputs/logs", + "tools": [ + { + "name": "gh", + "description": "Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh \u003cargs\u003e. Use single quotes ' for complex args to avoid shell interpretation issues.", + "inputSchema": { + "properties": { + "args": { + "description": "Arguments to pass to gh CLI (without the 'gh' prefix). Examples: 'pr list --limit 5', 'issue view 123', 'api repos/{owner}/{repo}'", + "type": "string" + } + }, + "required": [ + "args" + ], + "type": "object" + }, + "handler": "gh.sh", + "env": { + "GH_AW_GH_TOKEN": "GH_AW_GH_TOKEN", + "GH_DEBUG": "GH_DEBUG" + }, + "timeout": 60 + } + ] + } + EOF_TOOLS_JSON + cat > /opt/gh-aw/safe-inputs/mcp-server.cjs << 'EOFSI' + const path = require("path"); + const { startHttpServer } = require("./safe_inputs_mcp_server_http.cjs"); + const configPath = path.join(__dirname, "tools.json"); + const port = parseInt(process.env.GH_AW_SAFE_INPUTS_PORT || "3000", 10); + const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; + startHttpServer(configPath, { + port: port, + stateless: false, + logDir: "/opt/gh-aw/safe-inputs/logs" + }).catch(error => { + console.error("Failed to start safe-inputs HTTP server:", error); + process.exit(1); + }); + EOFSI + chmod +x /opt/gh-aw/safe-inputs/mcp-server.cjs + + - name: Setup Safe Inputs Tool Files + run: | + cat > /opt/gh-aw/safe-inputs/gh.sh << 'EOFSH_gh' + #!/bin/bash + # Auto-generated safe-input tool: gh + # Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh . Use single quotes ' for complex args to avoid shell interpretation issues. + + set -euo pipefail + + echo "gh $INPUT_ARGS" + echo " token: ${GH_AW_GH_TOKEN:0:6}..." + GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS + + + EOFSH_gh + chmod +x /opt/gh-aw/safe-inputs/gh.sh + + - name: Generate Safe Inputs MCP Server Config + id: safe-inputs-config + run: | + # Generate a secure random API key (360 bits of entropy, 40+ chars) + API_KEY="" + API_KEY=$(openssl rand -base64 45 | tr -d '/+=') + PORT=3000 + + # Register API key as secret to mask it from logs + echo "::add-mask::${API_KEY}" + + # Set outputs for next steps + { + echo "safe_inputs_api_key=${API_KEY}" + echo "safe_inputs_port=${PORT}" + } >> "$GITHUB_OUTPUT" + + echo "Safe Inputs MCP server will run on port ${PORT}" + + - name: Start Safe Inputs MCP HTTP Server + id: safe-inputs-start + env: + GH_AW_SAFE_INPUTS_PORT: ${{ steps.safe-inputs-config.outputs.safe_inputs_port }} + GH_AW_SAFE_INPUTS_API_KEY: ${{ steps.safe-inputs-config.outputs.safe_inputs_api_key }} + GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_DEBUG: 1 + run: | + # Environment variables are set above to prevent template injection + export GH_AW_SAFE_INPUTS_PORT + export GH_AW_SAFE_INPUTS_API_KEY + + bash /opt/gh-aw/actions/start_safe_inputs_server.sh + - name: Start MCP gateway id: start-mcp-gateway env: + GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_AW_SAFE_INPUTS_API_KEY: ${{ steps.safe-inputs-start.outputs.api_key }} + GH_AW_SAFE_INPUTS_PORT: ${{ steps.safe-inputs-start.outputs.port }} GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }} GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }} + GH_DEBUG: 1 GITHUB_MCP_LOCKDOWN: ${{ steps.determine-automatic-lockdown.outputs.lockdown == 'true' && '1' || '0' }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} run: | @@ -496,7 +601,7 @@ jobs: # Register API key as secret to mask it from logs echo "::add-mask::${MCP_GATEWAY_API_KEY}" export GH_AW_ENGINE="custom" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e 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_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/githubnext/gh-aw-mcpg:v0.0.76' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e 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_LOCKDOWN -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_INPUTS_PORT -e GH_AW_SAFE_INPUTS_API_KEY -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GH_AW_GH_TOKEN -e GH_DEBUG -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/githubnext/gh-aw-mcpg:v0.0.76' cat << MCPCONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh { @@ -510,6 +615,13 @@ jobs: "GITHUB_TOOLSETS": "context,repos,issues,pull_requests" } }, + "safeinputs": { + "type": "http", + "url": "http://host.docker.internal:$GH_AW_SAFE_INPUTS_PORT", + "headers": { + "Authorization": "$GH_AW_SAFE_INPUTS_API_KEY" + } + }, "safeoutputs": { "type": "http", "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT", @@ -652,10 +764,11 @@ jobs: ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in __GH_AW_GITHUB_REPOSITORY__ - 2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) - 3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" - 4. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-opencode-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for OpenCode at $(date)" (create the directory if it doesn't exist) - 5. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) + 2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from __GH_AW_GITHUB_REPOSITORY__ (use args: "pr list --repo __GH_AW_GITHUB_REPOSITORY__ --limit 2 --json number,title,author") + 3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `__GH_AW_GITHUB_WORKSPACE__` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) + 4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" + 5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-opencode-__GH_AW_GITHUB_RUN_ID__.txt` with content "Smoke test passed for OpenCode at $(date)" (create the directory if it doesn't exist) + 6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output @@ -877,6 +990,15 @@ jobs: setupGlobals(core, github, context, exec, io); const { main } = require('/opt/gh-aw/actions/parse_custom_log.cjs'); await main(); + - name: Parse safe-inputs logs for step summary + if: always() + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + with: + script: | + const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs'); + setupGlobals(core, github, context, exec, io); + const { main } = require('/opt/gh-aw/actions/parse_safe_inputs_logs.cjs'); + await main(); - name: Parse MCP gateway logs for step summary if: always() uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 @@ -896,6 +1018,7 @@ jobs: /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/aw_info.json /tmp/gh-aw/mcp-logs/ + /tmp/gh-aw/safe-inputs/logs/ /tmp/gh-aw/agent-stdio.log if-no-files-found: ignore diff --git a/.github/workflows/smoke-opencode.md b/.github/workflows/smoke-opencode.md index 422a096739d..c36badbbea8 100644 --- a/.github/workflows/smoke-opencode.md +++ b/.github/workflows/smoke-opencode.md @@ -15,7 +15,21 @@ permissions: name: Smoke OpenCode imports: - shared/opencode.md -strict: true +safe-inputs: + gh: + description: "Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh . Use single quotes ' for complex args to avoid shell interpretation issues." + inputs: + args: + type: string + description: "Arguments to pass to gh CLI (without the 'gh' prefix). Examples: 'pr list --limit 5', 'issue view 123', 'api repos/{owner}/{repo}'" + required: true + env: + GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_DEBUG: "1" + run: | + echo "gh $INPUT_ARGS" + echo " token: ${GH_AW_GH_TOKEN:0:6}..." + GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS sandbox: mcp: container: "ghcr.io/githubnext/gh-aw-mcpg" @@ -56,10 +70,11 @@ timeout-minutes: 10 ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in ${{ github.repository }} -2. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) -3. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" -4. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-opencode-${{ github.run_id }}.txt` with content "Smoke test passed for OpenCode at $(date)" (create the directory if it doesn't exist) -5. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +2. **Safe Inputs GH CLI Testing**: Use the `safeinputs-gh` tool to query 2 pull requests from ${{ github.repository }} (use args: "pr list --repo ${{ github.repository }} --limit 2 --json number,title,author") +3. **Serena MCP Testing**: Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) +4. **Playwright Testing**: Use playwright to navigate to https://github.com and verify the page title contains "GitHub" +5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-opencode-${{ github.run_id }}.txt` with content "Smoke test passed for OpenCode at $(date)" (create the directory if it doesn't exist) +6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) ## Output From 8b5b6b76134da6a06151ba48507873c2a69ce7b0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 14:05:17 +0000 Subject: [PATCH 3/6] Changes before error encountered Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/shared/gh.md | 3 --- .github/workflows/smoke-claude.lock.yml | 2 +- .github/workflows/smoke-codex.lock.yml | 6 +++--- .github/workflows/smoke-copilot.lock.yml | 2 +- .github/workflows/smoke-opencode.lock.yml | 19 ++++++++++++++++++- .github/workflows/smoke-opencode.md | 17 ++--------------- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/.github/workflows/shared/gh.md b/.github/workflows/shared/gh.md index 2219d85fedf..72d81ebe624 100644 --- a/.github/workflows/shared/gh.md +++ b/.github/workflows/shared/gh.md @@ -1,7 +1,4 @@ --- -network: - allowed: - - api.github.com safe-inputs: gh: description: "Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh . Use single quotes ' for complex args to avoid shell interpretation issues." diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 3b6b75837af..0d55c5d8a67 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -732,7 +732,7 @@ jobs: event_name: context.eventName, staged: false, network_mode: "defaults", - allowed_domains: ["api.github.com","defaults","github","playwright"], + allowed_domains: ["defaults","github","playwright"], firewall_enabled: true, awf_version: "v0.10.0", awmg_version: "v0.0.76", diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 250b3b4f0fa..da1c9a14483 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -826,7 +826,7 @@ jobs: event_name: context.eventName, staged: false, network_mode: "defaults", - allowed_domains: ["api.github.com","defaults","github","playwright"], + allowed_domains: ["defaults","github","playwright"], firewall_enabled: true, awf_version: "v0.10.0", awmg_version: "v0.0.76", @@ -1106,7 +1106,7 @@ jobs: set -o pipefail INSTRUCTION="$(cat "$GH_AW_PROMPT")" mkdir -p "$CODEX_HOME/logs" - sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount /tmp:/tmp:rw --mount "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw" --mount /opt/hostedtoolcache/node:/opt/hostedtoolcache/node:ro --mount /opt/gh-aw:/opt/gh-aw:ro --allow-domains '*.githubusercontent.com,api.github.com,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,mcp.tavily.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.10.0 \ + sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount /tmp:/tmp:rw --mount "${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw" --mount /opt/hostedtoolcache/node:/opt/hostedtoolcache/node:ro --mount /opt/gh-aw:/opt/gh-aw:ro --allow-domains '*.githubusercontent.com,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,mcp.tavily.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.10.0 \ -- NODE_BIN_PATH="$(find /opt/hostedtoolcache/node -mindepth 1 -maxdepth 1 -type d | head -1 | xargs basename)/x64/bin" && export PATH="/opt/hostedtoolcache/node/$NODE_BIN_PATH:$PATH" && codex ${GH_AW_MODEL_AGENT_CODEX:+-c model="$GH_AW_MODEL_AGENT_CODEX" }exec --full-auto --skip-git-repo-check --sandbox danger-full-access "$INSTRUCTION" \ 2>&1 | tee /tmp/gh-aw/agent-stdio.log env: @@ -1158,7 +1158,7 @@ jobs: uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }} - GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.github.com,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" + GH_AW_ALLOWED_DOMAINS: "*.githubusercontent.com,api.openai.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,cdn.playwright.dev,codeload.github.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.githubassets.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,lfs.github.com,objects.githubusercontent.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,openai.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,playwright.download.prss.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,s.symcb.com,s.symcd.com,security.ubuntu.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com" GITHUB_SERVER_URL: ${{ github.server_url }} GITHUB_API_URL: ${{ github.api_url }} with: diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 98ba1147d95..f0fc5042438 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -736,7 +736,7 @@ jobs: event_name: context.eventName, staged: false, network_mode: "defaults", - allowed_domains: ["api.github.com","defaults","github","node","playwright"], + allowed_domains: ["defaults","node","github","playwright"], firewall_enabled: true, awf_version: "v0.10.0", awmg_version: "v0.0.76", diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 762144f94b0..53e54a3e6ed 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -23,6 +23,7 @@ # # Resolved workflow manifest: # Imports: +# - shared/gh.md # - shared/opencode.md name: "Smoke OpenCode" @@ -538,7 +539,6 @@ jobs: echo " token: ${GH_AW_GH_TOKEN:0:6}..." GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS - EOFSH_gh chmod +x /opt/gh-aw/safe-inputs/gh.sh @@ -757,6 +757,23 @@ jobs: cat << 'PROMPT_EOF' >> "$GH_AW_PROMPT" + **IMPORTANT**: Always use the `safeinputs-gh` tool for GitHub CLI commands instead of running `gh` directly via bash. The `safeinputs-gh` tool has proper authentication configured with `GITHUB_TOKEN`, while bash commands do not have GitHub CLI authentication by default. + + **Correct**: + ``` + Use the safeinputs-gh tool with args: "pr list --limit 5" + Use the safeinputs-gh tool with args: "issue view 123" + ``` + + **Incorrect**: + ``` + Use the gh safe-input tool with args: "pr list --limit 5" ❌ (Wrong tool name - use safeinputs-gh) + Run: gh pr list --limit 5 ❌ (No authentication in bash) + Execute bash: gh issue view 123 ❌ (No authentication in bash) + ``` + + + # Smoke Test: OpenCode Custom Engine Validation **IMPORTANT: Keep all outputs extremely short and concise. Use single-line responses where possible. No verbose explanations.** diff --git a/.github/workflows/smoke-opencode.md b/.github/workflows/smoke-opencode.md index c36badbbea8..f24ee5508f4 100644 --- a/.github/workflows/smoke-opencode.md +++ b/.github/workflows/smoke-opencode.md @@ -15,21 +15,8 @@ permissions: name: Smoke OpenCode imports: - shared/opencode.md -safe-inputs: - gh: - description: "Execute any gh CLI command. This tool is accessible as 'safeinputs-gh'. Provide the full command after 'gh' (e.g., args: 'pr list --limit 5'). The tool will run: gh . Use single quotes ' for complex args to avoid shell interpretation issues." - inputs: - args: - type: string - description: "Arguments to pass to gh CLI (without the 'gh' prefix). Examples: 'pr list --limit 5', 'issue view 123', 'api repos/{owner}/{repo}'" - required: true - env: - GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_DEBUG: "1" - run: | - echo "gh $INPUT_ARGS" - echo " token: ${GH_AW_GH_TOKEN:0:6}..." - GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS + - shared/gh.md +strict: true sandbox: mcp: container: "ghcr.io/githubnext/gh-aw-mcpg" From 98a0efb24ce00418b55c5935f7824de1287c3698 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 22 Jan 2026 14:52:53 +0000 Subject: [PATCH 4/6] Add changeset [skip-ci] --- .changeset/patch-add-safe-inputs-gh-cli-testing.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .changeset/patch-add-safe-inputs-gh-cli-testing.md diff --git a/.changeset/patch-add-safe-inputs-gh-cli-testing.md b/.changeset/patch-add-safe-inputs-gh-cli-testing.md new file mode 100644 index 00000000000..d4feae11af6 --- /dev/null +++ b/.changeset/patch-add-safe-inputs-gh-cli-testing.md @@ -0,0 +1,11 @@ +--- +"gh-aw": patch +--- + +Add safe-inputs gh CLI testing to smoke workflows. + +This patch adds validation to the smoke workflows to exercise the GitHub CLI +integration via the `safeinputs-gh` tool. It also updates `shared/gh.md` +to remove the `network.allowed` restriction so the `safeinputs-gh` tool can +query PRs using the provided `GITHUB_TOKEN`. + From 78ca24dd09136c705a10a18468178be2637ecf0c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 22 Jan 2026 07:22:10 -0800 Subject: [PATCH 5/6] Fix safe-inputs MCP server mode mismatch causing tool registration failure (#11318) --- .github/workflows/copilot-pr-merged-report.lock.yml | 4 ++-- .github/workflows/daily-performance-summary.lock.yml | 2 +- .github/workflows/daily-regulatory.lock.yml | 2 +- .github/workflows/smoke-claude.lock.yml | 2 +- .github/workflows/smoke-codex.lock.yml | 2 +- .github/workflows/smoke-copilot.lock.yml | 2 +- .github/workflows/smoke-opencode.lock.yml | 2 +- pkg/workflow/safe_inputs_generator.go | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/copilot-pr-merged-report.lock.yml b/.github/workflows/copilot-pr-merged-report.lock.yml index aa07efb9be2..2e26bfa9c17 100644 --- a/.github/workflows/copilot-pr-merged-report.lock.yml +++ b/.github/workflows/copilot-pr-merged-report.lock.yml @@ -395,7 +395,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); @@ -532,7 +532,7 @@ jobs: event_name: context.eventName, staged: false, network_mode: "defaults", - allowed_domains: ["api.github.com","defaults","github"], + allowed_domains: ["defaults","github","api.github.com"], firewall_enabled: true, awf_version: "v0.10.0", awmg_version: "v0.0.76", diff --git a/.github/workflows/daily-performance-summary.lock.yml b/.github/workflows/daily-performance-summary.lock.yml index 4efb2ef2895..f081540eb42 100644 --- a/.github/workflows/daily-performance-summary.lock.yml +++ b/.github/workflows/daily-performance-summary.lock.yml @@ -596,7 +596,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/.github/workflows/daily-regulatory.lock.yml b/.github/workflows/daily-regulatory.lock.yml index 3d2460cf416..4b61521a9b4 100644 --- a/.github/workflows/daily-regulatory.lock.yml +++ b/.github/workflows/daily-regulatory.lock.yml @@ -528,7 +528,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 0d55c5d8a67..017b43725f2 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -544,7 +544,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index da1c9a14483..e0ba9c1d130 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -571,7 +571,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index f0fc5042438..e0de7544858 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -561,7 +561,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 53e54a3e6ed..72cfd840537 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -517,7 +517,7 @@ jobs: const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); diff --git a/pkg/workflow/safe_inputs_generator.go b/pkg/workflow/safe_inputs_generator.go index 35b6849cf67..ba842639b18 100644 --- a/pkg/workflow/safe_inputs_generator.go +++ b/pkg/workflow/safe_inputs_generator.go @@ -160,7 +160,7 @@ const apiKey = process.env.GH_AW_SAFE_INPUTS_API_KEY || ""; // Start the HTTP server startHttpServer(configPath, { port: port, - stateless: false, + stateless: true, logDir: "/opt/gh-aw/safe-inputs/logs" }).catch(error => { console.error("Failed to start safe-inputs HTTP server:", error); From 52ed928a6debf86509f4c6151a9056b51efe60a1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 22 Jan 2026 15:25:14 +0000 Subject: [PATCH 6/6] Add changeset [skip-ci] --- ...h-add-safe-inputs-gh-cli-testing-to-smoke-workflows.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/patch-add-safe-inputs-gh-cli-testing-to-smoke-workflows.md diff --git a/.changeset/patch-add-safe-inputs-gh-cli-testing-to-smoke-workflows.md b/.changeset/patch-add-safe-inputs-gh-cli-testing-to-smoke-workflows.md new file mode 100644 index 00000000000..aad786929b8 --- /dev/null +++ b/.changeset/patch-add-safe-inputs-gh-cli-testing-to-smoke-workflows.md @@ -0,0 +1,8 @@ +--- +"gh-aw": patch +--- + +Add safe-inputs gh CLI testing to smoke workflows; updates `shared/gh.md` to remove the `network.allowed` restriction and validate GitHub CLI access using `GITHUB_TOKEN`. + +This changeset accompanies the PR that adds `safeinputs-gh` testing to all smoke workflows (smoke-copilot.md, smoke-claude.md, smoke-codex.md, smoke-opencode.md) and adjusts `shared/gh.md` accordingly. +