diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index a48acdcc427..21cffd435d1 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"6d0a385e47ce5ed241f4358e1578525037722f288b64d3dc18289d01bd352fbd","agent_id":"copilot"} +# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"c38bfced4d0d58420a4e37771a9978cd1ef356dbd60e9c8ca2e46d60ff0a2c4b","agent_id":"copilot"} # ___ _ _ # / _ \ | | (_) # | |_| | __ _ ___ _ __ | |_ _ ___ @@ -27,7 +27,6 @@ # Imports: # - shared/gh.md # - shared/github-guard-policy.md -# - shared/github-queries-mcp-script.md # - shared/mcp/serena-go.md # - shared/mcp/serena.md # - shared/observability-otlp.md @@ -211,7 +210,7 @@ jobs: GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number || inputs.item_number }} + GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} @@ -220,9 +219,9 @@ jobs: run: | bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh { - cat << 'GH_AW_PROMPT_2d91fec7281e9c47_EOF' + cat << 'GH_AW_PROMPT_9972a8768a8af6e3_EOF' - GH_AW_PROMPT_2d91fec7281e9c47_EOF + GH_AW_PROMPT_9972a8768a8af6e3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" @@ -230,7 +229,7 @@ jobs: cat "${RUNNER_TEMP}/gh-aw/prompts/agentic_workflows_guide.md" cat "${RUNNER_TEMP}/gh-aw/prompts/cache_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_2d91fec7281e9c47_EOF' + cat << 'GH_AW_PROMPT_9972a8768a8af6e3_EOF' Tools: add_comment(max:2), create_issue, create_discussion, create_pull_request_review_comment(max:5), submit_pull_request_review, reply_to_pull_request_review_comment(max:5), add_labels, remove_labels, set_issue_type, dispatch_workflow, missing_tool, missing_data, noop, send_slack_message @@ -262,9 +261,9 @@ jobs: {{/if}} - GH_AW_PROMPT_2d91fec7281e9c47_EOF + GH_AW_PROMPT_9972a8768a8af6e3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_2d91fec7281e9c47_EOF' + cat << 'GH_AW_PROMPT_9972a8768a8af6e3_EOF' ## Serena Code Analysis @@ -300,18 +299,16 @@ jobs: {{#runtime-import .github/workflows/shared/github-guard-policy.md}} {{#runtime-import .github/workflows/shared/gh.md}} {{#runtime-import .github/workflows/shared/reporting.md}} - {{#runtime-import .github/workflows/shared/github-queries-mcp-script.md}} {{#runtime-import .github/workflows/shared/mcp/serena-go.md}} {{#runtime-import .github/workflows/shared/observability-otlp.md}} {{#runtime-import .github/workflows/smoke-copilot.md}} - GH_AW_PROMPT_2d91fec7281e9c47_EOF + GH_AW_PROMPT_9972a8768a8af6e3_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 env: GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number || inputs.item_number }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} @@ -332,7 +329,7 @@ jobs: GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }} GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }} GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }} - GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number || inputs.item_number }} + GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} GH_AW_GITHUB_REPOSITORY: ${{ github.repository }} GH_AW_GITHUB_RUN_ID: ${{ github.run_id }} GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }} @@ -477,6 +474,25 @@ jobs: run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh env: GH_TOKEN: ${{ github.token }} + - name: Start DIFC proxy for pre-agent gh calls + env: + GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + GITHUB_SERVER_URL: ${{ github.server_url }} + DIFC_PROXY_POLICY: '{"allow-only":{"min-integrity":"approved","repos":"all"}}' + DIFC_PROXY_IMAGE: 'ghcr.io/github/gh-aw-mcpg:v0.2.12' + run: | + bash ${RUNNER_TEMP}/gh-aw/actions/start_difc_proxy.sh + - name: Set GH_REPO for proxied steps + run: | + echo "GH_REPO=${GITHUB_REPOSITORY}" >> "$GITHUB_ENV" + - env: + GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + if: github.event_name == 'pull_request' + name: Pre-fetch PR context + run: "mkdir -p /tmp/gh-aw/agent\ngh api \\\n \"/repos/$REPO/pulls/$PR_NUMBER\" \\\n --jq '{number, title, author: .user, assignees}' \\\n > /tmp/gh-aw/agent/smoke-pr-meta.json\ngh api \\\n \"/repos/$REPO/pulls/$PR_NUMBER/files\" \\\n --jq '[.[] | select(.patch != null) | {filename, patch}][0:3]' \\\n > /tmp/gh-aw/agent/smoke-pr-files.json\n" + # Cache memory file share configuration from frontmatter processed below - name: Create cache-memory directory run: bash ${RUNNER_TEMP}/gh-aw/actions/create_cache_memory_dir.sh @@ -533,6 +549,10 @@ jobs: GH_AW_APPROVAL_LABELS_EXTRA: cookie,community GH_AW_APPROVAL_LABELS_VAR: ${{ vars.GH_AW_GITHUB_APPROVAL_LABELS || '' }} run: bash ${RUNNER_TEMP}/gh-aw/actions/parse_guard_list.sh + - name: Stop DIFC proxy + if: always() + continue-on-error: true + run: bash ${RUNNER_TEMP}/gh-aw/actions/stop_difc_proxy.sh - name: Download container images run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.13 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.13 ghcr.io/github/gh-aw-firewall/squid:0.25.13 ghcr.io/github/gh-aw-mcpg:v0.2.12 ghcr.io/github/github-mcp-server:v0.32.0 ghcr.io/github/serena-mcp-server:latest mcr.microsoft.com/playwright/mcp node:lts-alpine - name: Install gh-aw extension @@ -564,12 +584,12 @@ jobs: mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_8c3103569671ea37_EOF' + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_373124ea0baa719b_EOF' {"add_comment":{"allowed_repos":["github/gh-aw"],"hide_older_comments":true,"max":2},"add_labels":{"allowed":["smoke-copilot"],"allowed_repos":["github/gh-aw"]},"create_discussion":{"category":"announcements","close_older_discussions":true,"close_older_key":"smoke-copilot","expires":2,"fallback_to_issue":true,"labels":["ai-generated"],"max":1},"create_issue":{"close_older_issues":true,"close_older_key":"smoke-copilot","expires":2,"group":true,"labels":["automation","testing"],"max":1},"create_pull_request_review_comment":{"max":5,"side":"RIGHT"},"dispatch_workflow":{"max":1,"workflow_files":{"haiku-printer":".yml"},"workflows":["haiku-printer"]},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"remove_labels":{"allowed":["smoke"]},"reply_to_pull_request_review_comment":{"max":5},"send-slack-message":{"description":"Send a message to Slack (stub for testing)","inputs":{"message":{"description":"The message to send","required":false,"type":"string"}},"output":"Slack message stub executed!"},"set_issue_type":{},"submit_pull_request_review":{"max":1}} - GH_AW_SAFE_OUTPUTS_CONFIG_8c3103569671ea37_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_373124ea0baa719b_EOF - name: Write Safe Outputs Tools run: | - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_6ba81623fc072ff3_EOF' + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_f4160f8e2e127874_EOF' { "description_suffixes": { "add_comment": " CONSTRAINTS: Maximum 2 comment(s) can be added.", @@ -627,8 +647,8 @@ jobs: } ] } - GH_AW_SAFE_OUTPUTS_TOOLS_META_6ba81623fc072ff3_EOF - cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_4cb5c46d855d3c50_EOF' + GH_AW_SAFE_OUTPUTS_TOOLS_META_f4160f8e2e127874_EOF + cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_212fc0438b515c40_EOF' { "add_comment": { "defaultMax": 1, @@ -898,7 +918,7 @@ jobs: } } } - GH_AW_SAFE_OUTPUTS_VALIDATION_4cb5c46d855d3c50_EOF + GH_AW_SAFE_OUTPUTS_VALIDATION_212fc0438b515c40_EOF node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs - name: Generate Safe Outputs MCP Server Config id: safe-outputs-config @@ -943,7 +963,7 @@ jobs: - name: Setup MCP Scripts Config run: | mkdir -p ${RUNNER_TEMP}/gh-aw/mcp-scripts/logs - cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/tools.json << 'GH_AW_MCP_SCRIPTS_TOOLS_7babc89e6d790778_EOF' + cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/tools.json << 'GH_AW_MCP_SCRIPTS_TOOLS_33270c13e6d0d177_EOF' { "serverName": "mcpscripts", "version": "1.0.0", @@ -970,97 +990,11 @@ jobs: "GH_DEBUG": "GH_DEBUG" }, "timeout": 60 - }, - { - "name": "github-discussion-query", - "description": "Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", - "inputSchema": { - "properties": { - "jq": { - "description": "jq filter expression to apply to output. If not provided, returns schema info instead of full data.", - "type": "string" - }, - "limit": { - "description": "Maximum number of discussions to fetch (default: 30)", - "type": "number" - }, - "repo": { - "description": "Repository in owner/repo format (defaults to current repository)", - "type": "string" - } - }, - "type": "object" - }, - "handler": "github-discussion-query.sh", - "env": { - "GH_TOKEN": "GH_TOKEN" - }, - "timeout": 60 - }, - { - "name": "github-issue-query", - "description": "Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", - "inputSchema": { - "properties": { - "jq": { - "description": "jq filter expression to apply to output. If not provided, returns schema info instead of full data.", - "type": "string" - }, - "limit": { - "description": "Maximum number of issues to fetch (default: 30)", - "type": "number" - }, - "repo": { - "description": "Repository in owner/repo format (defaults to current repository)", - "type": "string" - }, - "state": { - "description": "Issue state: open, closed, all (default: open)", - "type": "string" - } - }, - "type": "object" - }, - "handler": "github-issue-query.sh", - "env": { - "GH_TOKEN": "GH_TOKEN" - }, - "timeout": 60 - }, - { - "name": "github-pr-query", - "description": "Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter.", - "inputSchema": { - "properties": { - "jq": { - "description": "jq filter expression to apply to output. If not provided, returns schema info instead of full data.", - "type": "string" - }, - "limit": { - "description": "Maximum number of PRs to fetch (default: 30)", - "type": "number" - }, - "repo": { - "description": "Repository in owner/repo format (defaults to current repository)", - "type": "string" - }, - "state": { - "description": "PR state: open, closed, merged, all (default: open)", - "type": "string" - } - }, - "type": "object" - }, - "handler": "github-pr-query.sh", - "env": { - "GH_TOKEN": "GH_TOKEN" - }, - "timeout": 60 } ] } - GH_AW_MCP_SCRIPTS_TOOLS_7babc89e6d790778_EOF - cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/mcp-server.cjs << 'GH_AW_MCP_SCRIPTS_SERVER_ef1fbc7ce3eca295_EOF' + GH_AW_MCP_SCRIPTS_TOOLS_33270c13e6d0d177_EOF + cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/mcp-server.cjs << 'GH_AW_MCP_SCRIPTS_SERVER_682074a45d6cbf70_EOF' const path = require("path"); const { startHttpServer } = require("./mcp_scripts_mcp_server_http.cjs"); const configPath = path.join(__dirname, "tools.json"); @@ -1074,12 +1008,12 @@ jobs: console.error("Failed to start mcp-scripts HTTP server:", error); process.exit(1); }); - GH_AW_MCP_SCRIPTS_SERVER_ef1fbc7ce3eca295_EOF + GH_AW_MCP_SCRIPTS_SERVER_682074a45d6cbf70_EOF chmod +x ${RUNNER_TEMP}/gh-aw/mcp-scripts/mcp-server.cjs - name: Setup MCP Scripts Tool Files run: | - cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/gh.sh << 'GH_AW_MCP_SCRIPTS_SH_GH_5a6688685d632c08_EOF' + cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/gh.sh << 'GH_AW_MCP_SCRIPTS_SH_GH_e5b12cc02f4cc4a8_EOF' #!/bin/bash # Auto-generated mcp-script tool: gh # Execute any gh CLI command. This tool is accessible as 'mcpscripts-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. @@ -1090,313 +1024,8 @@ jobs: echo " token: ${GH_AW_GH_TOKEN:0:6}..." GH_TOKEN="$GH_AW_GH_TOKEN" gh $INPUT_ARGS - GH_AW_MCP_SCRIPTS_SH_GH_5a6688685d632c08_EOF + GH_AW_MCP_SCRIPTS_SH_GH_e5b12cc02f4cc4a8_EOF chmod +x ${RUNNER_TEMP}/gh-aw/mcp-scripts/gh.sh - cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/github-discussion-query.sh << 'GH_AW_MCP_SCRIPTS_SH_GITHUB-DISCUSSION-QUERY_acccc7340415fad4_EOF' - #!/bin/bash - # Auto-generated mcp-script tool: github-discussion-query - # Query GitHub discussions with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter. - - set -euo pipefail - - set -e - - # Default values - REPO="${INPUT_REPO:-}" - LIMIT="${INPUT_LIMIT:-30}" - JQ_FILTER="${INPUT_JQ:-}" - - # Parse repository owner and name - if [[ -n "$REPO" ]]; then - OWNER=$(echo "$REPO" | cut -d'/' -f1) - NAME=$(echo "$REPO" | cut -d'/' -f2) - else - # Get current repository from GitHub context - OWNER="${GITHUB_REPOSITORY_OWNER:-}" - NAME=$(echo "${GITHUB_REPOSITORY:-}" | cut -d'/' -f2) - fi - - # Validate owner and name - if [[ -z "$OWNER" || -z "$NAME" ]]; then - echo "Error: Could not determine repository owner and name" >&2 - exit 1 - fi - - # Build GraphQL query for discussions - GRAPHQL_QUERY=$(cat < ${RUNNER_TEMP}/gh-aw/mcp-scripts/github-issue-query.sh << 'GH_AW_MCP_SCRIPTS_SH_GITHUB-ISSUE-QUERY_a6eacbb65c40c0ed_EOF' - #!/bin/bash - # Auto-generated mcp-script tool: github-issue-query - # Query GitHub issues with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter. - - set -euo pipefail - - set -e - - # Default values - REPO="${INPUT_REPO:-}" - STATE="${INPUT_STATE:-open}" - LIMIT="${INPUT_LIMIT:-30}" - JQ_FILTER="${INPUT_JQ:-}" - - # JSON fields to fetch - JSON_FIELDS="number,title,state,author,createdAt,updatedAt,closedAt,body,labels,assignees,comments,milestone,url" - - # Build and execute gh command - if [[ -n "$REPO" ]]; then - OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO") - else - OUTPUT=$(gh issue list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS") - fi - - # Apply jq filter if specified - if [[ -n "$JQ_FILTER" ]]; then - jq "$JQ_FILTER" <<< "$OUTPUT" - else - # Return schema and size instead of full data - ITEM_COUNT=$(jq 'length' <<< "$OUTPUT") - DATA_SIZE=${#OUTPUT} - - # Validate values are numeric - if ! [[ "$ITEM_COUNT" =~ ^[0-9]+$ ]]; then - ITEM_COUNT=0 - fi - if ! [[ "$DATA_SIZE" =~ ^[0-9]+$ ]]; then - DATA_SIZE=0 - fi - - cat << EOF - { - "message": "No --jq filter provided. Use --jq to filter and retrieve data.", - "item_count": $ITEM_COUNT, - "data_size_bytes": $DATA_SIZE, - "schema": { - "type": "array", - "description": "Array of issue objects", - "item_fields": { - "number": "integer - Issue number", - "title": "string - Issue title", - "state": "string - Issue state (OPEN, CLOSED)", - "author": "object - Author info with login field", - "createdAt": "string - ISO timestamp of creation", - "updatedAt": "string - ISO timestamp of last update", - "closedAt": "string|null - ISO timestamp of close", - "body": "string - Issue body content", - "labels": "array - Array of label objects with name field", - "assignees": "array - Array of assignee objects with login field", - "comments": "object - Comments info with totalCount field", - "milestone": "object|null - Milestone info with title field", - "url": "string - Issue URL" - } - }, - "suggested_queries": [ - {"description": "Get all data", "query": "."}, - {"description": "Get issue numbers and titles", "query": ".[] | {number, title}"}, - {"description": "Get open issues only", "query": ".[] | select(.state == \"OPEN\")"}, - {"description": "Get issues by author", "query": ".[] | select(.author.login == \"USERNAME\")"}, - {"description": "Get issues with label", "query": ".[] | select(.labels | map(.name) | index(\"bug\"))"}, - {"description": "Get issues with many comments", "query": ".[] | select(.comments.totalCount > 5) | {number, title, comments: .comments.totalCount}"}, - {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"} - ] - } - EOF - fi - - - GH_AW_MCP_SCRIPTS_SH_GITHUB-ISSUE-QUERY_a6eacbb65c40c0ed_EOF - chmod +x ${RUNNER_TEMP}/gh-aw/mcp-scripts/github-issue-query.sh - cat > ${RUNNER_TEMP}/gh-aw/mcp-scripts/github-pr-query.sh << 'GH_AW_MCP_SCRIPTS_SH_GITHUB-PR-QUERY_cba8eb127506e4a8_EOF' - #!/bin/bash - # Auto-generated mcp-script tool: github-pr-query - # Query GitHub pull requests with jq filtering support. Without --jq, returns schema and data size info. Use --jq '.' to get all data, or specific jq expressions to filter. - - set -euo pipefail - - set -e - - # Default values - REPO="${INPUT_REPO:-}" - STATE="${INPUT_STATE:-open}" - LIMIT="${INPUT_LIMIT:-30}" - JQ_FILTER="${INPUT_JQ:-}" - - # JSON fields to fetch - JSON_FIELDS="number,title,state,author,createdAt,updatedAt,mergedAt,closedAt,headRefName,baseRefName,isDraft,reviewDecision,additions,deletions,changedFiles,labels,assignees,reviewRequests,url" - - # Build and execute gh command - if [[ -n "$REPO" ]]; then - OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS" --repo "$REPO") - else - OUTPUT=$(gh pr list --state "$STATE" --limit "$LIMIT" --json "$JSON_FIELDS") - fi - - # Apply jq filter if specified - if [[ -n "$JQ_FILTER" ]]; then - jq "$JQ_FILTER" <<< "$OUTPUT" - else - # Return schema and size instead of full data - ITEM_COUNT=$(jq 'length' <<< "$OUTPUT") - DATA_SIZE=${#OUTPUT} - - # Validate values are numeric - if ! [[ "$ITEM_COUNT" =~ ^[0-9]+$ ]]; then - ITEM_COUNT=0 - fi - if ! [[ "$DATA_SIZE" =~ ^[0-9]+$ ]]; then - DATA_SIZE=0 - fi - - cat << EOF - { - "message": "No --jq filter provided. Use --jq to filter and retrieve data.", - "item_count": $ITEM_COUNT, - "data_size_bytes": $DATA_SIZE, - "schema": { - "type": "array", - "description": "Array of pull request objects", - "item_fields": { - "number": "integer - PR number", - "title": "string - PR title", - "state": "string - PR state (OPEN, CLOSED, MERGED)", - "author": "object - Author info with login field", - "createdAt": "string - ISO timestamp of creation", - "updatedAt": "string - ISO timestamp of last update", - "mergedAt": "string|null - ISO timestamp of merge", - "closedAt": "string|null - ISO timestamp of close", - "headRefName": "string - Source branch name", - "baseRefName": "string - Target branch name", - "isDraft": "boolean - Whether PR is a draft", - "reviewDecision": "string|null - Review decision (APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED)", - "additions": "integer - Lines added", - "deletions": "integer - Lines deleted", - "changedFiles": "integer - Number of files changed", - "labels": "array - Array of label objects with name field", - "assignees": "array - Array of assignee objects with login field", - "reviewRequests": "array - Array of review request objects", - "url": "string - PR URL" - } - }, - "suggested_queries": [ - {"description": "Get all data", "query": "."}, - {"description": "Get PR numbers and titles", "query": ".[] | {number, title}"}, - {"description": "Get open PRs only", "query": ".[] | select(.state == \"OPEN\")"}, - {"description": "Get merged PRs", "query": ".[] | select(.mergedAt != null)"}, - {"description": "Get PRs by author", "query": ".[] | select(.author.login == \"USERNAME\")"}, - {"description": "Get large PRs", "query": ".[] | select(.changedFiles > 10) | {number, title, changedFiles}"}, - {"description": "Count by state", "query": "group_by(.state) | map({state: .[0].state, count: length})"} - ] - } - EOF - fi - - - GH_AW_MCP_SCRIPTS_SH_GITHUB-PR-QUERY_cba8eb127506e4a8_EOF - chmod +x ${RUNNER_TEMP}/gh-aw/mcp-scripts/github-pr-query.sh - name: Generate MCP Scripts Server Config id: mcp-scripts-config @@ -1424,7 +1053,6 @@ jobs: GH_AW_MCP_SCRIPTS_API_KEY: ${{ steps.mcp-scripts-config.outputs.mcp_scripts_api_key }} GH_AW_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_DEBUG: 1 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | # Environment variables are set above to prevent template injection export DEBUG @@ -1443,7 +1071,6 @@ jobs: 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 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | @@ -1463,10 +1090,10 @@ jobs: export DEBUG="*" 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 MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_MCP_SCRIPTS_PORT -e GH_AW_MCP_SCRIPTS_API_KEY -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GH_AW_GH_TOKEN -e GH_DEBUG -e GH_TOKEN -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.2.12' + 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 MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_MCP_SCRIPTS_PORT -e GH_AW_MCP_SCRIPTS_API_KEY -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e GH_AW_GH_TOKEN -e GH_DEBUG -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.2.12' mkdir -p /home/runner/.copilot - cat << GH_AW_MCP_CONFIG_8d31e9e79e8b0709_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh + cat << GH_AW_MCP_CONFIG_5d5f50320a6e92d2_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh { "mcpServers": { "agenticworkflows": { @@ -1586,7 +1213,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_8d31e9e79e8b0709_EOF + GH_AW_MCP_CONFIG_5d5f50320a6e92d2_EOF - name: Download activation artifact uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: @@ -1603,8 +1230,8 @@ jobs: set -o pipefail touch /tmp/gh-aw/agent-step-summary.md # shellcheck disable=SC1003 - sudo -E awf --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" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_GH_TOKEN --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,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,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,go.dev,golang.org,googleapis.deno.dev,googlechromelabs.github.io,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,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,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,playwright.download.prss.microsoft.com,ppa.launchpad.net,proxy.golang.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,sum.golang.org,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ - -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --autopilot --max-autopilot-continues 2 --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + sudo -E awf --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" --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GH_AW_GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --allow-domains '*.githubusercontent.com,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,bun.sh,cdn.jsdelivr.net,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,deb.nodesource.com,deno.land,docs.github.com,esm.sh,get.pnpm.io,github-cloud.githubusercontent.com,github-cloud.s3.amazonaws.com,github.blog,github.com,github.githubassets.com,go.dev,golang.org,googleapis.deno.dev,googlechromelabs.github.io,goproxy.io,host.docker.internal,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,lfs.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,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,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pkg.go.dev,playwright.download.prss.microsoft.com,ppa.launchpad.net,proxy.golang.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.yarnpkg.com,s.symcb.com,s.symcd.com,security.ubuntu.com,skimdb.npmjs.com,storage.googleapis.com,sum.golang.org,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.npmjs.com,www.npmjs.org,yarnpkg.com' --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --image-tag 0.25.13 --skip-pull --enable-api-proxy \ + -- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-all-tools --add-dir /tmp/gh-aw/cache-memory/ --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: COPILOT_AGENT_RUNNER_TYPE: STANDALONE COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }} @@ -1616,7 +1243,6 @@ jobs: GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }} GH_AW_VERSION: dev GH_DEBUG: 1 - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_API_URL: ${{ github.api_url }} GITHUB_AW: true GITHUB_HEAD_REF: ${{ github.head_ref }} diff --git a/.github/workflows/smoke-copilot.md b/.github/workflows/smoke-copilot.md index 8c6087573ed..e487fd2d144 100644 --- a/.github/workflows/smoke-copilot.md +++ b/.github/workflows/smoke-copilot.md @@ -18,12 +18,11 @@ permissions: name: Smoke Copilot engine: id: copilot - max-continuations: 2 + max-continuations: 1 imports: - shared/github-guard-policy.md - shared/gh.md - shared/reporting.md - - shared/github-queries-mcp-script.md - shared/mcp/serena-go.md - shared/observability-otlp.md network: @@ -116,6 +115,23 @@ safe-outputs: run-started: "📰 BREAKING: [{workflow_name}]({run_url}) is now investigating this {event_type}. Sources say the story is developing..." run-success: "📰 VERDICT: [{workflow_name}]({run_url}) has concluded. All systems operational. This is a developing story. 🎤" run-failure: "📰 DEVELOPING STORY: [{workflow_name}]({run_url}) reports {status}. Our correspondents are investigating the incident..." +steps: + - name: Pre-fetch PR context + if: github.event_name == 'pull_request' + env: + GH_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + REPO: ${{ github.repository }} + run: | + mkdir -p /tmp/gh-aw/agent + gh api \ + "/repos/$REPO/pulls/$PR_NUMBER" \ + --jq '{number, title, author: .user, assignees}' \ + > /tmp/gh-aw/agent/smoke-pr-meta.json + gh api \ + "/repos/$REPO/pulls/$PR_NUMBER/files" \ + --jq '[.[] | select(.patch != null) | {filename, patch}][0:3]' \ + > /tmp/gh-aw/agent/smoke-pr-files.json timeout-minutes: 15 strict: false --- @@ -124,6 +140,8 @@ strict: false **IMPORTANT: Keep all outputs extremely short and concise. Use single-line responses where possible. No verbose explanations.** +**EFFICIENCY RULE: Complete all 12 tests in ≤ 15 tool calls total. Do not verify what you've already confirmed. Batch reads where possible.** + ## Test Requirements 1. **GitHub MCP Testing**: Review the last 2 merged pull requests in ${{ github.repository }} @@ -136,13 +154,13 @@ strict: false 6. **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) 7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) 8. **Discussion Interaction Testing**: - - Use the `github-discussion-query` mcp-script tool with params: `limit=1, jq=".[0]"` to get the latest discussion from ${{ github.repository }} + - Use the `list_discussions` GitHub MCP tool — split `${{ github.repository }}` by `/` to set `owner` (first part) and `repo` (second part), and set `perPage: 1` — to get the latest discussion - Extract the discussion number from the result (e.g., if the result is `{"number": 123, "title": "...", ...}`, extract 123) - Use the `add_comment` tool with `discussion_number: ` to add a fun, playful comment stating that the smoke test agent was here 9. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project (both caches must be set to /tmp because the default cache locations are not writable). If the command fails, mark this test as ❌ and report the failure. 10. **Discussion Creation Testing**: Use the `create_discussion` safe-output tool to create a discussion in the announcements category titled "copilot was here" with the label "ai-generated" 11. **Workflow Dispatch Testing**: Use the `dispatch_workflow` safe output tool to trigger the `haiku-printer` workflow with a haiku as the message input. Create an original, creative haiku about software testing or automation. -12. **PR Review Testing**: Review the diff of the current pull request. Leave 1-2 inline `create_pull_request_review_comment` comments on specific lines, then call `submit_pull_request_review` with a brief body summarizing your review and event `COMMENT`. To test `reply_to_pull_request_review_comment`: use the `pull_request_read` tool (with `method: "get_review_comments"` and `pullNumber: ${{ github.event.pull_request.number }}`) to fetch the PR's existing review comments, then reply to the most recent one using `reply_to_pull_request_review_comment` with its actual numeric `id` as the `comment_id`. Note: `create_pull_request_review_comment` does not return a `comment_id` — you must fetch existing comment IDs from the GitHub API. If the PR has no existing review comments, skip the reply sub-test. +12. **PR Review Testing** (only if triggered by a pull_request event): Read the pre-fetched PR context from `/tmp/gh-aw/agent/smoke-pr-meta.json` (PR metadata) and `/tmp/gh-aw/agent/smoke-pr-files.json` (changed files with patch lines). From the files JSON, pick a file and find a line added in the patch (lines prefixed with `+` in the hunk, counting from the hunk header `@@ -a,b +c,d @@` where `c` is the starting line — use the position offset within the patch). Create 1 inline `create_pull_request_review_comment` on that file and line, then call `submit_pull_request_review` with a brief body and event `COMMENT`. Do not call the GitHub API to re-fetch this data. Skip if not a PR event. ## Output