diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index b7c87c691ac..298424d2818 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d855efd256c75de6ca1d2f20bac63d0f238aec7201c304bd6dbe4013ed348a76","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"23c768d340eb1d7e43465f9dc097f91d94cd3b62dd1692e46d796cdce017ad65","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7","digest":"sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7@sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7","digest":"sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7@sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7","digest":"sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7@sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e","pinned_image":"ghcr.io/github/gh-aw-node@sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e"}],"mcp_servers":[{"name":"github","tools":["get_repository","issue_read","list_issues"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -1100,6 +1100,7 @@ jobs: - activation - agent - detection + - raw_mcp_canary - safe_outputs if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || @@ -1653,6 +1654,165 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json + raw_mcp_canary: + needs: agent + if: always() && !cancelled() + runs-on: ubuntu-latest + permissions: + contents: read + discussions: read + issues: read + steps: + - name: Configure GH_HOST for enterprise compatibility + id: ghes-host-config + shell: bash + run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input. + # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct + # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op. + GH_HOST="${GITHUB_SERVER_URL#https://}" + GH_HOST="${GH_HOST#http://}" + echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" + - name: Verify raw GitHub remote MCP handshake + run: | + set -euo pipefail + + if [ -z "${GITHUB_MCP_SERVER_TOKEN:-}" ]; then + echo "No GitHub MCP token is available." + exit 1 + fi + echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" + + server_url="https://api.githubcopilot.com/mcp/" + initialize_headers_file="$(mktemp)" + response_headers_file="$(mktemp)" + body_file="$(mktemp)" + json_file="$(mktemp)" + error_file="$(mktemp)" + trap 'rm -f "$initialize_headers_file" "$response_headers_file" "$body_file" "$json_file" "$error_file"' EXIT + + { + echo "## Raw GitHub remote MCP canary" + echo + } >> "$GITHUB_STEP_SUMMARY" + + mcp_post() { + local payload="$1" + local response_headers_file="$2" + shift 2 + local http_code + if ! http_code="$(curl -sS -D "$response_headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + -X POST "$server_url" \ + --oauth2-bearer "$GITHUB_MCP_SERVER_TOKEN" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json, text/event-stream" \ + -H "X-MCP-Readonly: true" \ + -H "X-MCP-Toolsets: repos,issues,discussions" \ + "$@" \ + -d "$payload" 2>"$error_file")"; then + http_code="000" + fi + printf '%s' "$http_code" + } + + read_json_response() { + if jq -e . "$body_file" >/dev/null 2>&1; then + cp "$body_file" "$json_file" + else + awk '/^data:/ { sub(/^data: ?/, ""); print }' "$body_file" | tail -n 1 > "$json_file" + fi + } + + assert_success_response() { + local label="$1" + local http_code="$2" + if [ "$http_code" != "200" ]; then + echo "$label failed with HTTP $http_code." + echo "- ❌ $label: HTTP $http_code" >> "$GITHUB_STEP_SUMMARY" + if [ -s "$error_file" ]; then + echo "curl error: $(head -c 200 "$error_file")" + fi + exit 1 + fi + + read_json_response + if ! jq -e . "$json_file" >/dev/null 2>&1; then + echo "$label did not return a JSON response." + echo "- ❌ $label: invalid JSON response" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + if jq -e '.error' "$json_file" >/dev/null 2>&1; then + error_message="$(jq -r '.error.message // "unknown JSON-RPC error"' "$json_file")" + echo "$label returned JSON-RPC error: $error_message" + echo "- ❌ $label: JSON-RPC error \`$error_message\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + } + + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' "$initialize_headers_file")" + assert_success_response "MCP initialize" "$initialize_code" + protocol_version="$(jq -r '.result.protocolVersion // "unknown"' "$json_file")" + server_info="$(jq -c '.result.serverInfo // {}' "$json_file")" + echo "- ✅ MCP initialize: protocol \`$protocol_version\`, server \`$server_info\`" >> "$GITHUB_STEP_SUMMARY" + + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$initialize_headers_file")" + session_args=() + if [ -n "$session_id" ]; then + session_args=(-H "Mcp-Session-Id: $session_id") + fi + + initialized_code="$(mcp_post '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' "$response_headers_file" "${session_args[@]}")" + if [[ ! "$initialized_code" =~ ^20[024]$ ]]; then + echo "MCP notifications/initialized failed with HTTP $initialized_code." + echo "- ❌ MCP notifications/initialized: HTTP $initialized_code" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP notifications/initialized: HTTP $initialized_code" >> "$GITHUB_STEP_SUMMARY" + + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"ping"}' "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP ping" "$ping_code" + echo "- ✅ MCP ping" >> "$GITHUB_STEP_SUMMARY" + + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP tools/list" "$tools_code" + + tool_count="$(jq -r 'if (.result.tools | type) == "array" then (.result.tools | length) else 0 end' "$json_file")" + if [ "$tool_count" -eq 0 ]; then + echo "MCP tools/list did not return any tools." + echo "- ❌ MCP tools/list: empty tool catalog" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + if ! jq -e '.result.tools[] | select(.name == "get_repository")' "$json_file" >/dev/null; then + echo 'MCP tools/list did not return the get_repository tool.' + echo "- ❌ MCP tools/list: \`get_repository\` is unavailable" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP tools/list: $tool_count tools, including \`get_repository\`" >> "$GITHUB_STEP_SUMMARY" + + repository_owner="${GITHUB_REPOSITORY%%/*}" + repository_name="${GITHUB_REPOSITORY#*/}" + call_payload="$(jq -nc \ + --arg owner "$repository_owner" \ + --arg repo "$repository_name" \ + '{jsonrpc:"2.0",id:4,method:"tools/call",params:{name:"get_repository",arguments:{owner:$owner,repo:$repo}}}')" + call_code="$(mcp_post "$call_payload" "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP get_repository" "$call_code" + if jq -e '.result.isError == true' "$json_file" >/dev/null; then + tool_error="$(jq -r '([.result.content[]?.text] | join(" "))[0:200]' "$json_file")" + echo "MCP get_repository returned a tool error: $tool_error" + echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + repository_content="$(jq -r '[.result.content[]? | select(.type == "text") | .text] | join(" ")' "$json_file")" + if [[ "$repository_content" != *"$GITHUB_REPOSITORY"* ]]; then + echo "MCP get_repository did not return the requested repository." + echo "- ❌ MCP get_repository: result did not identify \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP get_repository: retrieved \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." + env: + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + safe_outputs: needs: - activation diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md index e43e8b8e476..8ddd49f22fd 100644 --- a/.github/workflows/github-remote-mcp-auth-test.md +++ b/.github/workflows/github-remote-mcp-auth-test.md @@ -30,6 +30,156 @@ imports: - shared/otlp.md +jobs: + raw_mcp_canary: + needs: agent + if: always() && !cancelled() + runs-on: ubuntu-latest + permissions: + contents: read + issues: read + discussions: read + steps: + - name: Verify raw GitHub remote MCP handshake + env: + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + if [ -z "${GITHUB_MCP_SERVER_TOKEN:-}" ]; then + echo "No GitHub MCP token is available." + exit 1 + fi + echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" + + server_url="https://api.githubcopilot.com/mcp/" + initialize_headers_file="$(mktemp)" + response_headers_file="$(mktemp)" + body_file="$(mktemp)" + json_file="$(mktemp)" + error_file="$(mktemp)" + trap 'rm -f "$initialize_headers_file" "$response_headers_file" "$body_file" "$json_file" "$error_file"' EXIT + + { + echo "## Raw GitHub remote MCP canary" + echo + } >> "$GITHUB_STEP_SUMMARY" + + mcp_post() { + local payload="$1" + local response_headers_file="$2" + shift 2 + local http_code + if ! http_code="$(curl -sS -D "$response_headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + -X POST "$server_url" \ + --oauth2-bearer "$GITHUB_MCP_SERVER_TOKEN" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json, text/event-stream" \ + -H "X-MCP-Readonly: true" \ + -H "X-MCP-Toolsets: repos,issues,discussions" \ + "$@" \ + -d "$payload" 2>"$error_file")"; then + http_code="000" + fi + printf '%s' "$http_code" + } + + read_json_response() { + if jq -e . "$body_file" >/dev/null 2>&1; then + cp "$body_file" "$json_file" + else + awk '/^data:/ { sub(/^data: ?/, ""); print }' "$body_file" | tail -n 1 > "$json_file" + fi + } + + assert_success_response() { + local label="$1" + local http_code="$2" + if [ "$http_code" != "200" ]; then + echo "$label failed with HTTP $http_code." + echo "- ❌ $label: HTTP $http_code" >> "$GITHUB_STEP_SUMMARY" + if [ -s "$error_file" ]; then + echo "curl error: $(head -c 200 "$error_file")" + fi + exit 1 + fi + + read_json_response + if ! jq -e . "$json_file" >/dev/null 2>&1; then + echo "$label did not return a JSON response." + echo "- ❌ $label: invalid JSON response" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + if jq -e '.error' "$json_file" >/dev/null 2>&1; then + error_message="$(jq -r '.error.message // "unknown JSON-RPC error"' "$json_file")" + echo "$label returned JSON-RPC error: $error_message" + echo "- ❌ $label: JSON-RPC error \`$error_message\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + } + + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' "$initialize_headers_file")" + assert_success_response "MCP initialize" "$initialize_code" + protocol_version="$(jq -r '.result.protocolVersion // "unknown"' "$json_file")" + server_info="$(jq -c '.result.serverInfo // {}' "$json_file")" + echo "- ✅ MCP initialize: protocol \`$protocol_version\`, server \`$server_info\`" >> "$GITHUB_STEP_SUMMARY" + + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$initialize_headers_file")" + session_args=() + if [ -n "$session_id" ]; then + session_args=(-H "Mcp-Session-Id: $session_id") + fi + + initialized_code="$(mcp_post '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' "$response_headers_file" "${session_args[@]}")" + if [[ ! "$initialized_code" =~ ^20[024]$ ]]; then + echo "MCP notifications/initialized failed with HTTP $initialized_code." + echo "- ❌ MCP notifications/initialized: HTTP $initialized_code" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP notifications/initialized: HTTP $initialized_code" >> "$GITHUB_STEP_SUMMARY" + + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"ping"}' "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP ping" "$ping_code" + echo "- ✅ MCP ping" >> "$GITHUB_STEP_SUMMARY" + + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP tools/list" "$tools_code" + + tool_count="$(jq -r 'if (.result.tools | type) == "array" then (.result.tools | length) else 0 end' "$json_file")" + if [ "$tool_count" -eq 0 ]; then + echo "MCP tools/list did not return any tools." + echo "- ❌ MCP tools/list: empty tool catalog" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + if ! jq -e '.result.tools[] | select(.name == "get_repository")' "$json_file" >/dev/null; then + echo 'MCP tools/list did not return the get_repository tool.' + echo "- ❌ MCP tools/list: \`get_repository\` is unavailable" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP tools/list: $tool_count tools, including \`get_repository\`" >> "$GITHUB_STEP_SUMMARY" + + repository_owner="${GITHUB_REPOSITORY%%/*}" + repository_name="${GITHUB_REPOSITORY#*/}" + call_payload="$(jq -nc \ + --arg owner "$repository_owner" \ + --arg repo "$repository_name" \ + '{jsonrpc:"2.0",id:4,method:"tools/call",params:{name:"get_repository",arguments:{owner:$owner,repo:$repo}}}')" + call_code="$(mcp_post "$call_payload" "$response_headers_file" "${session_args[@]}")" + assert_success_response "MCP get_repository" "$call_code" + if jq -e '.result.isError == true' "$json_file" >/dev/null; then + tool_error="$(jq -r '([.result.content[]?.text] | join(" "))[0:200]' "$json_file")" + echo "MCP get_repository returned a tool error: $tool_error" + echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + repository_content="$(jq -r '[.result.content[]? | select(.type == "text") | .text] | join(" ")' "$json_file")" + if [[ "$repository_content" != *"$GITHUB_REPOSITORY"* ]]; then + echo "MCP get_repository did not return the requested repository." + echo "- ❌ MCP get_repository: result did not identify \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi + echo "- ✅ MCP get_repository: retrieved \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." features: gh-aw-detection: true sandbox: diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 5df0a0ba4ad..bd609de57f0 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -1549,6 +1549,7 @@ jobs: # - Bash # - BashOutput # - Edit + # - Edit(/tmp/*) # - Edit(/tmp/gh-aw/agent/*) # - Edit(/tmp/gh-aw/cache-memory/*) # - ExitPlanMode @@ -1557,16 +1558,19 @@ jobs: # - KillBash # - LS # - MultiEdit + # - MultiEdit(/tmp/*) # - MultiEdit(/tmp/gh-aw/agent/*) # - MultiEdit(/tmp/gh-aw/cache-memory/*) # - NotebookEdit # - NotebookRead # - Read + # - Read(/tmp/*) # - Read(/tmp/gh-aw/agent/*) # - Read(/tmp/gh-aw/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/*) # - Write(/tmp/gh-aw/agent/*) # - Write(/tmp/gh-aw/cache-memory/*) # - mcp__agenticworkflows @@ -1667,7 +1671,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --tty --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env ANTHROPIC_API_KEY --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --exclude-env TAVILY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 100 --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__agenticworkflows,mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__mcpscripts,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for,mcp__safeoutputs,mcp__tavily'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --bare --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 100 --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__agenticworkflows,mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__mcpscripts,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for,mcp__safeoutputs,mcp__tavily'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --bare --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MAX_RETRIES: 0 diff --git a/.github/workflows/step-name-alignment.lock.yml b/.github/workflows/step-name-alignment.lock.yml index 79ea464dff2..621b8c694a6 100644 --- a/.github/workflows/step-name-alignment.lock.yml +++ b/.github/workflows/step-name-alignment.lock.yml @@ -871,6 +871,7 @@ jobs: # - Bash(yq*) # - BashOutput # - Edit + # - Edit(/tmp/*) # - Edit(/tmp/gh-aw/agent/*) # - Edit(/tmp/gh-aw/cache-memory/*) # - ExitPlanMode @@ -879,16 +880,19 @@ jobs: # - KillBash # - LS # - MultiEdit + # - MultiEdit(/tmp/*) # - MultiEdit(/tmp/gh-aw/agent/*) # - MultiEdit(/tmp/gh-aw/cache-memory/*) # - NotebookEdit # - NotebookRead # - Read + # - Read(/tmp/*) # - Read(/tmp/gh-aw/agent/*) # - Read(/tmp/gh-aw/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/*) # - Write(/tmp/gh-aw/agent/*) # - Write(/tmp/gh-aw/cache-memory/*) # - mcp__github__actions_get @@ -965,7 +969,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --tty --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env ANTHROPIC_API_KEY --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 50 --allowed-tools '\''Bash(cat /tmp/gh-aw/agent/step-alignment-input.json),Bash(cat /tmp/gh-aw/cache-memory/),Bash(cat > /tmp/gh-aw/cache-memory/),Bash(cat docs/src/content/docs/reference/glossary.md),Bash(cat),Bash(date),Bash(echo),Bash(find .github/workflows -name "*.lock.yml" -type f),Bash(gh:*),Bash(git log --since="24 hours ago" --oneline --name-only -- ".github/workflows/*.lock.yml"),Bash(grep),Bash(head),Bash(jq* /tmp/gh-aw/agent/step-alignment-input.json),Bash(ls),Bash(mkdir -p /tmp/gh-aw/cache-memory/),Bash(mv /tmp/gh-aw/cache-memory/),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),Bash(yq*),BashOutput,Edit,Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 50 --allowed-tools '\''Bash(cat /tmp/gh-aw/agent/step-alignment-input.json),Bash(cat /tmp/gh-aw/cache-memory/),Bash(cat > /tmp/gh-aw/cache-memory/),Bash(cat docs/src/content/docs/reference/glossary.md),Bash(cat),Bash(date),Bash(echo),Bash(find .github/workflows -name "*.lock.yml" -type f),Bash(gh:*),Bash(git log --since="24 hours ago" --oneline --name-only -- ".github/workflows/*.lock.yml"),Bash(grep),Bash(head),Bash(jq* /tmp/gh-aw/agent/step-alignment-input.json),Bash(ls),Bash(mkdir -p /tmp/gh-aw/cache-memory/),Bash(mv /tmp/gh-aw/cache-memory/),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),Bash(yq*),BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MAX_RETRIES: 0