mirror of
https://github.com/dotnet/skills.git
synced 2026-09-20 09:49:54 +08:00
11c5dfc738
* Require environment input to pat_pool shared workflow. - Updates the PAT pool shared workflow to latest version - Updates the validate-pat-pool workflow to match other repos - Updates all agentic workflows to use the updated PAT pool import with the standard secret names used across other repos - The new version of the import does not require the 'needs' workaround but the issue-triage workflow's 'roles: all' configuration requires a different workaround to ensure the pre_activation job exists for the pat_pool job to be able to depend on it (necessary for ordering). * Update markdown bullet style * Apply Copilot PR feedback Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Bump versions to match gh-aw --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1686 lines
100 KiB
YAML
Generated
1686 lines
100 KiB
YAML
Generated
# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"5354f6c550d77638a89c91435e043c1e0e56e1fd00c63cdfc743a03d78751113","body_hash":"9caea2d16810798c5cdf63dbeb5d3a5866e81a594bfcc608d362984b94d7620f","compiler_version":"v0.79.8","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
|
||
# gh-aw-manifest: {"version":1,"secrets":["COPILOT_PAT_0","COPILOT_PAT_1","COPILOT_PAT_2","COPILOT_PAT_3","COPILOT_PAT_4","COPILOT_PAT_5","COPILOT_PAT_6","COPILOT_PAT_7","COPILOT_PAT_8","COPILOT_PAT_9","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"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"},{"repo":"github/gh-aw-actions/setup","sha":"c0338fef4749d08c21f8f975fb0e37efa17dda47","version":"v0.79.8"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
|
||
# This file was automatically generated by gh-aw (v0.79.8). DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md
|
||
#
|
||
# ___ _ _
|
||
# / _ \ | | (_)
|
||
# | |_| | __ _ ___ _ __ | |_ _ ___
|
||
# | _ |/ _` |/ _ \ '_ \| __| |/ __|
|
||
# | | | | (_| | __/ | | | |_| | (__
|
||
# \_| |_/\__, |\___|_| |_|\__|_|\___|
|
||
# __/ |
|
||
# _ _ |___/
|
||
# | | | | / _| |
|
||
# | | | | ___ _ __ _ __| |_| | _____ ____
|
||
# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
|
||
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
|
||
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
|
||
#
|
||
#
|
||
# To update this file, edit the corresponding .md file and run:
|
||
# gh aw compile
|
||
# Not all edits will cause changes to this file.
|
||
#
|
||
# For more information: https://github.github.com/gh-aw/introduction/overview/
|
||
#
|
||
# Automatically warn about and close pull requests that have been open for more than 30 days with no recent activity.
|
||
#
|
||
# Resolved workflow manifest:
|
||
# Imports:
|
||
# - shared/pat_pool.md
|
||
#
|
||
# Secrets used:
|
||
# - COPILOT_PAT_0
|
||
# - COPILOT_PAT_1
|
||
# - COPILOT_PAT_2
|
||
# - COPILOT_PAT_3
|
||
# - COPILOT_PAT_4
|
||
# - COPILOT_PAT_5
|
||
# - COPILOT_PAT_6
|
||
# - COPILOT_PAT_7
|
||
# - COPILOT_PAT_8
|
||
# - COPILOT_PAT_9
|
||
# - GH_AW_GITHUB_MCP_SERVER_TOKEN
|
||
# - GH_AW_GITHUB_TOKEN
|
||
# - GITHUB_TOKEN
|
||
#
|
||
# Custom actions used:
|
||
# - actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||
# - actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
# - actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
|
||
# - actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||
# - actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
# - github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
#
|
||
# Container images used:
|
||
# - ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6
|
||
# - ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4
|
||
# - ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
|
||
# - ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa
|
||
# - ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
|
||
|
||
name: "Close Stale Pull Requests"
|
||
on:
|
||
# permissions: {} # Permissions applied to pre-activation job
|
||
schedule:
|
||
- cron: "6 22 * * 1"
|
||
# Friendly format: weekly on monday (scattered)
|
||
workflow_dispatch:
|
||
inputs:
|
||
aw_context:
|
||
default: ""
|
||
description: "Agent caller context (used internally by Agentic Workflows)."
|
||
required: false
|
||
type: string
|
||
|
||
permissions: {}
|
||
|
||
concurrency:
|
||
group: "gh-aw-${{ github.workflow }}"
|
||
|
||
run-name: "Close Stale Pull Requests"
|
||
|
||
jobs:
|
||
activation:
|
||
needs:
|
||
- pat_pool
|
||
- pre_activation
|
||
if: >
|
||
needs.pre_activation.outputs.activated == 'true' && ((!(github.event_name == 'schedule' && github.event.repository.fork)))
|
||
runs-on: ubuntu-slim
|
||
permissions:
|
||
actions: read
|
||
contents: read
|
||
env:
|
||
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
|
||
outputs:
|
||
comment_id: ""
|
||
comment_repo: ""
|
||
daily_ai_credits_exceeded: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_exceeded == 'true' }}
|
||
daily_ai_credits_threshold: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_threshold || '' }}
|
||
daily_ai_credits_total_effective_tokens: ${{ steps.daily-effective-workflow-guardrail.outputs.daily_ai_credits_total_effective_tokens || '' }}
|
||
engine_id: ${{ steps.generate_aw_info.outputs.engine_id }}
|
||
lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
|
||
model: ${{ steps.generate_aw_info.outputs.model }}
|
||
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
||
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
||
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
||
stale_lock_file_failed: ${{ steps.check-lock-file.outputs.stale_lock_file_failed == 'true' }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
trace-id: ${{ needs.pre_activation.outputs.setup-trace-id }}
|
||
parent-span-id: ${{ needs.pre_activation.outputs.setup-parent-span-id || needs.pre_activation.outputs.setup-span-id }}
|
||
safe-output-artifact-client: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Generate agentic run info
|
||
id: generate_aw_info
|
||
env:
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
|
||
GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AGENT_VERSION: "1.0.60"
|
||
GH_AW_INFO_CLI_VERSION: "v0.79.8"
|
||
GH_AW_INFO_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_INFO_EXPERIMENTAL: "false"
|
||
GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
|
||
GH_AW_INFO_STAGED: "false"
|
||
GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
|
||
GH_AW_INFO_FIREWALL_ENABLED: "true"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_AWMG_VERSION: ""
|
||
GH_AW_INFO_FIREWALL_TYPE: "squid"
|
||
GH_AW_COMPILED_STRICT: "true"
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
|
||
await main(core, context);
|
||
- name: Check daily workflow token guardrail
|
||
id: daily-effective-workflow-guardrail
|
||
if: ${{ env.GH_AW_MAX_DAILY_AI_CREDITS != '' }}
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_ID: "close-stale-prs.agent"
|
||
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
GH_AW_WORKFLOW_DISPATCH_AW_CONTEXT: ${{ github.event.inputs.aw_context || '' }}
|
||
GH_AW_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
GH_AW_MAX_DAILY_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_DAILY_AI_CREDITS || '5000' }}
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_daily_aic_workflow_guardrail.cjs');
|
||
await main();
|
||
- name: Checkout .github and .agents folders
|
||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||
with:
|
||
persist-credentials: false
|
||
sparse-checkout: |
|
||
.github
|
||
.agents
|
||
.antigravity
|
||
.claude
|
||
.codex
|
||
.crush
|
||
.gemini
|
||
.opencode
|
||
.pi
|
||
sparse-checkout-cone-mode: true
|
||
fetch-depth: 1
|
||
- name: Save agent config folders for base branch restoration
|
||
env:
|
||
GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
|
||
GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
|
||
# poutine:ignore untrusted_checkout_exec
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/save_base_github_folders.sh"
|
||
- name: Check workflow lock file
|
||
id: check-lock-file
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_WORKFLOW_FILE: "close-stale-prs.agent.lock.yml"
|
||
GH_AW_CONTEXT_WORKFLOW_REF: "${{ github.workflow_ref }}"
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
|
||
await main();
|
||
- name: Check compile-agentic version
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_COMPILED_VERSION: "v0.79.8"
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_version_updates.cjs');
|
||
await main();
|
||
- name: Create prompt with built-in context
|
||
env:
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
|
||
GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
|
||
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
|
||
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
|
||
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
|
||
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
|
||
# poutine:ignore untrusted_checkout_exec
|
||
run: |
|
||
bash "${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh"
|
||
{
|
||
cat << 'GH_AW_PROMPT_02dfccadcc72e13b_EOF'
|
||
<system>
|
||
GH_AW_PROMPT_02dfccadcc72e13b_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/safe_outputs_prompt.md"
|
||
cat << 'GH_AW_PROMPT_02dfccadcc72e13b_EOF'
|
||
<safe-output-tools>
|
||
Tools: add_comment(max:30), close_pull_request(max:25), missing_tool, missing_data, noop
|
||
</safe-output-tools>
|
||
GH_AW_PROMPT_02dfccadcc72e13b_EOF
|
||
cat "${RUNNER_TEMP}/gh-aw/prompts/mcp_cli_tools_prompt.md"
|
||
cat << 'GH_AW_PROMPT_02dfccadcc72e13b_EOF'
|
||
<github-context>
|
||
The following GitHub context information is available for this workflow:
|
||
{{#if github.actor}}
|
||
- **actor**: __GH_AW_GITHUB_ACTOR__
|
||
{{/if}}
|
||
{{#if github.repository}}
|
||
- **repository**: __GH_AW_GITHUB_REPOSITORY__
|
||
{{/if}}
|
||
{{#if github.workspace}}
|
||
- **workspace**: __GH_AW_GITHUB_WORKSPACE__
|
||
{{/if}}
|
||
{{#if github.event.issue.number || (github.aw.context.item_type == 'issue' && github.aw.context.item_number)}}
|
||
- **issue-number**: #__GH_AW_EXPR_802A9F6A__
|
||
{{/if}}
|
||
{{#if github.event.discussion.number || (github.aw.context.item_type == 'discussion' && github.aw.context.item_number)}}
|
||
- **discussion-number**: #__GH_AW_EXPR_1A3A194A__
|
||
{{/if}}
|
||
{{#if github.event.pull_request.number || (github.aw.context.item_type == 'pull_request' && github.aw.context.item_number)}}
|
||
- **pull-request-number**: #__GH_AW_EXPR_463A214A__
|
||
{{/if}}
|
||
{{#if github.event.comment.id || github.aw.context.comment_id}}
|
||
- **comment-id**: __GH_AW_EXPR_FF1D34CE__
|
||
{{/if}}
|
||
{{#if github.run_id}}
|
||
- **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
|
||
{{/if}}
|
||
</github-context>
|
||
|
||
GH_AW_PROMPT_02dfccadcc72e13b_EOF
|
||
cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
|
||
cat << 'GH_AW_PROMPT_02dfccadcc72e13b_EOF'
|
||
</system>
|
||
{{#runtime-import .github/workflows/close-stale-prs.agent.md}}
|
||
GH_AW_PROMPT_02dfccadcc72e13b_EOF
|
||
} > "$GH_AW_PROMPT"
|
||
- name: Interpolate variables and render templates
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
GH_AW_ENGINE_ID: "copilot"
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
|
||
await main();
|
||
- name: Substitute placeholders
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
GH_AW_EXPR_1A3A194A: ${{ github.event.discussion.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'discussion' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_463A214A: ${{ github.event.pull_request.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'pull_request' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_802A9F6A: ${{ github.event.issue.number || (fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_type == 'issue' && fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').item_number) }}
|
||
GH_AW_EXPR_FF1D34CE: ${{ github.event.comment.id || fromJSON(github.event.inputs.aw_context || github.event.client_payload.aw_context || '{}').comment_id }}
|
||
GH_AW_GITHUB_ACTOR: ${{ github.actor }}
|
||
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
|
||
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
|
||
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
|
||
GH_AW_MCP_CLI_SERVERS_LIST: '- `safeoutputs` — run `safeoutputs --help` to see available tools'
|
||
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
|
||
const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
|
||
|
||
// Call the substitution function
|
||
return await substitutePlaceholders({
|
||
file: process.env.GH_AW_PROMPT,
|
||
substitutions: {
|
||
GH_AW_EXPR_1A3A194A: process.env.GH_AW_EXPR_1A3A194A,
|
||
GH_AW_EXPR_463A214A: process.env.GH_AW_EXPR_463A214A,
|
||
GH_AW_EXPR_802A9F6A: process.env.GH_AW_EXPR_802A9F6A,
|
||
GH_AW_EXPR_FF1D34CE: process.env.GH_AW_EXPR_FF1D34CE,
|
||
GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
|
||
GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
|
||
GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
|
||
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
|
||
GH_AW_MCP_CLI_SERVERS_LIST: process.env.GH_AW_MCP_CLI_SERVERS_LIST,
|
||
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
|
||
}
|
||
});
|
||
- name: Validate prompt placeholders
|
||
env:
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
# poutine:ignore untrusted_checkout_exec
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh"
|
||
- name: Print prompt
|
||
env:
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
# poutine:ignore untrusted_checkout_exec
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh"
|
||
- name: Upload activation artifact
|
||
if: success()
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: activation
|
||
include-hidden-files: true
|
||
path: |
|
||
/tmp/gh-aw/aw_info.json
|
||
/tmp/gh-aw/models.json
|
||
/tmp/gh-aw/aw-prompts/prompt.txt
|
||
/tmp/gh-aw/aw-prompts/prompt-template.txt
|
||
/tmp/gh-aw/aw-prompts/prompt-import-tree.json
|
||
/tmp/gh-aw/github_rate_limits.jsonl
|
||
/tmp/gh-aw/base
|
||
/tmp/gh-aw/.github/agents
|
||
/tmp/gh-aw/.github/skills
|
||
if-no-files-found: ignore
|
||
retention-days: 1
|
||
|
||
agent:
|
||
needs:
|
||
- activation
|
||
- pat_pool
|
||
if: needs.activation.outputs.daily_ai_credits_exceeded != 'true'
|
||
runs-on: ubuntu-latest
|
||
environment: copilot-pat-pool
|
||
permissions:
|
||
contents: read
|
||
concurrency:
|
||
group: "gh-aw-copilot-${{ github.workflow }}"
|
||
queue: max
|
||
env:
|
||
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
||
GH_AW_ASSETS_ALLOWED_EXTS: ""
|
||
GH_AW_ASSETS_BRANCH: ""
|
||
GH_AW_ASSETS_MAX_SIZE_KB: 0
|
||
GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
|
||
GH_AW_WORKFLOW_ID_SANITIZED: closestaleprs.agent
|
||
outputs:
|
||
agentic_engine_timeout: ${{ steps.detect-agent-errors.outputs.agentic_engine_timeout || 'false' }}
|
||
ai_credits_rate_limit_error: ${{ steps.parse-mcp-gateway.outputs.ai_credits_rate_limit_error || 'false' }}
|
||
aic: ${{ steps.parse-mcp-gateway.outputs.aic }}
|
||
ambient_context: ${{ steps.parse-mcp-gateway.outputs.ambient_context }}
|
||
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
|
||
effective_tokens: ${{ steps.parse-mcp-gateway.outputs.effective_tokens }}
|
||
has_patch: ${{ steps.collect_output.outputs.has_patch }}
|
||
inference_access_error: ${{ steps.detect-agent-errors.outputs.inference_access_error || 'false' }}
|
||
mcp_policy_error: ${{ steps.detect-agent-errors.outputs.mcp_policy_error || 'false' }}
|
||
model: ${{ needs.activation.outputs.model }}
|
||
model_not_supported_error: ${{ steps.detect-agent-errors.outputs.model_not_supported_error || 'false' }}
|
||
output: ${{ steps.collect_output.outputs.output }}
|
||
output_types: ${{ steps.collect_output.outputs.output_types }}
|
||
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
||
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
||
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
||
unknown_model_ai_credits: ${{ steps.parse-mcp-gateway.outputs.unknown_model_ai_credits || 'false' }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
||
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Set runtime paths
|
||
id: set-runtime-paths
|
||
run: |
|
||
{
|
||
echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl"
|
||
echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json"
|
||
echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json"
|
||
} >> "$GITHUB_OUTPUT"
|
||
- name: Checkout repository
|
||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||
with:
|
||
persist-credentials: false
|
||
- name: Create gh-aw temp directory
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh"
|
||
- name: Configure gh CLI for GitHub Enterprise
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh"
|
||
env:
|
||
GH_TOKEN: ${{ github.token }}
|
||
- name: Configure Git credentials
|
||
env:
|
||
REPO_NAME: ${{ github.repository }}
|
||
SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_TOKEN: ${{ github.token }}
|
||
run: |
|
||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||
git config --global user.name "github-actions[bot]"
|
||
git config --global am.keepcr true
|
||
# Re-authenticate git with GitHub token
|
||
SERVER_URL_STRIPPED="${SERVER_URL#https://}"
|
||
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
|
||
echo "Git configured with standard GitHub Actions identity"
|
||
- name: Checkout PR branch
|
||
id: checkout-pr
|
||
if: |
|
||
github.event.pull_request || github.event.issue.pull_request || github.event_name == 'workflow_dispatch' && fromJSON(github.event.inputs.aw_context || '{}').item_type == 'pull_request'
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
|
||
await main();
|
||
- name: Install GitHub Copilot CLI
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
|
||
env:
|
||
GH_HOST: github.com
|
||
- name: Install AWF binary
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
|
||
- name: Determine automatic lockdown mode for GitHub MCP Server
|
||
id: determine-automatic-lockdown
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 (source v9)
|
||
env:
|
||
GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
|
||
GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
|
||
with:
|
||
script: |
|
||
const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
|
||
await determineAutomaticLockdown(github, context, core);
|
||
- name: Download activation artifact
|
||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||
with:
|
||
name: activation
|
||
path: /tmp/gh-aw
|
||
- name: Restore agent config folders from base branch
|
||
if: steps.checkout-pr.outcome == 'success'
|
||
env:
|
||
GH_AW_AGENT_FOLDERS: ".agents .antigravity .claude .codex .crush .gemini .github .opencode .pi"
|
||
GH_AW_AGENT_FILES: ".crush.json AGENTS.md ANTIGRAVITY.md CLAUDE.md GEMINI.md PI.md opencode.jsonc"
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_base_github_folders.sh"
|
||
- name: Restore inline sub-agents from activation artifact
|
||
env:
|
||
GH_AW_SUB_AGENT_DIR: ".github/agents"
|
||
GH_AW_SUB_AGENT_EXT: ".agent.md"
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_sub_agents.sh"
|
||
- name: Restore inline skills from activation artifact
|
||
env:
|
||
GH_AW_SKILL_DIR: ".github/skills"
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/restore_inline_skills.sh"
|
||
- name: Download container images
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591 ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c
|
||
- name: Generate Safe Outputs Config
|
||
run: |
|
||
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_eff4c6d472aa87e4_EOF'
|
||
{"add_comment":{"max":30},"close_pull_request":{"max":25},"create_report_incomplete_issue":{},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"false"},"report_incomplete":{}}
|
||
GH_AW_SAFE_OUTPUTS_CONFIG_eff4c6d472aa87e4_EOF
|
||
- name: Generate Safe Outputs Tools
|
||
env:
|
||
GH_AW_TOOLS_META_JSON: |
|
||
{
|
||
"description_suffixes": {
|
||
"add_comment": " CONSTRAINTS: Maximum 30 comment(s) can be added. Supports reply_to_id for discussion threading.",
|
||
"close_pull_request": " CONSTRAINTS: Maximum 25 pull request(s) can be closed."
|
||
},
|
||
"repo_params": {},
|
||
"dynamic_tools": []
|
||
}
|
||
GH_AW_VALIDATION_JSON: |
|
||
{
|
||
"add_comment": {
|
||
"defaultMax": 1,
|
||
"fields": {
|
||
"body": {
|
||
"required": true,
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 65000
|
||
},
|
||
"item_number": {
|
||
"issueOrPRNumber": true
|
||
},
|
||
"reply_to_id": {
|
||
"type": "string",
|
||
"maxLength": 256
|
||
},
|
||
"repo": {
|
||
"type": "string",
|
||
"maxLength": 256
|
||
}
|
||
}
|
||
},
|
||
"close_pull_request": {
|
||
"defaultMax": 1,
|
||
"fields": {
|
||
"body": {
|
||
"required": true,
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 65000
|
||
},
|
||
"pull_request_number": {
|
||
"optionalPositiveInteger": true
|
||
},
|
||
"repo": {
|
||
"type": "string",
|
||
"maxLength": 256
|
||
}
|
||
}
|
||
},
|
||
"missing_data": {
|
||
"defaultMax": 20,
|
||
"fields": {
|
||
"alternatives": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 256
|
||
},
|
||
"context": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 256
|
||
},
|
||
"data_type": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 128
|
||
},
|
||
"reason": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 256
|
||
}
|
||
}
|
||
},
|
||
"missing_tool": {
|
||
"defaultMax": 20,
|
||
"fields": {
|
||
"alternatives": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 512
|
||
},
|
||
"reason": {
|
||
"required": true,
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 256
|
||
},
|
||
"tool": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 128
|
||
}
|
||
}
|
||
},
|
||
"noop": {
|
||
"defaultMax": 1,
|
||
"fields": {
|
||
"message": {
|
||
"required": true,
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 65000
|
||
}
|
||
}
|
||
},
|
||
"report_incomplete": {
|
||
"defaultMax": 5,
|
||
"fields": {
|
||
"details": {
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 65000
|
||
},
|
||
"reason": {
|
||
"required": true,
|
||
"type": "string",
|
||
"sanitize": true,
|
||
"maxLength": 1024
|
||
}
|
||
}
|
||
}
|
||
}
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_safe_outputs_tools.cjs');
|
||
await main();
|
||
- name: Generate Safe Outputs MCP Server Config
|
||
id: safe-outputs-config
|
||
run: |
|
||
# Generate a secure random API key (360 bits of entropy, 40+ chars)
|
||
# Mask immediately to prevent timing vulnerabilities
|
||
API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
|
||
echo "::add-mask::${API_KEY}"
|
||
|
||
PORT=3001
|
||
|
||
# Set outputs for next steps
|
||
{
|
||
echo "safe_outputs_api_key=${API_KEY}"
|
||
echo "safe_outputs_port=${PORT}"
|
||
} >> "$GITHUB_OUTPUT"
|
||
|
||
echo "Safe Outputs MCP server will run on port ${PORT}"
|
||
|
||
- name: Start Safe Outputs MCP HTTP Server
|
||
id: safe-outputs-start
|
||
env:
|
||
DEBUG: '*'
|
||
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
||
GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
|
||
GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
|
||
GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
|
||
GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
|
||
GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
|
||
run: |
|
||
# Environment variables are set above to prevent template injection
|
||
export DEBUG
|
||
export GH_AW_SAFE_OUTPUTS
|
||
export GH_AW_SAFE_OUTPUTS_PORT
|
||
export GH_AW_SAFE_OUTPUTS_API_KEY
|
||
export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
|
||
export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
|
||
export GH_AW_MCP_LOG_DIR
|
||
|
||
bash "${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh"
|
||
|
||
- name: Start MCP Gateway
|
||
id: start-mcp-gateway
|
||
env:
|
||
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.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 }}
|
||
GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
|
||
GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
|
||
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
run: |
|
||
set -eo pipefail
|
||
mkdir -p "${RUNNER_TEMP}/gh-aw/mcp-config"
|
||
|
||
# Export gateway environment variables for MCP config and gateway script
|
||
export MCP_GATEWAY_PORT="8080"
|
||
export MCP_GATEWAY_DOMAIN="host.docker.internal"
|
||
export MCP_GATEWAY_HOST_DOMAIN="localhost"
|
||
MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
|
||
echo "::add-mask::${MCP_GATEWAY_API_KEY}"
|
||
export MCP_GATEWAY_API_KEY
|
||
export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
|
||
mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
|
||
export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
|
||
export DEBUG="*"
|
||
|
||
export GH_AW_ENGINE="copilot"
|
||
MCP_GATEWAY_UID=$(id -u 2>/dev/null || echo '0')
|
||
MCP_GATEWAY_GID=$(id -g 2>/dev/null || echo '0')
|
||
case "${DOCKER_HOST:-}" in
|
||
unix://* ) DOCKER_SOCK_PATH="${DOCKER_HOST#unix://}" ;;
|
||
/* ) DOCKER_SOCK_PATH="$DOCKER_HOST" ;;
|
||
* ) DOCKER_SOCK_PATH=/var/run/docker.sock ;;
|
||
esac
|
||
DOCKER_SOCK_GID=$(stat -c '%g' "$DOCKER_SOCK_PATH" 2>/dev/null || echo '0')
|
||
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host --add-host host.docker.internal:127.0.0.1 --user '"${MCP_GATEWAY_UID}"':'"${MCP_GATEWAY_GID}"' --group-add '"${DOCKER_SOCK_GID}"' -v '"${DOCKER_SOCK_PATH}"':/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 DOCKER_HOST=unix:///var/run/docker.sock -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_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.3.25'
|
||
|
||
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_c6fee03c27b97257_EOF | "$GH_AW_NODE" "${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.cjs"
|
||
{
|
||
"mcpServers": {
|
||
"github": {
|
||
"type": "stdio",
|
||
"container": "ghcr.io/github/github-mcp-server:v1.1.2",
|
||
"env": {
|
||
"GITHUB_HOST": "\${GITHUB_SERVER_URL}",
|
||
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
|
||
"GITHUB_READ_ONLY": "1",
|
||
"GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
|
||
},
|
||
"guard-policies": {
|
||
"allow-only": {
|
||
"min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
|
||
"repos": "$GITHUB_MCP_GUARD_REPOS"
|
||
}
|
||
}
|
||
},
|
||
"safeoutputs": {
|
||
"type": "http",
|
||
"url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
|
||
"headers": {
|
||
"Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
|
||
},
|
||
"guard-policies": {
|
||
"write-sink": {
|
||
"accept": [
|
||
"*"
|
||
]
|
||
}
|
||
}
|
||
}
|
||
},
|
||
"gateway": {
|
||
"port": $MCP_GATEWAY_PORT,
|
||
"domain": "${MCP_GATEWAY_DOMAIN}",
|
||
"apiKey": "${MCP_GATEWAY_API_KEY}",
|
||
"payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
|
||
}
|
||
}
|
||
GH_AW_MCP_CONFIG_c6fee03c27b97257_EOF
|
||
- name: Mount MCP servers as CLIs
|
||
id: mount-mcp-clis
|
||
continue-on-error: true
|
||
env:
|
||
MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
|
||
MCP_GATEWAY_DOMAIN: ${{ steps.start-mcp-gateway.outputs.gateway-domain }}
|
||
MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/mount_mcp_as_cli.cjs');
|
||
await main();
|
||
- name: Clean credentials
|
||
continue-on-error: true
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh"
|
||
- name: Audit pre-agent workspace
|
||
id: pre_agent_audit
|
||
continue-on-error: true
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/audit_pre_agent_workspace.sh"
|
||
- name: Execute GitHub Copilot CLI
|
||
id: agentic_execution
|
||
# Copilot CLI tool arguments (sorted):
|
||
timeout-minutes: 20
|
||
run: |
|
||
set -o pipefail
|
||
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
|
||
trap 'rm -f "$HOME/.copilot/settings.json"' EXIT
|
||
mkdir -p "$HOME/.copilot"
|
||
printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json"
|
||
export XDG_CONFIG_HOME="$HOME"
|
||
export GH_AW_MCP_CONFIG="$HOME/.copilot/mcp-config.json"
|
||
touch /tmp/gh-aw/agent-step-summary.md
|
||
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
|
||
export GH_AW_NODE_BIN
|
||
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
|
||
(umask 177 && touch /tmp/gh-aw/agent-stdio.log)
|
||
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}"
|
||
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"api.snapcraft.io\",\"archive.ubuntu.com\",\"azure.archive.ubuntu.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.com\",\"host.docker.internal\",\"json-schema.org\",\"json.schemastore.org\",\"keyserver.ubuntu.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\",\"ppa.launchpad.net\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"s.symcb.com\",\"s.symcd.com\",\"security.ubuntu.com\",\"telemetry.enterprise.githubcopilot.com\",\"ts-crl.ws.symantec.com\",\"ts-ocsp.ws.symantec.com\",\"www.googleapis.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"vision\":[\"copilot/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
|
||
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
|
||
export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
|
||
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
|
||
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
|
||
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
|
||
fi
|
||
GH_AW_TOOL_CACHE_MOUNT=""
|
||
GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
|
||
if [ -d "$GH_AW_TOOL_CACHE" ]; then
|
||
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
|
||
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
|
||
fi
|
||
elif [ -d "/home/runner/work/_tool" ]; then
|
||
GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
|
||
fi
|
||
# shellcheck disable=SC1003
|
||
sudo -E 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_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
|
||
-- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/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/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --allow-all-paths --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
|
||
env:
|
||
AWF_REFLECT_ENABLED: 1
|
||
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
|
||
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
|
||
COPILOT_GITHUB_TOKEN: |
|
||
${{ case(
|
||
needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
|
||
needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
|
||
needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
|
||
needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
|
||
needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
|
||
needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
|
||
needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
|
||
needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
|
||
needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
|
||
needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
|
||
'NO COPILOT PAT AVAILABLE')
|
||
}}
|
||
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
|
||
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
|
||
GH_AW_PHASE: agent
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
||
GH_AW_TIMEOUT_MINUTES: 20
|
||
GH_AW_VERSION: v0.79.8
|
||
GITHUB_API_URL: ${{ github.api_url }}
|
||
GITHUB_AW: true
|
||
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
|
||
GITHUB_HEAD_REF: ${{ github.head_ref }}
|
||
GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
|
||
GITHUB_WORKSPACE: ${{ github.workspace }}
|
||
GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
|
||
GIT_AUTHOR_NAME: github-actions[bot]
|
||
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
|
||
GIT_COMMITTER_NAME: github-actions[bot]
|
||
RUNNER_TEMP: ${{ runner.temp }}
|
||
- name: Detect agent errors
|
||
if: always()
|
||
id: detect-agent-errors
|
||
continue-on-error: true
|
||
run: node "${RUNNER_TEMP}/gh-aw/actions/detect_agent_errors.cjs"
|
||
- name: Configure Git credentials
|
||
env:
|
||
REPO_NAME: ${{ github.repository }}
|
||
SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_TOKEN: ${{ github.token }}
|
||
run: |
|
||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||
git config --global user.name "github-actions[bot]"
|
||
git config --global am.keepcr true
|
||
# Re-authenticate git with GitHub token
|
||
SERVER_URL_STRIPPED="${SERVER_URL#https://}"
|
||
git remote set-url origin "https://x-access-token:${GITHUB_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
|
||
echo "Git configured with standard GitHub Actions identity"
|
||
- name: Copy Copilot session state files to logs
|
||
if: always()
|
||
continue-on-error: true
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/copy_copilot_session_state.sh"
|
||
- name: Stop MCP Gateway
|
||
if: always()
|
||
continue-on-error: true
|
||
env:
|
||
MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
|
||
MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
|
||
GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
|
||
run: |
|
||
bash "${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh" "$GATEWAY_PID"
|
||
- name: Redact secrets in logs
|
||
if: always()
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
|
||
await main();
|
||
env:
|
||
GH_AW_SECRET_NAMES: 'COPILOT_PAT_0,COPILOT_PAT_1,COPILOT_PAT_2,COPILOT_PAT_3,COPILOT_PAT_4,COPILOT_PAT_5,COPILOT_PAT_6,COPILOT_PAT_7,COPILOT_PAT_8,COPILOT_PAT_9,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
|
||
SECRET_COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
|
||
SECRET_COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
|
||
SECRET_COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
|
||
SECRET_COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
|
||
SECRET_COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
|
||
SECRET_COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
|
||
SECRET_COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
|
||
SECRET_COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
|
||
SECRET_COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
|
||
SECRET_COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
|
||
SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
|
||
SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
|
||
SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
- name: Append agent step summary
|
||
if: always()
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh"
|
||
- name: Copy Safe Outputs
|
||
if: always()
|
||
env:
|
||
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
||
run: |
|
||
mkdir -p /tmp/gh-aw
|
||
cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
|
||
- name: Ingest agent output
|
||
id: collect_output
|
||
if: always()
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
|
||
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.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.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.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,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
|
||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_API_URL: ${{ github.api_url }}
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
|
||
await main();
|
||
- name: Parse agent logs for step summary
|
||
if: always()
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
|
||
await main();
|
||
- name: Parse MCP Gateway logs for step summary
|
||
if: always()
|
||
id: parse-mcp-gateway
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
|
||
await main();
|
||
- name: Print firewall logs
|
||
if: always()
|
||
continue-on-error: true
|
||
env:
|
||
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
|
||
run: |
|
||
# Fix permissions on firewall logs/audit dirs so they can be uploaded as artifacts
|
||
# AWF runs with sudo, creating files owned by root
|
||
sudo chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
|
||
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
|
||
if command -v awf &> /dev/null; then
|
||
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
|
||
else
|
||
echo 'AWF binary not installed, skipping firewall log summary'
|
||
fi
|
||
- name: Parse token usage for step summary
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
|
||
await main();
|
||
- name: Print AWF reflect summary
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/awf_reflect_summary.cjs');
|
||
await main();
|
||
- name: Write agent output placeholder if missing
|
||
if: always()
|
||
run: |
|
||
if [ ! -f /tmp/gh-aw/agent_output.json ]; then
|
||
echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
|
||
fi
|
||
- name: Upload agent artifacts
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: agent
|
||
path: |
|
||
/tmp/gh-aw/aw-prompts/prompt.txt
|
||
/tmp/gh-aw/sandbox/agent/logs/
|
||
/tmp/gh-aw/redacted-urls.log
|
||
/tmp/gh-aw/mcp-logs/
|
||
/tmp/gh-aw/agent_usage.json
|
||
/tmp/gh-aw/agent-stdio.log
|
||
/tmp/gh-aw/pre-agent-audit.txt
|
||
/tmp/gh-aw/agent/
|
||
/tmp/gh-aw/github_rate_limits.jsonl
|
||
/tmp/gh-aw/safeoutputs.jsonl
|
||
/tmp/gh-aw/agent_output.json
|
||
/tmp/gh-aw/aw-*.patch
|
||
/tmp/gh-aw/aw-*.bundle
|
||
/tmp/gh-aw/awf-config.json
|
||
/tmp/gh-aw/sandbox/firewall/logs/
|
||
/tmp/gh-aw/sandbox/firewall/audit/
|
||
/tmp/gh-aw/sandbox/firewall/awf-reflect.json
|
||
if-no-files-found: ignore
|
||
|
||
conclusion:
|
||
needs:
|
||
- activation
|
||
- agent
|
||
- detection
|
||
- pat_pool
|
||
- safe_outputs
|
||
if: >
|
||
always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' ||
|
||
needs.activation.outputs.stale_lock_file_failed == 'true' || needs.activation.outputs.daily_ai_credits_exceeded == 'true')
|
||
runs-on: ubuntu-slim
|
||
environment: copilot-pat-pool
|
||
permissions:
|
||
contents: read
|
||
discussions: write
|
||
issues: write
|
||
pull-requests: write
|
||
concurrency:
|
||
group: "gh-aw-conclusion-close-stale-prs.agent"
|
||
cancel-in-progress: false
|
||
queue: max
|
||
outputs:
|
||
incomplete_count: ${{ steps.report_incomplete.outputs.incomplete_count }}
|
||
noop_message: ${{ steps.noop.outputs.noop_message }}
|
||
tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
|
||
total_count: ${{ steps.missing_tool.outputs.total_count }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
||
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Download agent output artifact
|
||
id: download-agent-output
|
||
continue-on-error: true
|
||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||
with:
|
||
name: agent
|
||
path: /tmp/gh-aw/
|
||
- name: Setup agent output environment variable
|
||
id: setup-agent-output-env
|
||
if: steps.download-agent-output.outcome == 'success'
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/
|
||
find "/tmp/gh-aw/" -type f -print
|
||
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
||
- name: Collect usage artifact files
|
||
if: always()
|
||
continue-on-error: true
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/usage/agent /tmp/gh-aw/usage/detection
|
||
echo "Usage artifact source file status:"
|
||
for file in /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl; do
|
||
[ -f "$file" ] && echo "FOUND: $file" || echo "MISSING: $file"
|
||
done
|
||
[ -f /tmp/gh-aw/aw-info.jsonl ] && cp /tmp/gh-aw/aw-info.jsonl /tmp/gh-aw/usage/aw-info.jsonl || true
|
||
[ -f /tmp/gh-aw/agent_usage.jsonl ] && cp /tmp/gh-aw/agent_usage.jsonl /tmp/gh-aw/usage/agent_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/detection_usage.jsonl ] && cp /tmp/gh-aw/detection_usage.jsonl /tmp/gh-aw/usage/detection_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/agent/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall-audit-logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/logs/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl ] && cp /tmp/gh-aw/threat-detection/sandbox/firewall/audit/api-proxy-logs/token-usage.jsonl /tmp/gh-aw/usage/detection/token_usage.jsonl || true
|
||
[ -f /tmp/gh-aw/usage/agent/token_usage.jsonl ] || : > /tmp/gh-aw/usage/agent/token_usage.jsonl
|
||
[ -f /tmp/gh-aw/usage/detection/token_usage.jsonl ] || : > /tmp/gh-aw/usage/detection/token_usage.jsonl
|
||
find /tmp/gh-aw/usage -type f -print | sort
|
||
- name: Upload usage artifact
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: usage
|
||
path: |
|
||
/tmp/gh-aw/usage/aw-info.jsonl
|
||
/tmp/gh-aw/usage/agent_usage.jsonl
|
||
/tmp/gh-aw/usage/detection_usage.jsonl
|
||
/tmp/gh-aw/usage/agent/token_usage.jsonl
|
||
/tmp/gh-aw/usage/detection/token_usage.jsonl
|
||
if-no-files-found: ignore
|
||
- name: Process no-op messages
|
||
id: noop
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_NOOP_MAX: "1"
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
|
||
GH_AW_NOOP_REPORT_AS_ISSUE: "false"
|
||
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
|
||
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
|
||
GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
|
||
GH_AW_WORKFLOW_ID: "close-stale-prs.agent"
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
|
||
await main();
|
||
- name: Log detection run
|
||
id: detection_runs
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
|
||
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_detection_runs.cjs');
|
||
await main();
|
||
- name: Record missing tool
|
||
id: missing_tool
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_MISSING_TOOL_CREATE_ISSUE: "true"
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
|
||
await main();
|
||
- name: Record incomplete
|
||
id: report_incomplete
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_REPORT_INCOMPLETE_CREATE_ISSUE: "true"
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/report_incomplete_handler.cjs');
|
||
await main();
|
||
- name: Handle agent failure
|
||
id: handle_agent_failure
|
||
if: always()
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||
GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
|
||
GH_AW_WORKFLOW_ID: "close-stale-prs.agent"
|
||
GH_AW_ACTION_FAILURE_ISSUE_EXPIRES_HOURS: "168"
|
||
GH_AW_ENGINE_ID: "copilot"
|
||
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
|
||
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens || '' }}
|
||
GH_AW_AI_CREDITS_RATE_LIMIT_ERROR: ${{ needs.agent.outputs.ai_credits_rate_limit_error || 'false' }}
|
||
GH_AW_UNKNOWN_MODEL_AI_CREDITS: ${{ needs.agent.outputs.unknown_model_ai_credits || 'false' }}
|
||
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
|
||
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
|
||
GH_AW_MAX_AI_CREDITS: ${{ vars.GH_AW_DEFAULT_MAX_AI_CREDITS || '1000' }}
|
||
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
|
||
GH_AW_MCP_POLICY_ERROR: ${{ needs.agent.outputs.mcp_policy_error }}
|
||
GH_AW_AGENTIC_ENGINE_TIMEOUT: ${{ needs.agent.outputs.agentic_engine_timeout }}
|
||
GH_AW_MODEL_NOT_SUPPORTED_ERROR: ${{ needs.agent.outputs.model_not_supported_error }}
|
||
GH_AW_ENGINE_API_HOSTS: "api.enterprise.githubcopilot.com,api.githubcopilot.com,api.business.githubcopilot.com,api.individual.githubcopilot.com"
|
||
GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
|
||
GH_AW_STALE_LOCK_FILE_FAILED: ${{ needs.activation.outputs.stale_lock_file_failed }}
|
||
GH_AW_DAILY_AI_CREDITS_EXCEEDED: ${{ needs.activation.outputs.daily_ai_credits_exceeded }}
|
||
GH_AW_DAILY_AI_CREDITS_TOTAL_EFFECTIVE_TOKENS: ${{ needs.activation.outputs.daily_ai_credits_total_effective_tokens }}
|
||
GH_AW_DAILY_AI_CREDITS_THRESHOLD: ${{ needs.activation.outputs.daily_ai_credits_threshold }}
|
||
GH_AW_GROUP_REPORTS: "false"
|
||
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
|
||
GH_AW_MISSING_TOOL_REPORT_AS_FAILURE: "true"
|
||
GH_AW_MISSING_DATA_REPORT_AS_FAILURE: "true"
|
||
GH_AW_TIMEOUT_MINUTES: "20"
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
|
||
await main();
|
||
|
||
detection:
|
||
needs:
|
||
- activation
|
||
- agent
|
||
if: >
|
||
always() && needs.agent.result != 'skipped' && (needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true')
|
||
runs-on: ubuntu-latest
|
||
environment: copilot-pat-pool
|
||
permissions:
|
||
contents: read
|
||
outputs:
|
||
aic: ${{ steps.parse_detection_token_usage.outputs.aic }}
|
||
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
|
||
detection_reason: ${{ steps.detection_conclusion.outputs.reason }}
|
||
detection_success: ${{ steps.detection_conclusion.outputs.success }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
||
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Download agent output artifact
|
||
id: download-agent-output
|
||
continue-on-error: true
|
||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||
with:
|
||
name: agent
|
||
path: /tmp/gh-aw/
|
||
- name: Setup agent output environment variable
|
||
id: setup-agent-output-env
|
||
if: steps.download-agent-output.outcome == 'success'
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/
|
||
find "/tmp/gh-aw/" -type f -print
|
||
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
||
- name: Checkout repository for patch context
|
||
if: needs.agent.outputs.has_patch == 'true'
|
||
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||
with:
|
||
persist-credentials: false
|
||
# --- Threat Detection ---
|
||
- name: Clean stale firewall files from agent artifact
|
||
run: |
|
||
rm -rf /tmp/gh-aw/sandbox/firewall/logs
|
||
rm -rf /tmp/gh-aw/sandbox/firewall/audit
|
||
- name: Download container images
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh" ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6 ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4 ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591
|
||
- name: Check if detection needed
|
||
id: detection_guard
|
||
if: always()
|
||
env:
|
||
OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
|
||
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
|
||
run: |
|
||
if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
|
||
echo "run_detection=true" >> "$GITHUB_OUTPUT"
|
||
echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
|
||
else
|
||
echo "run_detection=false" >> "$GITHUB_OUTPUT"
|
||
echo "Detection skipped: no agent outputs or patches to analyze"
|
||
fi
|
||
- name: Clear MCP Config for detection
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
run: |
|
||
rm -f "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json"
|
||
rm -f "$HOME/.copilot/mcp-config.json"
|
||
rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
|
||
- name: Prepare threat detection files
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
|
||
rm -f /tmp/gh-aw/agent_usage.json
|
||
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
|
||
if [ ! -s /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt ]; then
|
||
echo "::warning::ERR_VALIDATION: Missing or empty detection context prompt at /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt. Ensure the agent artifact includes /tmp/gh-aw/aw-prompts/prompt.txt. Detection will continue with fallback workflow context."
|
||
fi
|
||
cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
|
||
for f in /tmp/gh-aw/aw-*.patch; do
|
||
[ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
||
done
|
||
for f in /tmp/gh-aw/aw-*.bundle; do
|
||
[ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
||
done
|
||
echo "Prepared threat detection files:"
|
||
ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
|
||
- name: Setup threat detection
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
WORKFLOW_DESCRIPTION: "Automatically warn about and close pull requests that have been open for more than 30 days with no recent activity."
|
||
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
|
||
await main();
|
||
- name: Ensure threat-detection directory and log
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/threat-detection
|
||
touch /tmp/gh-aw/threat-detection/detection.log
|
||
- name: Setup Node.js
|
||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||
with:
|
||
node-version: '24'
|
||
package-manager-cache: false
|
||
- name: Install GitHub Copilot CLI
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh" 1.0.60
|
||
env:
|
||
GH_HOST: github.com
|
||
- name: Install AWF binary
|
||
run: bash "${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh" v0.27.2
|
||
- name: Execute GitHub Copilot CLI
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
continue-on-error: true
|
||
id: detection_agentic_execution
|
||
# Copilot CLI tool arguments (sorted):
|
||
timeout-minutes: 20
|
||
run: |
|
||
set -o pipefail
|
||
printf '%s' "$(date +%s%3N)" > /tmp/gh-aw/agent_cli_start_ms.txt
|
||
trap 'rm -f "$HOME/.copilot/settings.json"' EXIT
|
||
mkdir -p "$HOME/.copilot"
|
||
printf '%s' '{"builtInAgents":{"rubberDuck":false}}' > "$HOME/.copilot/settings.json"
|
||
export XDG_CONFIG_HOME="$HOME"
|
||
touch /tmp/gh-aw/agent-step-summary.md
|
||
GH_AW_NODE_BIN=$(command -v node 2>/dev/null || true)
|
||
export GH_AW_NODE_BIN
|
||
export COPILOT_API_KEY="$COPILOT_DUMMY_BYOK"
|
||
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
|
||
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
|
||
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.2/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS}},\"container\":{\"imageTag\":\"0.27.2,squid=sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591,agent=sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6,api-proxy=sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4,cli-proxy=sha256:02f3ec08f32dc26c5427920c6a2e2f3036238fce44802f2f11ef49ed8621b5d0\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
|
||
cp "${RUNNER_TEMP}/gh-aw/awf-config.json" /tmp/gh-aw/awf-config.json
|
||
export GH_AW_MODELS_JSON_PATH="/tmp/gh-aw/models.json"
|
||
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS=""
|
||
if [[ "${DOCKER_HOST:-}" =~ ^tcp:// ]]; then
|
||
GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS="--docker-host-path-prefix /tmp/gh-aw"
|
||
fi
|
||
GH_AW_TOOL_CACHE_MOUNT=""
|
||
GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"
|
||
if [ -d "$GH_AW_TOOL_CACHE" ]; then
|
||
if [[ "$GH_AW_TOOL_CACHE" != /opt/* ]]; then
|
||
GH_AW_TOOL_CACHE_MOUNT="$GH_AW_TOOL_CACHE:$GH_AW_TOOL_CACHE:ro"
|
||
fi
|
||
elif [ -d "/home/runner/work/_tool" ]; then
|
||
GH_AW_TOOL_CACHE_MOUNT="/home/runner/work/_tool:/home/runner/work/_tool:ro"
|
||
fi
|
||
# shellcheck disable=SC1003
|
||
sudo -E 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_PATH_PREFIX_ARGS} --env-all --exclude-env COPILOT_GITHUB_TOKEN --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --audit-dir /tmp/gh-aw/sandbox/firewall/audit --enable-host-access --allow-host-ports 80,443,8080 --skip-pull \
|
||
-- /bin/bash -c 'set +o histexpand; GH_AW_TOOL_CACHE="${RUNNER_TOOL_CACHE:-/opt/hostedtoolcache}"; export PATH="$(find "$GH_AW_TOOL_CACHE" /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/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/copilot_harness.cjs /usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --no-ask-user --allow-all-tools --add-dir "${GITHUB_WORKSPACE}" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
|
||
env:
|
||
AWF_REFLECT_ENABLED: 1
|
||
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
|
||
COPILOT_DUMMY_BYOK: dummy-byok-key-for-offline-mode
|
||
COPILOT_GITHUB_TOKEN: |
|
||
${{ case(
|
||
needs.pat_pool.outputs.pat_number == '0', secrets.COPILOT_PAT_0,
|
||
needs.pat_pool.outputs.pat_number == '1', secrets.COPILOT_PAT_1,
|
||
needs.pat_pool.outputs.pat_number == '2', secrets.COPILOT_PAT_2,
|
||
needs.pat_pool.outputs.pat_number == '3', secrets.COPILOT_PAT_3,
|
||
needs.pat_pool.outputs.pat_number == '4', secrets.COPILOT_PAT_4,
|
||
needs.pat_pool.outputs.pat_number == '5', secrets.COPILOT_PAT_5,
|
||
needs.pat_pool.outputs.pat_number == '6', secrets.COPILOT_PAT_6,
|
||
needs.pat_pool.outputs.pat_number == '7', secrets.COPILOT_PAT_7,
|
||
needs.pat_pool.outputs.pat_number == '8', secrets.COPILOT_PAT_8,
|
||
needs.pat_pool.outputs.pat_number == '9', secrets.COPILOT_PAT_9,
|
||
'NO COPILOT PAT AVAILABLE')
|
||
}}
|
||
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || vars.GH_AW_DEFAULT_MODEL_COPILOT || 'claude-sonnet-4.6' }}
|
||
GH_AW_MAX_TURNS: ${{ vars.GH_AW_DEFAULT_MAX_TURNS || '' }}
|
||
GH_AW_PHASE: detection
|
||
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
|
||
GH_AW_TIMEOUT_MINUTES: 20
|
||
GH_AW_VERSION: v0.79.8
|
||
GITHUB_API_URL: ${{ github.api_url }}
|
||
GITHUB_AW: true
|
||
GITHUB_COPILOT_INTEGRATION_ID: agentic-workflows
|
||
GITHUB_HEAD_REF: ${{ github.head_ref }}
|
||
GITHUB_REF_NAME: ${{ github.ref_name }}
|
||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
|
||
GITHUB_WORKSPACE: ${{ github.workspace }}
|
||
GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
|
||
GIT_AUTHOR_NAME: github-actions[bot]
|
||
GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
|
||
GIT_COMMITTER_NAME: github-actions[bot]
|
||
RUNNER_TEMP: ${{ runner.temp }}
|
||
- name: Parse threat detection token usage for step summary
|
||
id: parse_detection_token_usage
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_TOKEN_USAGE_SUMMARY_TITLE: Threat Detection Token Usage
|
||
with:
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_token_usage.cjs');
|
||
await main();
|
||
- name: Upload threat detection log
|
||
if: always() && steps.detection_guard.outputs.run_detection == 'true'
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: detection
|
||
path: /tmp/gh-aw/threat-detection/detection.log
|
||
if-no-files-found: ignore
|
||
- name: Parse and conclude threat detection
|
||
id: detection_conclusion
|
||
if: always()
|
||
continue-on-error: true
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
|
||
DETECTION_AGENTIC_EXECUTION_OUTCOME: ${{ steps.detection_agentic_execution.outcome }}
|
||
GH_AW_DETECTION_CONTINUE_ON_ERROR: "true"
|
||
with:
|
||
script: |
|
||
try {
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
|
||
await main();
|
||
} catch (loadErr) {
|
||
const continueOnError = process.env.GH_AW_DETECTION_CONTINUE_ON_ERROR !== 'false';
|
||
const detectionExecutionFailed = process.env.DETECTION_AGENTIC_EXECUTION_OUTCOME === 'failure';
|
||
const msg = 'ERR_SYSTEM: \u274C Unexpected error loading threat detection module: ' + (loadErr && loadErr.message ? loadErr.message : String(loadErr));
|
||
core.error(msg);
|
||
core.setOutput('reason', 'parse_error');
|
||
if (continueOnError && !detectionExecutionFailed) {
|
||
core.warning('\u26A0\uFE0F ' + msg);
|
||
core.setOutput('conclusion', 'warning');
|
||
core.setOutput('success', 'false');
|
||
} else {
|
||
core.setOutput('conclusion', 'failure');
|
||
core.setOutput('success', 'false');
|
||
core.setFailed(msg);
|
||
}
|
||
}
|
||
|
||
pat_pool:
|
||
needs: pre_activation
|
||
runs-on: ubuntu-slim
|
||
environment: copilot-pat-pool
|
||
outputs:
|
||
pat_number: ${{ steps.select-pat-number.outputs.copilot_pat_number }}
|
||
steps:
|
||
- name: Configure GH_HOST for enterprise compatibility
|
||
id: ghes-host-config
|
||
shell: bash
|
||
# zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
|
||
run: |
|
||
# 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: Select Copilot token from pool
|
||
id: select-pat-number
|
||
run: |
|
||
# Collect pool entries with non-empty secrets from COPILOT_PAT_0..COPILOT_PAT_9.
|
||
PAT_NUMBERS=()
|
||
POOL_INDICATORS=(➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖ ➖)
|
||
|
||
for i in $(seq 0 9); do
|
||
var="COPILOT_PAT_${i}"
|
||
val="${!var}"
|
||
if [ -n "$val" ]; then
|
||
PAT_NUMBERS+=(${i})
|
||
POOL_INDICATORS[${i}]="🟪"
|
||
fi
|
||
done
|
||
|
||
# If none of the entries in the pool have values, emit a warning
|
||
# and do not set an output value. The consumer can fall back to
|
||
# using COPILOT_GITHUB_TOKEN.
|
||
if [ ${#PAT_NUMBERS[@]} -eq 0 ]; then
|
||
warning_message="::warning::None of the PAT pool entries had values "
|
||
warning_message+="(checked COPILOT_PAT_0 through COPILOT_PAT_9)"
|
||
echo "$warning_message"
|
||
exit 0
|
||
fi
|
||
|
||
# Select a random index using the seed if specified
|
||
if [ -n "$RANDOM_SEED" ]; then
|
||
RANDOM=$RANDOM_SEED
|
||
fi
|
||
|
||
PAT_INDEX=$(( RANDOM % ${#PAT_NUMBERS[@]} ))
|
||
PAT_NUMBER="${PAT_NUMBERS[$PAT_INDEX]}"
|
||
POOL_INDICATORS[${PAT_NUMBER}]="✅"
|
||
|
||
echo "Pool size: ${#PAT_NUMBERS[@]}"
|
||
echo "Selected PAT number ${PAT_NUMBER} (index: ${PAT_INDEX})"
|
||
|
||
# Emit a markdown table of the pool entries to the step summary
|
||
echo "|0|1|2|3|4|5|6|7|8|9|" >> "$GITHUB_STEP_SUMMARY"
|
||
echo "|-|-|-|-|-|-|-|-|-|-|" >> "$GITHUB_STEP_SUMMARY"
|
||
(IFS='|'; printf '|%s' "${POOL_INDICATORS[@]}"; printf '|\n') >> "$GITHUB_STEP_SUMMARY"
|
||
|
||
# Set the PAT number as the output
|
||
echo "copilot_pat_number=${PAT_NUMBER}" >> "$GITHUB_OUTPUT"
|
||
env:
|
||
COPILOT_PAT_0: ${{ secrets.COPILOT_PAT_0 }}
|
||
COPILOT_PAT_1: ${{ secrets.COPILOT_PAT_1 }}
|
||
COPILOT_PAT_2: ${{ secrets.COPILOT_PAT_2 }}
|
||
COPILOT_PAT_3: ${{ secrets.COPILOT_PAT_3 }}
|
||
COPILOT_PAT_4: ${{ secrets.COPILOT_PAT_4 }}
|
||
COPILOT_PAT_5: ${{ secrets.COPILOT_PAT_5 }}
|
||
COPILOT_PAT_6: ${{ secrets.COPILOT_PAT_6 }}
|
||
COPILOT_PAT_7: ${{ secrets.COPILOT_PAT_7 }}
|
||
COPILOT_PAT_8: ${{ secrets.COPILOT_PAT_8 }}
|
||
COPILOT_PAT_9: ${{ secrets.COPILOT_PAT_9 }}
|
||
RANDOM_SEED: ${{ github.aw.import-inputs.random_seed }}
|
||
shell: bash
|
||
|
||
pre_activation:
|
||
if: (!(github.event_name == 'schedule' && github.event.repository.fork))
|
||
runs-on: ubuntu-slim
|
||
environment: copilot-pat-pool
|
||
outputs:
|
||
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
|
||
matched_command: ''
|
||
setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }}
|
||
setup-span-id: ${{ steps.setup.outputs.span-id }}
|
||
setup-trace-id: ${{ steps.setup.outputs.trace-id }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Check team membership for workflow
|
||
id: check_membership
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_REQUIRED_ROLES: "admin,maintainer,write"
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
|
||
await main();
|
||
|
||
safe_outputs:
|
||
needs:
|
||
- activation
|
||
- agent
|
||
- detection
|
||
if: (!cancelled()) && needs.agent.result != 'skipped' && needs.detection.result == 'success'
|
||
runs-on: ubuntu-slim
|
||
environment: copilot-pat-pool
|
||
permissions:
|
||
contents: read
|
||
discussions: write
|
||
issues: write
|
||
pull-requests: write
|
||
timeout-minutes: 45
|
||
env:
|
||
GH_AW_AGENT_AIC: ${{ needs.agent.outputs.aic }}
|
||
GH_AW_AIC: ${{ needs.agent.outputs.aic }}
|
||
GH_AW_AMBIENT_CONTEXT: ${{ needs.agent.outputs.ambient_context }}
|
||
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/close-stale-prs.agent"
|
||
GH_AW_DETECTION_CONCLUSION: ${{ needs.detection.outputs.detection_conclusion }}
|
||
GH_AW_DETECTION_REASON: ${{ needs.detection.outputs.detection_reason }}
|
||
GH_AW_EFFECTIVE_TOKENS: ${{ needs.agent.outputs.effective_tokens }}
|
||
GH_AW_ENGINE_ID: "copilot"
|
||
GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
|
||
GH_AW_ENGINE_VERSION: "1.0.60"
|
||
GH_AW_THREAT_DETECTION_AIC: ${{ needs.detection.outputs.aic }}
|
||
GH_AW_WORKFLOW_ID: "close-stale-prs.agent"
|
||
GH_AW_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_WORKFLOW_SOURCE_URL: "${{ github.server_url }}/${{ github.repository }}/blob/${{ github.ref_name }}/.github/workflows/close-stale-prs.agent.md"
|
||
outputs:
|
||
code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
|
||
code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
|
||
comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
|
||
comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
|
||
create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
|
||
create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
|
||
process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
|
||
process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
|
||
steps:
|
||
- name: Setup Scripts
|
||
id: setup
|
||
uses: github/gh-aw-actions/setup@c0338fef4749d08c21f8f975fb0e37efa17dda47 # v0.79.8
|
||
with:
|
||
destination: ${{ runner.temp }}/gh-aw/actions
|
||
job-name: ${{ github.job }}
|
||
trace-id: ${{ needs.activation.outputs.setup-trace-id }}
|
||
parent-span-id: ${{ needs.activation.outputs.setup-parent-span-id || needs.activation.outputs.setup-span-id }}
|
||
env:
|
||
GH_AW_SETUP_WORKFLOW_NAME: "Close Stale Pull Requests"
|
||
GH_AW_CURRENT_WORKFLOW_REF: ${{ github.repository }}/.github/workflows/close-stale-prs.agent.lock.yml@${{ github.ref }}
|
||
GH_AW_INFO_VERSION: "1.0.60"
|
||
GH_AW_INFO_AWF_VERSION: "v0.27.2"
|
||
GH_AW_INFO_ENGINE_ID: "copilot"
|
||
- name: Download agent output artifact
|
||
id: download-agent-output
|
||
continue-on-error: true
|
||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||
with:
|
||
name: agent
|
||
path: /tmp/gh-aw/
|
||
- name: Setup agent output environment variable
|
||
id: setup-agent-output-env
|
||
if: steps.download-agent-output.outcome == 'success'
|
||
run: |
|
||
mkdir -p /tmp/gh-aw/
|
||
find "/tmp/gh-aw/" -type f -print
|
||
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
|
||
- name: Configure GH_HOST for enterprise compatibility
|
||
id: ghes-host-config
|
||
shell: bash
|
||
# zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input.
|
||
run: |
|
||
# 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: Process Safe Outputs
|
||
id: process_safe_outputs
|
||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||
env:
|
||
GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
|
||
GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
|
||
GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.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.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.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,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
|
||
GITHUB_SERVER_URL: ${{ github.server_url }}
|
||
GITHUB_API_URL: ${{ github.api_url }}
|
||
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":30},\"close_pull_request\":{\"max\":25},\"create_report_incomplete_issue\":{},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"false\"},\"report_incomplete\":{}}"
|
||
with:
|
||
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
|
||
setupGlobals(core, github, context, exec, io, getOctokit);
|
||
const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
|
||
await main();
|
||
- name: Upload Safe Outputs Items
|
||
if: always()
|
||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||
with:
|
||
name: safe-outputs-items
|
||
path: |
|
||
/tmp/gh-aw/safe-output-items.jsonl
|
||
/tmp/gh-aw/temporary-id-map.json
|
||
if-no-files-found: ignore
|
||
|