diff --git a/.github/workflows/copilot-centralization-optimizer.lock.yml b/.github/workflows/copilot-centralization-optimizer.lock.yml index 5291346bc73..f9fa1467143 100644 --- a/.github/workflows/copilot-centralization-optimizer.lock.yml +++ b/.github/workflows/copilot-centralization-optimizer.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d96033297d67e1117ac54b7b9a852d4c3ec86fb4924e4abc20d0d9c1776e563a","body_hash":"b0275c42aea96f7ac0d7f4819dabe9cb5fdb3829bb179743f5efa6d105871520","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5abbb71c8183c2b6bcaa82298d561a780aa4c44e355a65263458cba3bc44120a","body_hash":"b0275c42aea96f7ac0d7f4819dabe9cb5fdb3829bb179743f5efa6d105871520","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.63"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/cache/save","sha":"27d5ce7f107fe9357f9df03efb73ab90386fccae","version":"v5.0.5"},{"repo":"actions/checkout","sha":"9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0","version":"v7.0.0"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7","digest":"sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.7@sha256:aae231e4635c8999d039c132f1602d3df850fe9b84a00aa2b5ac981179b5661c"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7","digest":"sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.7@sha256:009caf2e3d88fa77b64e9a03a95a228fc58db0f1701c6d324b29ba5a3c7c79b6"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7","digest":"sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.7@sha256:deb1d4e19de62d51cee0508057a596a19315c3423ada4d675cad136dc8037c96"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.27","digest":"sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.27@sha256:fe984bddde4ec05d756d9043edb0a32912e6b7b72f6a121b1082f29221421cc7"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b","pinned_image":"ghcr.io/github/gh-aw-node@sha256:529d02eb970b1161aa25c593a9c3df57fdfad5a8add328cb3b6eccef66f3183b"},{"image":"ghcr.io/github/github-mcp-server:v1.4.0","digest":"sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036","pinned_image":"ghcr.io/github/github-mcp-server:v1.4.0@sha256:2afb26356481d1a350e14544a6e160f7f7ec1561a1ea309b823665abf0309036"}]} # 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 # @@ -233,21 +233,21 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh" { - cat << 'GH_AW_PROMPT_e387428860c5431f_EOF' + cat << 'GH_AW_PROMPT_185b9582e53f12c3_EOF' - GH_AW_PROMPT_e387428860c5431f_EOF + GH_AW_PROMPT_185b9582e53f12c3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md" cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md" cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md" cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md" - cat << 'GH_AW_PROMPT_e387428860c5431f_EOF' + cat << 'GH_AW_PROMPT_185b9582e53f12c3_EOF' Tools: create_issue, missing_tool, missing_data, noop - GH_AW_PROMPT_e387428860c5431f_EOF + GH_AW_PROMPT_185b9582e53f12c3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md" - cat << 'GH_AW_PROMPT_e387428860c5431f_EOF' + cat << 'GH_AW_PROMPT_185b9582e53f12c3_EOF' The following GitHub context information is available for this workflow: {{#if github.actor}} @@ -276,12 +276,12 @@ jobs: {{/if}} - GH_AW_PROMPT_e387428860c5431f_EOF + GH_AW_PROMPT_185b9582e53f12c3_EOF cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md" - cat << 'GH_AW_PROMPT_e387428860c5431f_EOF' + cat << 'GH_AW_PROMPT_185b9582e53f12c3_EOF' {{#runtime-import .github/workflows/copilot-centralization-optimizer.md}} - GH_AW_PROMPT_e387428860c5431f_EOF + GH_AW_PROMPT_185b9582e53f12c3_EOF } > "$GH_AW_PROMPT" - name: Interpolate variables and render templates uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 @@ -457,7 +457,7 @@ jobs: TASK_LIMIT: "300" TASK_LOOKBACK_DAYS: "30" name: Collect agent task data - run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/data\n: > /tmp/gh-aw/data/task-summaries.jsonl\n\nSINCE=\"$(date -u -d \"-${TASK_LOOKBACK_DAYS} days\" +%Y-%m-%dT%H:%M:%SZ)\"\nAPI_VERSION=\"2026-03-10\"\n\ngh api --paginate \\\n -H \"Accept: application/vnd.github+json\" \\\n -H \"X-GitHub-Api-Version: ${API_VERSION}\" \\\n \"/agents/repos/$REPO/tasks?per_page=100\" \\\n --jq '.tasks[].id' \\\n | while IFS= read -r task_id; do\n gh api \\\n -H \"Accept: application/vnd.github+json\" \\\n -H \"X-GitHub-Api-Version: ${API_VERSION}\" \\\n \"/agents/repos/$REPO/tasks/$task_id\" \\\n | jq -c --arg since \"$SINCE\" '\n | def sorted_sessions: (.sessions // [] | sort_by(.created_at // \"\"));\n def artifact_types: ([.artifacts[]?.type | select(.)] | join(\",\"));\n def first_non_empty_index($sessions):\n ([range(0; ($sessions | length))\n | select((($sessions[.]?.prompt // \"\") | length) > 0)] | .[0]);\n\n sorted_sessions as $sessions\n | ($sessions | length) as $session_count\n | (if $session_count == 0 then null else ($sessions[0].prompt // null) end) as $earliest_input\n | first_non_empty_index($sessions) as $first_non_empty_index\n | (if $first_non_empty_index == null then null else $sessions[$first_non_empty_index].prompt end) as $first_non_empty_input\n | (if $session_count == 0 then \"none\"\n elif $first_non_empty_index == null or $first_non_empty_index == 0 then \"earliest\"\n else \"first_non_empty\"\n end) as $input_source\n | (if $session_count == 0 then null\n elif $first_non_empty_index == null then $earliest_input\n else $first_non_empty_input\n end) as $input\n | (artifact_types) as $artifact_types\n | ($earliest_input == \"\") as $earliest_prompt_empty\n | {\n artifact_types: $artifact_types,\n creator_id: (if .creator?.id == null then null else (.creator.id | tostring) end),\n creator_login: (.creator?.login // null),\n earliest_prompt_empty: $earliest_prompt_empty,\n id: .id,\n name: .name,\n state: .state,\n created_at: .created_at,\n updated_at: .updated_at,\n url: .html_url,\n earliest_input: $earliest_input,\n first_non_empty_input: $first_non_empty_input,\n input: $input,\n input_source: $input_source,\n input_session_index: (if $session_count == 0 then null elif $first_non_empty_index == null then 0 else $first_non_empty_index end),\n non_empty_prompt_count: ([.sessions[]?.prompt // \"\" | select(length > 0)] | length),\n session_count: $session_count,\n start_context_confidence: \"derived\",\n start_context_guess: (\n if $artifact_types == \"pull,branch\" and $earliest_prompt_empty then \"pull_branch_bootstrap\"\n elif $artifact_types == \"pull,branch,pull\" and $earliest_prompt_empty then \"pull_branch_review_bootstrap\"\n elif ($artifact_types | contains(\"pull\")) and $earliest_prompt_empty then \"pull_bootstrap\"\n elif $earliest_prompt_empty then \"bootstrap_unknown\"\n else \"direct_prompt\"\n end\n ),\n used_fallback_input: ($session_count > 0 and $first_non_empty_index != null and $first_non_empty_index > 0)\n }\n ' || true\n done \\\n | head -n \"$TASK_LIMIT\" \\\n >> /tmp/gh-aw/data/task-summaries.jsonl\n" + run: "set -euo pipefail\nmkdir -p /tmp/gh-aw/data\n: > /tmp/gh-aw/data/task-summaries.jsonl\n\nSINCE=\"$(date -u -d \"-${TASK_LOOKBACK_DAYS} days\" +%Y-%m-%dT%H:%M:%SZ)\"\nAPI_VERSION=\"2026-03-10\"\n\n_task_ids=$(mktemp)\ntrap 'rm -f \"$_task_ids\"' EXIT\n\nif gh api --paginate \\\n -H \"Accept: application/vnd.github+json\" \\\n -H \"X-GitHub-Api-Version: ${API_VERSION}\" \\\n \"/agents/repos/$REPO/tasks?per_page=100\" \\\n --jq '.tasks[].id' \\\n > \"$_task_ids\"; then\n while IFS= read -r task_id; do\n gh api \\\n -H \"Accept: application/vnd.github+json\" \\\n -H \"X-GitHub-Api-Version: ${API_VERSION}\" \\\n \"/agents/repos/$REPO/tasks/$task_id\" \\\n | jq -c --arg since \"$SINCE\" '\n | def sorted_sessions: (.sessions // [] | sort_by(.created_at // \"\"));\n def artifact_types: ([.artifacts[]?.type | select(.)] | join(\",\"));\n def first_non_empty_index($sessions):\n ([range(0; ($sessions | length))\n | select((($sessions[.]?.prompt // \"\") | length) > 0)] | .[0]);\n\n sorted_sessions as $sessions\n | ($sessions | length) as $session_count\n | (if $session_count == 0 then null else ($sessions[0].prompt // null) end) as $earliest_input\n | first_non_empty_index($sessions) as $first_non_empty_index\n | (if $first_non_empty_index == null then null else $sessions[$first_non_empty_index].prompt end) as $first_non_empty_input\n | (if $session_count == 0 then \"none\"\n elif $first_non_empty_index == null or $first_non_empty_index == 0 then \"earliest\"\n else \"first_non_empty\"\n end) as $input_source\n | (if $session_count == 0 then null\n elif $first_non_empty_index == null then $earliest_input\n else $first_non_empty_input\n end) as $input\n | (artifact_types) as $artifact_types\n | ($earliest_input == \"\") as $earliest_prompt_empty\n | {\n artifact_types: $artifact_types,\n creator_id: (if .creator?.id == null then null else (.creator.id | tostring) end),\n creator_login: (.creator?.login // null),\n earliest_prompt_empty: $earliest_prompt_empty,\n id: .id,\n name: .name,\n state: .state,\n created_at: .created_at,\n updated_at: .updated_at,\n url: .html_url,\n earliest_input: $earliest_input,\n first_non_empty_input: $first_non_empty_input,\n input: $input,\n input_source: $input_source,\n input_session_index: (if $session_count == 0 then null elif $first_non_empty_index == null then 0 else $first_non_empty_index end),\n non_empty_prompt_count: ([.sessions[]?.prompt // \"\" | select(length > 0)] | length),\n session_count: $session_count,\n start_context_confidence: \"derived\",\n start_context_guess: (\n if $artifact_types == \"pull,branch\" and $earliest_prompt_empty then \"pull_branch_bootstrap\"\n elif $artifact_types == \"pull,branch,pull\" and $earliest_prompt_empty then \"pull_branch_review_bootstrap\"\n elif ($artifact_types | contains(\"pull\")) and $earliest_prompt_empty then \"pull_bootstrap\"\n elif $earliest_prompt_empty then \"bootstrap_unknown\"\n else \"direct_prompt\"\n end\n ),\n used_fallback_input: ($session_count > 0 and $first_non_empty_index != null and $first_non_empty_index > 0)\n }\n ' || true\n done < \"$_task_ids\" \\\n | head -n \"$TASK_LIMIT\" \\\n >> /tmp/gh-aw/data/task-summaries.jsonl || true\nelse\n echo \"Agent tasks API request failed; proceeding with empty dataset\" >&2\nfi\n\n# Convert JSONL to JSON array for downstream analysis steps\njq -s '.' /tmp/gh-aw/data/task-summaries.jsonl > /tmp/gh-aw/data/task-summaries.json\n" - env: EXPR_GITHUB_EVENT_NAME: ${{ github.event_name }} EXPR_GITHUB_REPOSITORY: ${{ github.repository }} @@ -548,9 +548,9 @@ jobs: mkdir -p "${RUNNER_TEMP}/gh-aw/safeoutputs" mkdir -p /tmp/gh-aw/safeoutputs mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs - cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_c877db381b18b482_EOF' + cat > "${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" << 'GH_AW_SAFE_OUTPUTS_CONFIG_f7256a55fb2db974_EOF' {"create_issue":{"close_older_issues":true,"expires":720,"labels":["report","ai-optimization"],"max":1,"title_prefix":"[copilot-centralization] "},"create_report_incomplete_issue":{},"max_bot_mentions":1,"mentions":{"enabled":false},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":102400,"max_patch_size":10240}]},"report_incomplete":{}} - GH_AW_SAFE_OUTPUTS_CONFIG_c877db381b18b482_EOF + GH_AW_SAFE_OUTPUTS_CONFIG_f7256a55fb2db974_EOF - name: Generate Safe Outputs Tools env: GH_AW_TOOLS_META_JSON: | @@ -723,7 +723,7 @@ jobs: mkdir -p "$HOME/.copilot" GH_AW_NODE=$(which node 2>/dev/null || command -v node 2>/dev/null || echo node) - cat << GH_AW_MCP_CONFIG_2ed48797ea52df3f_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" + cat << GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs" { "mcpServers": { "github": { @@ -780,7 +780,7 @@ jobs: "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" } } - GH_AW_MCP_CONFIG_2ed48797ea52df3f_EOF + GH_AW_MCP_CONFIG_c70c556baaebe8bb_EOF - name: Mount MCP servers as CLIs id: mount-mcp-clis continue-on-error: true diff --git a/.github/workflows/copilot-centralization-optimizer.md b/.github/workflows/copilot-centralization-optimizer.md index b5b80c7a57c..225d68e5c08 100644 --- a/.github/workflows/copilot-centralization-optimizer.md +++ b/.github/workflows/copilot-centralization-optimizer.md @@ -40,12 +40,16 @@ steps: SINCE="$(date -u -d "-${TASK_LOOKBACK_DAYS} days" +%Y-%m-%dT%H:%M:%SZ)" API_VERSION="2026-03-10" - gh api --paginate \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: ${API_VERSION}" \ - "/agents/repos/$REPO/tasks?per_page=100" \ - --jq '.tasks[].id' \ - | while IFS= read -r task_id; do + _task_ids=$(mktemp) + trap 'rm -f "$_task_ids"' EXIT + + if gh api --paginate \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: ${API_VERSION}" \ + "/agents/repos/$REPO/tasks?per_page=100" \ + --jq '.tasks[].id' \ + > "$_task_ids"; then + while IFS= read -r task_id; do gh api \ -H "Accept: application/vnd.github+json" \ -H "X-GitHub-Api-Version: ${API_VERSION}" \ @@ -102,9 +106,15 @@ steps: used_fallback_input: ($session_count > 0 and $first_non_empty_index != null and $first_non_empty_index > 0) } ' || true - done \ + done < "$_task_ids" \ | head -n "$TASK_LIMIT" \ - >> /tmp/gh-aw/data/task-summaries.jsonl + >> /tmp/gh-aw/data/task-summaries.jsonl || true + else + echo "Agent tasks API request failed; proceeding with empty dataset" >&2 + fi + + # Convert JSONL to JSON array for downstream analysis steps + jq -s '.' /tmp/gh-aw/data/task-summaries.jsonl > /tmp/gh-aw/data/task-summaries.json - name: Precompute optimization datasets env: