Updating our agentic workflows (#996)

This commit is contained in:
Aaron Powell
2026-03-13 12:25:46 +11:00
committed by GitHub
parent 1970e7b584
commit 3025370a15
9 changed files with 1604 additions and 969 deletions

View File

@@ -13,7 +13,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by gh-aw (v0.45.7). DO NOT EDIT.
# This file was automatically generated by gh-aw (v0.57.2). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -23,7 +23,7 @@
#
# Updates the CODEOWNERS file when a maintainer comments #codeowner on a pull request
#
# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"8f7ecfe9d458039fea20a1e09fd094839da1ae52fd4e5006effac2a27da3bd50"}
# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"8f7ecfe9d458039fea20a1e09fd094839da1ae52fd4e5006effac2a27da3bd50","compiler_version":"v0.57.2","strict":true}
name: "Codeowner Update Agent"
"on":
@@ -34,7 +34,7 @@ name: "Codeowner Update Agent"
permissions: {}
concurrency:
group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number }}"
group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}"
run-name: "Codeowner Update Agent"
@@ -51,21 +51,53 @@ jobs:
body: ${{ steps.sanitized.outputs.body }}
comment_id: ""
comment_repo: ""
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
text: ${{ steps.sanitized.outputs.text }}
title: ${{ steps.sanitized.outputs.title }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- 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 || '' }}
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "latest"
GH_AW_INFO_CLI_VERSION: "v0.57.2"
GH_AW_INFO_WORKFLOW_NAME: "Codeowner Update Agent"
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.23.0"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { main } = require('/opt/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
.github
.agents
sparse-checkout-cone-mode: true
fetch-depth: 1
persist-credentials: false
- name: Check workflow file timestamps
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -101,41 +133,21 @@ jobs:
GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
run: |
bash /opt/gh-aw/actions/create_prompt_first.sh
cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT"
{
cat << 'GH_AW_PROMPT_EOF'
<system>
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
<safe-outputs>
<description>GitHub API Access Instructions</description>
<important>
The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations.
</important>
<instructions>
To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls.
Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body).
**IMPORTANT - temporary_id format rules:**
- If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed)
- If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i
- Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive)
- Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
- INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore)
- VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678
- To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate
Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i.
Discover available tools from the safeoutputs MCP server.
**Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped.
**Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed.
</instructions>
</safe-outputs>
cat "/opt/gh-aw/prompts/xpia.md"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md"
cat "/opt/gh-aw/prompts/markdown.md"
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
<safe-output-tools>
Tools: add_comment, create_pull_request, missing_tool, missing_data, noop
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/safe_outputs_create_pull_request.md"
cat << 'GH_AW_PROMPT_EOF'
</safe-output-tools>
<github-context>
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -166,14 +178,15 @@ jobs:
GH_AW_PROMPT_EOF
if [ "$GITHUB_EVENT_NAME" = "issue_comment" ] && [ -n "$GH_AW_IS_PR_COMMENT" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review_comment" ] || [ "$GITHUB_EVENT_NAME" = "pull_request_review" ]; then
cat "/opt/gh-aw/prompts/pr_context_prompt.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/pr_context_prompt.md"
fi
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
</system>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/codeowner-update.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -202,7 +215,6 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: ${{ needs.pre_activation.outputs.matched_command }}
GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
with:
script: |
@@ -225,7 +237,6 @@ jobs:
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
GH_AW_IS_PR_COMMENT: process.env.GH_AW_IS_PR_COMMENT,
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND,
GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: process.env.GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT
}
});
@@ -237,12 +248,14 @@ jobs:
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
run: bash /opt/gh-aw/actions/print_prompt_summary.sh
- name: Upload prompt artifact
- name: Upload activation artifact
if: success()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: prompt
path: /tmp/gh-aw/aw-prompts/prompt.txt
name: activation
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
retention-days: 1
agent:
@@ -264,14 +277,16 @@ jobs:
GH_AW_WORKFLOW_ID_SANITIZED: codeownerupdate
outputs:
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
detection_success: ${{ steps.detection_conclusion.outputs.success }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
model: ${{ steps.generate_aw_info.outputs.model }}
inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
model: ${{ needs.activation.outputs.model }}
output: ${{ steps.collect_output.outputs.output }}
output_types: ${{ steps.collect_output.outputs.output_types }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Checkout repository
@@ -287,6 +302,7 @@ jobs:
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"
@@ -294,7 +310,7 @@ jobs:
- name: Checkout PR branch
id: checkout-pr
if: |
github.event.pull_request
(github.event.pull_request) || (github.event.issue.pull_request)
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -305,59 +321,10 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Generate agentic run info
id: generate_aw_info
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const fs = require('fs');
const awInfo = {
engine_id: "copilot",
engine_name: "GitHub Copilot CLI",
model: process.env.GH_AW_MODEL_AGENT_COPILOT || "",
version: "",
agent_version: "0.0.410",
cli_version: "v0.45.7",
workflow_name: "Codeowner Update Agent",
experimental: false,
supports_tools_allowlist: true,
run_id: context.runId,
run_number: context.runNumber,
run_attempt: process.env.GITHUB_RUN_ATTEMPT,
repository: context.repo.owner + '/' + context.repo.repo,
ref: context.ref,
sha: context.sha,
actor: context.actor,
event_name: context.eventName,
staged: false,
allowed_domains: ["defaults"],
firewall_enabled: true,
awf_version: "v0.20.0",
awmg_version: "v0.1.4",
steps: {
firewall: "squid"
},
created_at: new Date().toISOString()
};
// Write to /tmp/gh-aw directory to avoid inclusion in PR
const tmpPath = '/tmp/gh-aw/aw_info.json';
fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2));
console.log('Generated aw_info.json at:', tmpPath);
console.log(JSON.stringify(awInfo, null, 2));
// Set model as output for reuse in other steps/jobs
core.setOutput('model', awInfo.model);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
run: /opt/gh-aw/actions/install_copilot_cli.sh latest
- name: Install awf binary
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.20.0
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.23.0
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -369,19 +336,19 @@ jobs:
const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
- name: Download container images
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.0 ghcr.io/github/gh-aw-firewall/squid:0.20.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.23.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.23.0 ghcr.io/github/gh-aw-firewall/squid:0.23.0 ghcr.io/github/gh-aw-mcpg:v0.1.8 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- name: Write Safe Outputs Config
run: |
mkdir -p /opt/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
{"add_comment":{"max":1},"create_pull_request":{},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
{"add_comment":{"max":1},"create_pull_request":{"base_branch":"staged","max":1,"title_prefix":"[codeowner] "},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF'
[
{
"description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. CONSTRAINTS: Maximum 1 comment(s) can be added.",
"description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. NOTE: By default, this tool requires discussions:write permission. If your GitHub App lacks Discussions permission, set 'discussions: false' in the workflow's safe-outputs.add-comment configuration to exclude this permission. CONSTRAINTS: Maximum 1 comment(s) can be added.",
"inputSchema": {
"additionalProperties": false,
"properties": {
@@ -389,9 +356,25 @@ jobs:
"description": "The comment text in Markdown format. This is the 'body' field - do not use 'comment_body' or other variations. Provide helpful, relevant information that adds value to the conversation. CONSTRAINTS: The complete comment (your body text + automatically added footer) must not exceed 65536 characters total. Maximum 10 mentions (@username), maximum 50 links (http/https URLs). A footer (~200-500 characters) is automatically appended with workflow attribution, so leave adequate space. If these limits are exceeded, the tool call will fail with a detailed error message indicating which constraint was violated.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"item_number": {
"description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). If omitted, the tool will attempt to resolve the target from the current workflow context (triggering issue, PR, or discussion).",
"type": "number"
"description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). Can also be a temporary_id (e.g., 'aw_abc123') from a previously created issue in the same workflow run. If omitted, the tool auto-targets the issue, PR, or discussion that triggered this workflow. Auto-targeting only works for issue, pull_request, discussion, and comment event triggers — it does NOT work for schedule, workflow_dispatch, push, or workflow_run triggers. For those trigger types, always provide item_number explicitly, or the tool call will fail with an error.",
"type": [
"number",
"string"
]
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"temporary_id": {
"description": "Unique temporary identifier for this comment. Format: 'aw_' followed by 3 to 12 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Auto-generated if not provided. The temporary ID is returned in the tool response so you can reference this comment later.",
"pattern": "^aw_[A-Za-z0-9]{3,12}$",
"type": "string"
}
},
"required": [
@@ -414,6 +397,14 @@ jobs:
"description": "Source branch name containing the changes. If omitted, uses the current working branch.",
"type": "string"
},
"draft": {
"description": "Whether to create the PR as a draft. Draft PRs cannot be merged until marked as ready for review. Use mark_pull_request_as_ready_for_review to convert a draft PR. Default: true.",
"type": "boolean"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"labels": {
"description": "Labels to categorize the PR (e.g., 'enhancement', 'bugfix'). Labels must exist in the repository.",
"items": {
@@ -421,6 +412,14 @@ jobs:
},
"type": "array"
},
"repo": {
"description": "Target repository in 'owner/repo' format. For multi-repo workflows where the target repo differs from the workflow repo, this must match a repo in the allowed-repos list or the configured target-repo. If omitted, defaults to the configured target-repo (from safe-outputs config), NOT the workflow repository. In most cases, you should omit this parameter and let the system use the configured default.",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"title": {
"description": "Concise PR title describing the changes. Follow repository conventions (e.g., conventional commits). The title appears as the main heading.",
"type": "string"
@@ -443,10 +442,18 @@ jobs:
"description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"tool": {
"description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.",
"type": "string"
@@ -464,9 +471,17 @@ jobs:
"inputSchema": {
"additionalProperties": false,
"properties": {
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"message": {
"description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [
@@ -493,9 +508,17 @@ jobs:
"description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this data is needed to complete the task (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [],
@@ -518,6 +541,10 @@ jobs:
},
"item_number": {
"issueOrPRNumber": true
},
"repo": {
"type": "string",
"maxLength": 256
}
}
},
@@ -536,12 +563,19 @@ jobs:
"sanitize": true,
"maxLength": 256
},
"draft": {
"type": "boolean"
},
"labels": {
"type": "array",
"itemType": "string",
"itemSanitize": true,
"itemMaxLength": 128
},
"repo": {
"type": "string",
"maxLength": 256
},
"title": {
"required": true,
"type": "string",
@@ -550,6 +584,31 @@ jobs:
}
}
},
"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": {
@@ -642,10 +701,11 @@ jobs:
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"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.4'
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.8'
mkdir -p /home/runner/.copilot
cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh
@@ -653,7 +713,7 @@ jobs:
"mcpServers": {
"github": {
"type": "stdio",
"container": "ghcr.io/github/github-mcp-server:v0.30.3",
"container": "ghcr.io/github/github-mcp-server:v0.32.0",
"env": {
"GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -677,17 +737,11 @@ jobs:
}
}
GH_AW_MCP_CONFIG_EOF
- name: Generate workflow overview
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- name: Download activation artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
script: |
const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs');
await generateWorkflowOverview(core);
- name: Download prompt artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: prompt
path: /tmp/gh-aw/aw-prompts
name: activation
path: /tmp/gh-aw
- name: Clean git credentials
run: bash /opt/gh-aw/actions/clean_git_credentials.sh
- name: Execute GitHub Copilot CLI
@@ -696,20 +750,37 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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 --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
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]
XDG_CONFIG_HOME: /home/runner
- name: Detect inference access error
id: detect-inference-error
if: always()
continue-on-error: true
run: bash /opt/gh-aw/actions/detect_inference_access_error.sh
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }}
@@ -717,6 +788,7 @@ jobs:
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"
@@ -762,9 +834,12 @@ jobs:
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 /opt/gh-aw/actions/append_agent_step_summary.sh
- name: Upload Safe Outputs
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output
path: ${{ env.GH_AW_SAFE_OUTPUTS }}
@@ -786,13 +861,13 @@ jobs:
await main();
- name: Upload sanitized agent output
if: always() && env.GH_AW_AGENT_OUTPUT
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-output
path: ${{ env.GH_AW_AGENT_OUTPUT }}
if-no-files-found: warn
- name: Upload engine output files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent_outputs
path: |
@@ -837,24 +912,146 @@ jobs:
- name: Upload agent artifacts
if: always()
continue-on-error: true
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-artifacts
path: |
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/agent-stdio.log
/tmp/gh-aw/agent/
/tmp/gh-aw/aw.patch
/tmp/gh-aw/aw-*.patch
if-no-files-found: ignore
# --- Threat Detection (inline) ---
- name: Check if detection needed
id: detection_guard
if: always()
env:
OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
HAS_PATCH: ${{ steps.collect_output.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 configuration for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
rm -f /home/runner/.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
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
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
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@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Codeowner Update Agent"
WORKFLOW_DESCRIPTION: "Updates the CODEOWNERS file when a maintainer comments #codeowner on a pull request"
HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/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: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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]
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_detection_results
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
- name: Set detection conclusion
id: detection_conclusion
if: always()
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
run: |
if [[ "$RUN_DETECTION" != "true" ]]; then
echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection was not needed, marking as skipped"
elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
echo "conclusion=success" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection passed successfully"
else
echo "conclusion=failure" >> "$GITHUB_OUTPUT"
echo "success=false" >> "$GITHUB_OUTPUT"
echo "Detection found issues"
fi
conclusion:
needs:
- activation
- agent
- detection
- safe_outputs
if: (always()) && (needs.agent.result != 'skipped')
runs-on: ubuntu-slim
@@ -863,22 +1060,27 @@ jobs:
discussions: write
issues: write
pull-requests: write
concurrency:
group: "gh-aw-conclusion-codeowner-update"
cancel-in-progress: false
outputs:
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -888,7 +1090,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: 1
GH_AW_NOOP_MAX: "1"
GH_AW_WORKFLOW_NAME: "Codeowner Update Agent"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -919,8 +1121,14 @@ jobs:
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: "codeowner-update"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }}
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -960,113 +1168,15 @@ jobs:
const { main } = require('/opt/gh-aw/actions/handle_create_pr_error.cjs');
await main();
detection:
needs: agent
if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true'
runs-on: ubuntu-latest
permissions: {}
timeout-minutes: 10
outputs:
success: ${{ steps.parse_results.outputs.success }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
with:
destination: /opt/gh-aw/actions
- name: Download agent artifacts
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-artifacts
path: /tmp/gh-aw/threat-detection/
- name: Download agent output artifact
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-output
path: /tmp/gh-aw/threat-detection/
- name: Echo agent output types
env:
AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
run: |
echo "Agent output-types: $AGENT_OUTPUT_TYPES"
- name: Setup threat detection
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Codeowner Update Agent"
WORKFLOW_DESCRIPTION: "Updates the CODEOWNERS file when a maintainer comments #codeowner on a pull request"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs');
await main();
- name: Ensure threat-detection directory and log
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"
mkdir -p /tmp/
mkdir -p /tmp/gh-aw/
mkdir -p /tmp/gh-aw/agent/
mkdir -p /tmp/gh-aw/sandbox/agent/logs/
copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
GITHUB_WORKSPACE: ${{ github.workspace }}
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_results
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
pre_activation:
if: ${{ contains(github.event.comment.body, '#codeowner') && github.event.issue.pull_request }}
runs-on: ubuntu-slim
outputs:
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
matched_command: ''
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Check team membership for workflow
@@ -1086,8 +1196,7 @@ jobs:
needs:
- activation
- agent
- detection
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true')
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
runs-on: ubuntu-slim
permissions:
contents: write
@@ -1096,33 +1205,43 @@ jobs:
pull-requests: write
timeout-minutes: 15
env:
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/codeowner-update"
GH_AW_ENGINE_ID: "copilot"
GH_AW_WORKFLOW_ID: "codeowner-update"
GH_AW_WORKFLOW_NAME: "Codeowner Update Agent"
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 }}
created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
safe-output-custom-tokens: 'true'
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/safeoutputs/agent_output.json" >> "$GITHUB_ENV"
- name: Download patch artifact
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-artifacts
path: /tmp/gh-aw/
@@ -1130,6 +1249,7 @@ jobs:
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (contains(needs.agent.outputs.output_types, 'create_pull_request'))
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: staged
token: ${{ secrets.GH_AW_CODEOWNER_PR_TOKEN }}
persist-credentials: false
fetch-depth: 1
@@ -1142,6 +1262,7 @@ jobs:
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:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
@@ -1151,7 +1272,12 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"base_branch\":\"staged\",\"draft\":false,\"max\":1,\"max_patch_size\":1024,\"title_prefix\":\"[codeowner] \"},\"missing_data\":{},\"missing_tool\":{}}"
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"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1},\"create_pull_request\":{\"base_branch\":\"staged\",\"draft\":false,\"github-token\":\"${{ secrets.GH_AW_CODEOWNER_PR_TOKEN }}\",\"max\":1,\"max_patch_size\":1024,\"protected_files\":[\"package.json\",\"bun.lockb\",\"bunfig.toml\",\"deno.json\",\"deno.jsonc\",\"deno.lock\",\"global.json\",\"NuGet.Config\",\"Directory.Packages.props\",\"mix.exs\",\"mix.lock\",\"go.mod\",\"go.sum\",\"stack.yaml\",\"stack.yaml.lock\",\"pom.xml\",\"build.gradle\",\"build.gradle.kts\",\"settings.gradle\",\"settings.gradle.kts\",\"gradle.properties\",\"package-lock.json\",\"yarn.lock\",\"pnpm-lock.yaml\",\"npm-shrinkwrap.json\",\"requirements.txt\",\"Pipfile\",\"Pipfile.lock\",\"pyproject.toml\",\"setup.py\",\"setup.cfg\",\"Gemfile\",\"Gemfile.lock\",\"uv.lock\",\"AGENTS.md\"],\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[codeowner] \"},\"missing_data\":{},\"missing_tool\":{}}"
GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GH_AW_CODEOWNER_PR_TOKEN }}
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1159,4 +1285,11 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs');
await main();
- name: Upload safe output items manifest
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output-items
path: /tmp/safe-output-items.jsonl
if-no-files-found: warn

View File

@@ -0,0 +1,26 @@
name: "Copilot Setup Steps"
# This workflow configures the environment for GitHub Copilot Agent with gh-aw MCP server
on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml
jobs:
# The job MUST be called 'copilot-setup-steps' to be recognized by GitHub Copilot Agent
copilot-setup-steps:
runs-on: ubuntu-latest
# Set minimal permissions for setup steps
# Copilot Agent receives its own token with appropriate permissions
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Install gh-aw extension
uses: github/gh-aw/actions/setup-cli@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
version: v0.57.2

View File

@@ -13,7 +13,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by gh-aw (v0.45.7). DO NOT EDIT.
# This file was automatically generated by gh-aw (v0.57.2). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -23,7 +23,7 @@
#
# Weekly scan of agents, instructions, and skills to identify potential duplicate resources and report them for review
#
# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"ff58c3ff9cf9181e74e682ba6117a448bb9a2a9e52c012dc53d86d7697f3b565"}
# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"ff58c3ff9cf9181e74e682ba6117a448bb9a2a9e52c012dc53d86d7697f3b565","compiler_version":"v0.57.2","strict":true}
name: "Duplicate Resource Detector"
"on":
@@ -47,19 +47,51 @@ jobs:
outputs:
comment_id: ""
comment_repo: ""
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- 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 || '' }}
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "latest"
GH_AW_INFO_CLI_VERSION: "v0.57.2"
GH_AW_INFO_WORKFLOW_NAME: "Duplicate Resource Detector"
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.23.0"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { main } = require('/opt/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
.github
.agents
sparse-checkout-cone-mode: true
fetch-depth: 1
persist-credentials: false
- name: Check workflow file timestamps
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -84,41 +116,18 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
run: |
bash /opt/gh-aw/actions/create_prompt_first.sh
cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT"
{
cat << 'GH_AW_PROMPT_EOF'
<system>
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
<safe-outputs>
<description>GitHub API Access Instructions</description>
<important>
The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations.
</important>
<instructions>
To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls.
Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body).
**IMPORTANT - temporary_id format rules:**
- If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed)
- If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i
- Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive)
- Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
- INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore)
- VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678
- To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate
Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i.
Discover available tools from the safeoutputs MCP server.
**Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped.
**Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed.
</instructions>
</safe-outputs>
cat "/opt/gh-aw/prompts/xpia.md"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md"
cat "/opt/gh-aw/prompts/markdown.md"
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
<safe-output-tools>
Tools: create_issue, missing_tool, missing_data, noop
</safe-output-tools>
<github-context>
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -148,12 +157,13 @@ jobs:
</github-context>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
</system>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/duplicate-resource-detector.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -176,8 +186,6 @@ jobs:
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: ${{ needs.pre_activation.outputs.matched_command }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
@@ -196,9 +204,7 @@ jobs:
GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
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_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
}
});
- name: Validate prompt placeholders
@@ -209,12 +215,14 @@ jobs:
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
run: bash /opt/gh-aw/actions/print_prompt_summary.sh
- name: Upload prompt artifact
- name: Upload activation artifact
if: success()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: prompt
path: /tmp/gh-aw/aw-prompts/prompt.txt
name: activation
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
retention-days: 1
agent:
@@ -237,14 +245,16 @@ jobs:
GH_AW_WORKFLOW_ID_SANITIZED: duplicateresourcedetector
outputs:
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
detection_success: ${{ steps.detection_conclusion.outputs.success }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
model: ${{ steps.generate_aw_info.outputs.model }}
inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
model: ${{ needs.activation.outputs.model }}
output: ${{ steps.collect_output.outputs.output }}
output_types: ${{ steps.collect_output.outputs.output_types }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Checkout repository
@@ -260,6 +270,7 @@ jobs:
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"
@@ -267,7 +278,7 @@ jobs:
- name: Checkout PR branch
id: checkout-pr
if: |
github.event.pull_request
(github.event.pull_request) || (github.event.issue.pull_request)
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -278,59 +289,10 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Generate agentic run info
id: generate_aw_info
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const fs = require('fs');
const awInfo = {
engine_id: "copilot",
engine_name: "GitHub Copilot CLI",
model: process.env.GH_AW_MODEL_AGENT_COPILOT || "",
version: "",
agent_version: "0.0.410",
cli_version: "v0.45.7",
workflow_name: "Duplicate Resource Detector",
experimental: false,
supports_tools_allowlist: true,
run_id: context.runId,
run_number: context.runNumber,
run_attempt: process.env.GITHUB_RUN_ATTEMPT,
repository: context.repo.owner + '/' + context.repo.repo,
ref: context.ref,
sha: context.sha,
actor: context.actor,
event_name: context.eventName,
staged: false,
allowed_domains: ["defaults"],
firewall_enabled: true,
awf_version: "v0.20.0",
awmg_version: "v0.1.4",
steps: {
firewall: "squid"
},
created_at: new Date().toISOString()
};
// Write to /tmp/gh-aw directory to avoid inclusion in PR
const tmpPath = '/tmp/gh-aw/aw_info.json';
fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2));
console.log('Generated aw_info.json at:', tmpPath);
console.log(JSON.stringify(awInfo, null, 2));
// Set model as output for reuse in other steps/jobs
core.setOutput('model', awInfo.model);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
run: /opt/gh-aw/actions/install_copilot_cli.sh latest
- name: Install awf binary
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.20.0
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.23.0
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -342,7 +304,7 @@ jobs:
const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
- name: Download container images
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.0 ghcr.io/github/gh-aw-firewall/squid:0.20.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.23.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.23.0 ghcr.io/github/gh-aw-firewall/squid:0.23.0 ghcr.io/github/gh-aw-mcpg:v0.1.8 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- name: Write Safe Outputs Config
run: |
mkdir -p /opt/gh-aw/safeoutputs
@@ -354,7 +316,7 @@ jobs:
cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF'
[
{
"description": "Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for actionable work items that need assignment, labeling, and status tracking. For reports, announcements, or status updates that don't require task tracking, use create_discussion instead. CONSTRAINTS: Maximum 1 issue(s) can be created. Labels [duplicate-review] will be automatically added.",
"description": "Create a new GitHub issue for tracking bugs, feature requests, or tasks. Use this for actionable work items that need assignment, labeling, and status tracking. For reports, announcements, or status updates that don't require task tracking, use create_discussion instead. CONSTRAINTS: Maximum 1 issue(s) can be created. Labels [\"duplicate-review\"] will be automatically added.",
"inputSchema": {
"additionalProperties": false,
"properties": {
@@ -362,6 +324,10 @@ jobs:
"description": "Detailed issue description in Markdown. Do NOT repeat the title as a heading since it already appears as the issue's h1. Include context, reproduction steps, or acceptance criteria as appropriate.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"labels": {
"description": "Labels to categorize the issue (e.g., 'bug', 'enhancement'). Labels must exist in the repository.",
"items": {
@@ -376,9 +342,13 @@ jobs:
"string"
]
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"temporary_id": {
"description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.",
"pattern": "^aw_[A-Za-z0-9]{3,8}$",
"description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 12 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.",
"pattern": "^aw_[A-Za-z0-9]{3,12}$",
"type": "string"
},
"title": {
@@ -403,10 +373,18 @@ jobs:
"description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"tool": {
"description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.",
"type": "string"
@@ -424,9 +402,17 @@ jobs:
"inputSchema": {
"additionalProperties": false,
"properties": {
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"message": {
"description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [
@@ -453,9 +439,17 @@ jobs:
"description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this data is needed to complete the task (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [],
@@ -500,6 +494,31 @@ jobs:
}
}
},
"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": {
@@ -592,10 +611,11 @@ jobs:
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"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.4'
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.8'
mkdir -p /home/runner/.copilot
cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh
@@ -603,7 +623,7 @@ jobs:
"mcpServers": {
"github": {
"type": "stdio",
"container": "ghcr.io/github/github-mcp-server:v0.30.3",
"container": "ghcr.io/github/github-mcp-server:v0.32.0",
"env": {
"GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -627,17 +647,11 @@ jobs:
}
}
GH_AW_MCP_CONFIG_EOF
- name: Generate workflow overview
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- name: Download activation artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
script: |
const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs');
await generateWorkflowOverview(core);
- name: Download prompt artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: prompt
path: /tmp/gh-aw/aw-prompts
name: activation
path: /tmp/gh-aw
- name: Clean git credentials
run: bash /opt/gh-aw/actions/clean_git_credentials.sh
- name: Execute GitHub Copilot CLI
@@ -646,20 +660,37 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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 --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
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]
XDG_CONFIG_HOME: /home/runner
- name: Detect inference access error
id: detect-inference-error
if: always()
continue-on-error: true
run: bash /opt/gh-aw/actions/detect_inference_access_error.sh
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }}
@@ -667,6 +698,7 @@ jobs:
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"
@@ -712,9 +744,12 @@ jobs:
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 /opt/gh-aw/actions/append_agent_step_summary.sh
- name: Upload Safe Outputs
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output
path: ${{ env.GH_AW_SAFE_OUTPUTS }}
@@ -736,13 +771,13 @@ jobs:
await main();
- name: Upload sanitized agent output
if: always() && env.GH_AW_AGENT_OUTPUT
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-output
path: ${{ env.GH_AW_AGENT_OUTPUT }}
if-no-files-found: warn
- name: Upload engine output files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent_outputs
path: |
@@ -787,45 +822,172 @@ jobs:
- name: Upload agent artifacts
if: always()
continue-on-error: true
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-artifacts
path: |
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/agent-stdio.log
/tmp/gh-aw/agent/
if-no-files-found: ignore
# --- Threat Detection (inline) ---
- name: Check if detection needed
id: detection_guard
if: always()
env:
OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
HAS_PATCH: ${{ steps.collect_output.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 configuration for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
rm -f /home/runner/.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
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
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
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@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Duplicate Resource Detector"
WORKFLOW_DESCRIPTION: "Weekly scan of agents, instructions, and skills to identify potential duplicate resources and report them for review"
HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/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: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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]
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_detection_results
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
- name: Set detection conclusion
id: detection_conclusion
if: always()
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
run: |
if [[ "$RUN_DETECTION" != "true" ]]; then
echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection was not needed, marking as skipped"
elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
echo "conclusion=success" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection passed successfully"
else
echo "conclusion=failure" >> "$GITHUB_OUTPUT"
echo "success=false" >> "$GITHUB_OUTPUT"
echo "Detection found issues"
fi
conclusion:
needs:
- activation
- agent
- detection
- safe_outputs
if: (always()) && (needs.agent.result != 'skipped')
runs-on: ubuntu-slim
permissions:
contents: read
issues: write
concurrency:
group: "gh-aw-conclusion-duplicate-resource-detector"
cancel-in-progress: false
outputs:
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -835,7 +997,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: 1
GH_AW_NOOP_MAX: "1"
GH_AW_WORKFLOW_NAME: "Duplicate Resource Detector"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -866,8 +1028,12 @@ jobs:
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: "duplicate-resource-detector"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }}
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -893,138 +1059,42 @@ jobs:
const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs');
await main();
detection:
needs: agent
if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true'
runs-on: ubuntu-latest
permissions: {}
concurrency:
group: "gh-aw-copilot-${{ github.workflow }}"
timeout-minutes: 10
outputs:
success: ${{ steps.parse_results.outputs.success }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
with:
destination: /opt/gh-aw/actions
- name: Download agent artifacts
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-artifacts
path: /tmp/gh-aw/threat-detection/
- name: Download agent output artifact
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-output
path: /tmp/gh-aw/threat-detection/
- name: Echo agent output types
env:
AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
run: |
echo "Agent output-types: $AGENT_OUTPUT_TYPES"
- name: Setup threat detection
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Duplicate Resource Detector"
WORKFLOW_DESCRIPTION: "Weekly scan of agents, instructions, and skills to identify potential duplicate resources and report them for review"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs');
await main();
- name: Ensure threat-detection directory and log
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"
mkdir -p /tmp/
mkdir -p /tmp/gh-aw/
mkdir -p /tmp/gh-aw/agent/
mkdir -p /tmp/gh-aw/sandbox/agent/logs/
copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
GITHUB_WORKSPACE: ${{ github.workspace }}
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_results
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
safe_outputs:
needs:
- agent
- detection
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true')
needs: agent
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
runs-on: ubuntu-slim
permissions:
contents: read
issues: write
timeout-minutes: 15
env:
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/duplicate-resource-detector"
GH_AW_ENGINE_ID: "copilot"
GH_AW_WORKFLOW_ID: "duplicate-resource-detector"
GH_AW_WORKFLOW_NAME: "Duplicate Resource Detector"
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 }}
create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -1034,6 +1104,9 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
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"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"labels\":[\"duplicate-review\"],\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -1042,4 +1115,11 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs');
await main();
- name: Upload safe output items manifest
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output-items
path: /tmp/safe-output-items.jsonl
if-no-files-found: warn

View File

@@ -13,7 +13,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by gh-aw (v0.45.7). DO NOT EDIT.
# This file was automatically generated by gh-aw (v0.57.2). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -23,7 +23,7 @@
#
# Checks PRs for potential duplicate agents, instructions, skills, and workflows already in the repository
#
# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"347e8e65bbb5c579929bf7b95fc496a3f69e64421481fa3a3c06c56f8d0b84a6"}
# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"becfe3455b339f84e723cebea7f5ee69b60955002cdac64d47fc889fce848ebe","compiler_version":"v0.57.2","strict":true}
name: "PR Duplicate Check"
"on":
@@ -36,31 +36,70 @@ name: "PR Duplicate Check"
permissions: {}
concurrency:
group: "gh-aw-${{ github.workflow }}-${{ github.event.pull_request.number }}"
group: "gh-aw-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }}"
cancel-in-progress: true
run-name: "PR Duplicate Check"
jobs:
activation:
needs: pre_activation
if: >
(needs.pre_activation.outputs.activated == 'true') && ((github.event_name != 'pull_request') || (github.event.pull_request.head.repo.id == github.repository_id))
runs-on: ubuntu-slim
permissions:
contents: read
outputs:
body: ${{ steps.sanitized.outputs.body }}
comment_id: ""
comment_repo: ""
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
text: ${{ steps.sanitized.outputs.text }}
title: ${{ steps.sanitized.outputs.title }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- 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 || '' }}
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "latest"
GH_AW_INFO_CLI_VERSION: "v0.57.2"
GH_AW_INFO_WORKFLOW_NAME: "PR Duplicate Check"
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.23.0"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { main } = require('/opt/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
.github
.agents
sparse-checkout-cone-mode: true
fetch-depth: 1
persist-credentials: false
- name: Check workflow file timestamps
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -71,6 +110,15 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/check_workflow_timestamp_api.cjs');
await main();
- name: Compute current body text
id: sanitized
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/compute_text.cjs');
await main();
- name: Create prompt with built-in context
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
@@ -85,41 +133,18 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
run: |
bash /opt/gh-aw/actions/create_prompt_first.sh
cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT"
{
cat << 'GH_AW_PROMPT_EOF'
<system>
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
<safe-outputs>
<description>GitHub API Access Instructions</description>
<important>
The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations.
</important>
<instructions>
To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls.
Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body).
**IMPORTANT - temporary_id format rules:**
- If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed)
- If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i
- Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive)
- Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
- INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore)
- VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678
- To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate
Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i.
Discover available tools from the safeoutputs MCP server.
**Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped.
**Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed.
</instructions>
</safe-outputs>
cat "/opt/gh-aw/prompts/xpia.md"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md"
cat "/opt/gh-aw/prompts/markdown.md"
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
<safe-output-tools>
Tools: add_comment, missing_tool, missing_data, noop
</safe-output-tools>
<github-context>
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -149,19 +174,18 @@ jobs:
</github-context>
GH_AW_PROMPT_EOF
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
cat "/opt/gh-aw/prompts/pr_context_prompt.md" >> "$GH_AW_PROMPT"
fi
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
</system>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/pr-duplicate-check.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
@@ -181,7 +205,6 @@ jobs:
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: ${{ needs.pre_activation.outputs.matched_command }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
@@ -201,8 +224,7 @@ jobs:
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_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
}
});
- name: Validate prompt placeholders
@@ -213,12 +235,14 @@ jobs:
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
run: bash /opt/gh-aw/actions/print_prompt_summary.sh
- name: Upload prompt artifact
- name: Upload activation artifact
if: success()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: prompt
path: /tmp/gh-aw/aw-prompts/prompt.txt
name: activation
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
retention-days: 1
agent:
@@ -226,10 +250,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
issues: read
pull-requests: read
concurrency:
group: "gh-aw-copilot-${{ github.workflow }}"
env:
DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
GH_AW_ASSETS_ALLOWED_EXTS: ""
@@ -242,14 +263,16 @@ jobs:
GH_AW_WORKFLOW_ID_SANITIZED: prduplicatecheck
outputs:
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
detection_success: ${{ steps.detection_conclusion.outputs.success }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
model: ${{ steps.generate_aw_info.outputs.model }}
inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
model: ${{ needs.activation.outputs.model }}
output: ${{ steps.collect_output.outputs.output }}
output_types: ${{ steps.collect_output.outputs.output_types }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Checkout repository
@@ -265,6 +288,7 @@ jobs:
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"
@@ -272,7 +296,7 @@ jobs:
- name: Checkout PR branch
id: checkout-pr
if: |
github.event.pull_request
(github.event.pull_request) || (github.event.issue.pull_request)
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -283,59 +307,10 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Generate agentic run info
id: generate_aw_info
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const fs = require('fs');
const awInfo = {
engine_id: "copilot",
engine_name: "GitHub Copilot CLI",
model: process.env.GH_AW_MODEL_AGENT_COPILOT || "",
version: "",
agent_version: "0.0.410",
cli_version: "v0.45.7",
workflow_name: "PR Duplicate Check",
experimental: false,
supports_tools_allowlist: true,
run_id: context.runId,
run_number: context.runNumber,
run_attempt: process.env.GITHUB_RUN_ATTEMPT,
repository: context.repo.owner + '/' + context.repo.repo,
ref: context.ref,
sha: context.sha,
actor: context.actor,
event_name: context.eventName,
staged: false,
allowed_domains: ["defaults"],
firewall_enabled: true,
awf_version: "v0.20.0",
awmg_version: "v0.1.4",
steps: {
firewall: "squid"
},
created_at: new Date().toISOString()
};
// Write to /tmp/gh-aw directory to avoid inclusion in PR
const tmpPath = '/tmp/gh-aw/aw_info.json';
fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2));
console.log('Generated aw_info.json at:', tmpPath);
console.log(JSON.stringify(awInfo, null, 2));
// Set model as output for reuse in other steps/jobs
core.setOutput('model', awInfo.model);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
run: /opt/gh-aw/actions/install_copilot_cli.sh latest
- name: Install awf binary
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.20.0
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.23.0
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -347,19 +322,19 @@ jobs:
const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
- name: Download container images
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.0 ghcr.io/github/gh-aw-firewall/squid:0.20.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.23.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.23.0 ghcr.io/github/gh-aw-firewall/squid:0.23.0 ghcr.io/github/gh-aw-mcpg:v0.1.8 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- name: Write Safe Outputs Config
run: |
mkdir -p /opt/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/safeoutputs
mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
cat > /opt/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
{"add_comment":{"max":1,"update_comment":true},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
{"add_comment":{"max":1},"missing_data":{},"missing_tool":{},"noop":{"max":1}}
GH_AW_SAFE_OUTPUTS_CONFIG_EOF
cat > /opt/gh-aw/safeoutputs/tools.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_EOF'
[
{
"description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. CONSTRAINTS: Maximum 1 comment(s) can be added.",
"description": "Add a comment to an existing GitHub issue, pull request, or discussion. Use this to provide feedback, answer questions, or add information to an existing conversation. For creating new items, use create_issue, create_discussion, or create_pull_request instead. IMPORTANT: Comments are subject to validation constraints enforced by the MCP server - maximum 65536 characters for the complete comment (including footer which is added automatically), 10 mentions (@username), and 50 links. Exceeding these limits will result in an immediate error with specific guidance. NOTE: By default, this tool requires discussions:write permission. If your GitHub App lacks Discussions permission, set 'discussions: false' in the workflow's safe-outputs.add-comment configuration to exclude this permission. CONSTRAINTS: Maximum 1 comment(s) can be added.",
"inputSchema": {
"additionalProperties": false,
"properties": {
@@ -367,9 +342,25 @@ jobs:
"description": "The comment text in Markdown format. This is the 'body' field - do not use 'comment_body' or other variations. Provide helpful, relevant information that adds value to the conversation. CONSTRAINTS: The complete comment (your body text + automatically added footer) must not exceed 65536 characters total. Maximum 10 mentions (@username), maximum 50 links (http/https URLs). A footer (~200-500 characters) is automatically appended with workflow attribution, so leave adequate space. If these limits are exceeded, the tool call will fail with a detailed error message indicating which constraint was violated.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"item_number": {
"description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). If omitted, the tool will attempt to resolve the target from the current workflow context (triggering issue, PR, or discussion).",
"type": "number"
"description": "The issue, pull request, or discussion number to comment on. This is the numeric ID from the GitHub URL (e.g., 123 in github.com/owner/repo/issues/123). Can also be a temporary_id (e.g., 'aw_abc123') from a previously created issue in the same workflow run. If omitted, the tool auto-targets the issue, PR, or discussion that triggered this workflow. Auto-targeting only works for issue, pull_request, discussion, and comment event triggers — it does NOT work for schedule, workflow_dispatch, push, or workflow_run triggers. For those trigger types, always provide item_number explicitly, or the tool call will fail with an error.",
"type": [
"number",
"string"
]
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"temporary_id": {
"description": "Unique temporary identifier for this comment. Format: 'aw_' followed by 3 to 12 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Auto-generated if not provided. The temporary ID is returned in the tool response so you can reference this comment later.",
"pattern": "^aw_[A-Za-z0-9]{3,12}$",
"type": "string"
}
},
"required": [
@@ -388,10 +379,18 @@ jobs:
"description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"tool": {
"description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.",
"type": "string"
@@ -409,9 +408,17 @@ jobs:
"inputSchema": {
"additionalProperties": false,
"properties": {
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"message": {
"description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [
@@ -438,9 +445,17 @@ jobs:
"description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this data is needed to complete the task (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [],
@@ -463,6 +478,35 @@ jobs:
},
"item_number": {
"issueOrPRNumber": 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
}
}
},
@@ -558,10 +602,11 @@ jobs:
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"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.4'
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.8'
mkdir -p /home/runner/.copilot
cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh
@@ -569,7 +614,7 @@ jobs:
"mcpServers": {
"github": {
"type": "stdio",
"container": "ghcr.io/github/github-mcp-server:v0.30.3",
"container": "ghcr.io/github/github-mcp-server:v0.32.0",
"env": {
"GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -593,17 +638,11 @@ jobs:
}
}
GH_AW_MCP_CONFIG_EOF
- name: Generate workflow overview
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- name: Download activation artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
script: |
const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs');
await generateWorkflowOverview(core);
- name: Download prompt artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: prompt
path: /tmp/gh-aw/aw-prompts
name: activation
path: /tmp/gh-aw
- name: Clean git credentials
run: bash /opt/gh-aw/actions/clean_git_credentials.sh
- name: Execute GitHub Copilot CLI
@@ -612,20 +651,37 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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 --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
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]
XDG_CONFIG_HOME: /home/runner
- name: Detect inference access error
id: detect-inference-error
if: always()
continue-on-error: true
run: bash /opt/gh-aw/actions/detect_inference_access_error.sh
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }}
@@ -633,6 +689,7 @@ jobs:
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"
@@ -678,9 +735,12 @@ jobs:
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 /opt/gh-aw/actions/append_agent_step_summary.sh
- name: Upload Safe Outputs
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output
path: ${{ env.GH_AW_SAFE_OUTPUTS }}
@@ -702,13 +762,13 @@ jobs:
await main();
- name: Upload sanitized agent output
if: always() && env.GH_AW_AGENT_OUTPUT
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-output
path: ${{ env.GH_AW_AGENT_OUTPUT }}
if-no-files-found: warn
- name: Upload engine output files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent_outputs
path: |
@@ -753,45 +813,174 @@ jobs:
- name: Upload agent artifacts
if: always()
continue-on-error: true
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-artifacts
path: |
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/agent-stdio.log
/tmp/gh-aw/agent/
if-no-files-found: ignore
# --- Threat Detection (inline) ---
- name: Check if detection needed
id: detection_guard
if: always()
env:
OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
HAS_PATCH: ${{ steps.collect_output.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 configuration for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
rm -f /home/runner/.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
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
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
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@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "PR Duplicate Check"
WORKFLOW_DESCRIPTION: "Checks PRs for potential duplicate agents, instructions, skills, and workflows already in the repository"
HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/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: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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]
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_detection_results
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
- name: Set detection conclusion
id: detection_conclusion
if: always()
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
run: |
if [[ "$RUN_DETECTION" != "true" ]]; then
echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection was not needed, marking as skipped"
elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
echo "conclusion=success" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection passed successfully"
else
echo "conclusion=failure" >> "$GITHUB_OUTPUT"
echo "success=false" >> "$GITHUB_OUTPUT"
echo "Detection found issues"
fi
conclusion:
needs:
- activation
- agent
- detection
- safe_outputs
if: (always()) && (needs.agent.result != 'skipped')
runs-on: ubuntu-slim
permissions:
contents: read
discussions: write
issues: write
pull-requests: write
concurrency:
group: "gh-aw-conclusion-pr-duplicate-check"
cancel-in-progress: false
outputs:
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -801,7 +990,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: 1
GH_AW_NOOP_MAX: "1"
GH_AW_WORKFLOW_NAME: "PR Duplicate Check"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -832,8 +1021,12 @@ jobs:
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: "pr-duplicate-check"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }}
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -859,139 +1052,68 @@ jobs:
const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs');
await main();
detection:
needs: agent
if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true'
runs-on: ubuntu-latest
permissions: {}
concurrency:
group: "gh-aw-copilot-${{ github.workflow }}"
timeout-minutes: 10
pre_activation:
if: (github.event_name != 'pull_request') || (github.event.pull_request.head.repo.id == github.repository_id)
runs-on: ubuntu-slim
outputs:
success: ${{ steps.parse_results.outputs.success }}
activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
matched_command: ''
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent artifacts
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-artifacts
path: /tmp/gh-aw/threat-detection/
- name: Download agent output artifact
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-output
path: /tmp/gh-aw/threat-detection/
- name: Echo agent output types
env:
AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
run: |
echo "Agent output-types: $AGENT_OUTPUT_TYPES"
- name: Setup threat detection
- name: Check team membership for workflow
id: check_membership
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "PR Duplicate Check"
WORKFLOW_DESCRIPTION: "Checks PRs for potential duplicate agents, instructions, skills, and workflows already in the repository"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
GH_AW_REQUIRED_ROLES: admin,maintainer,write
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs');
const { main } = require('/opt/gh-aw/actions/check_membership.cjs');
await main();
- name: Ensure threat-detection directory and log
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"
mkdir -p /tmp/
mkdir -p /tmp/gh-aw/
mkdir -p /tmp/gh-aw/agent/
mkdir -p /tmp/gh-aw/sandbox/agent/logs/
copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
GITHUB_WORKSPACE: ${{ github.workspace }}
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_results
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
safe_outputs:
needs:
- agent
- detection
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true')
needs: agent
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
runs-on: ubuntu-slim
permissions:
contents: read
discussions: write
issues: write
pull-requests: write
timeout-minutes: 15
env:
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/pr-duplicate-check"
GH_AW_ENGINE_ID: "copilot"
GH_AW_WORKFLOW_ID: "pr-duplicate-check"
GH_AW_WORKFLOW_NAME: "PR Duplicate Check"
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -1001,7 +1123,10 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":1,\"update_comment\":true},\"missing_data\":{},\"missing_tool\":{}}"
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"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -1009,4 +1134,11 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs');
await main();
- name: Upload safe output items manifest
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output-items
path: /tmp/safe-output-items.jsonl
if-no-files-found: warn

View File

@@ -5,14 +5,14 @@ on:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
pull-requests: read
tools:
github:
toolsets: [repos, pull_requests]
safe-outputs:
add-comment:
max: 1
update-comment: true
hide-older-comments: true
noop:
---

View File

@@ -13,7 +13,7 @@
# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
#
# This file was automatically generated by gh-aw (v0.45.7). DO NOT EDIT.
# This file was automatically generated by gh-aw (v0.57.2). DO NOT EDIT.
#
# To update this file, edit the corresponding .md file and run:
# gh aw compile
@@ -23,7 +23,7 @@
#
# Weekly report identifying stale and aging resources across agents, prompts, instructions, hooks, and skills folders
#
# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"9ab9dc5c875492aa5da7b793735c1a9816a55c753165c01efd9d86087d7f33d3"}
# gh-aw-metadata: {"schema_version":"v2","frontmatter_hash":"9ab9dc5c875492aa5da7b793735c1a9816a55c753165c01efd9d86087d7f33d3","compiler_version":"v0.57.2","strict":true}
name: "Resource Staleness Report"
"on":
@@ -47,19 +47,51 @@ jobs:
outputs:
comment_id: ""
comment_repo: ""
model: ${{ steps.generate_aw_info.outputs.model }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- 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 || '' }}
GH_AW_INFO_VERSION: ""
GH_AW_INFO_AGENT_VERSION: "latest"
GH_AW_INFO_CLI_VERSION: "v0.57.2"
GH_AW_INFO_WORKFLOW_NAME: "Resource Staleness Report"
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.23.0"
GH_AW_INFO_AWMG_VERSION: ""
GH_AW_INFO_FIREWALL_TYPE: "squid"
GH_AW_COMPILED_STRICT: "true"
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { main } = require('/opt/gh-aw/actions/generate_aw_info.cjs');
await main(core, context);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Checkout .github and .agents folders
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
sparse-checkout: |
.github
.agents
sparse-checkout-cone-mode: true
fetch-depth: 1
persist-credentials: false
- name: Check workflow file timestamps
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -84,41 +116,18 @@ jobs:
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
run: |
bash /opt/gh-aw/actions/create_prompt_first.sh
cat << 'GH_AW_PROMPT_EOF' > "$GH_AW_PROMPT"
{
cat << 'GH_AW_PROMPT_EOF'
<system>
GH_AW_PROMPT_EOF
cat "/opt/gh-aw/prompts/xpia.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md" >> "$GH_AW_PROMPT"
cat "/opt/gh-aw/prompts/markdown.md" >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
<safe-outputs>
<description>GitHub API Access Instructions</description>
<important>
The gh CLI is NOT authenticated. Do NOT use gh commands for GitHub operations.
</important>
<instructions>
To create or modify GitHub resources (issues, discussions, pull requests, etc.), you MUST call the appropriate safe output tool. Simply writing content will NOT work - the workflow requires actual tool calls.
Temporary IDs: Some safe output tools support a temporary ID field (usually named temporary_id) so you can reference newly-created items elsewhere in the SAME agent output (for example, using #aw_abc1 in a later body).
**IMPORTANT - temporary_id format rules:**
- If you DON'T need to reference the item later, OMIT the temporary_id field entirely (it will be auto-generated if needed)
- If you DO need cross-references/chaining, you MUST match this EXACT validation regex: /^aw_[A-Za-z0-9]{3,8}$/i
- Format: aw_ prefix followed by 3 to 8 alphanumeric characters (A-Z, a-z, 0-9, case-insensitive)
- Valid alphanumeric characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
- INVALID examples: aw_ab (too short), aw_123456789 (too long), aw_test-id (contains hyphen), aw_id_123 (contains underscore)
- VALID examples: aw_abc, aw_abc1, aw_Test123, aw_A1B2C3D4, aw_12345678
- To generate valid IDs: use 3-8 random alphanumeric characters or omit the field to let the system auto-generate
Do NOT invent other aw_* formats — downstream steps will reject them with validation errors matching against /^aw_[A-Za-z0-9]{3,8}$/i.
Discover available tools from the safeoutputs MCP server.
**Critical**: Tool calls write structured data that downstream jobs process. Without tool calls, follow-up actions will be skipped.
**Note**: If you made no other safe output tool calls during this workflow execution, call the "noop" tool to provide a status message indicating completion or that no actions were needed.
</instructions>
</safe-outputs>
cat "/opt/gh-aw/prompts/xpia.md"
cat "/opt/gh-aw/prompts/temp_folder_prompt.md"
cat "/opt/gh-aw/prompts/markdown.md"
cat "/opt/gh-aw/prompts/safe_outputs_prompt.md"
cat << 'GH_AW_PROMPT_EOF'
<safe-output-tools>
Tools: create_issue, missing_tool, missing_data, noop
</safe-output-tools>
<github-context>
The following GitHub context information is available for this workflow:
{{#if __GH_AW_GITHUB_ACTOR__ }}
@@ -148,12 +157,13 @@ jobs:
</github-context>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
</system>
GH_AW_PROMPT_EOF
cat << 'GH_AW_PROMPT_EOF' >> "$GH_AW_PROMPT"
cat << 'GH_AW_PROMPT_EOF'
{{#runtime-import .github/workflows/resource-staleness-report.md}}
GH_AW_PROMPT_EOF
} > "$GH_AW_PROMPT"
- name: Interpolate variables and render templates
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
@@ -176,8 +186,6 @@ jobs:
GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: ${{ needs.pre_activation.outputs.matched_command }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
@@ -196,9 +204,7 @@ jobs:
GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
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_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND
GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE
}
});
- name: Validate prompt placeholders
@@ -209,12 +215,14 @@ jobs:
env:
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
run: bash /opt/gh-aw/actions/print_prompt_summary.sh
- name: Upload prompt artifact
- name: Upload activation artifact
if: success()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: prompt
path: /tmp/gh-aw/aw-prompts/prompt.txt
name: activation
path: |
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/aw-prompts/prompt.txt
retention-days: 1
agent:
@@ -236,14 +244,16 @@ jobs:
GH_AW_WORKFLOW_ID_SANITIZED: resourcestalenessreport
outputs:
checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
detection_success: ${{ steps.detection_conclusion.outputs.success }}
has_patch: ${{ steps.collect_output.outputs.has_patch }}
model: ${{ steps.generate_aw_info.outputs.model }}
inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
model: ${{ needs.activation.outputs.model }}
output: ${{ steps.collect_output.outputs.output }}
output_types: ${{ steps.collect_output.outputs.output_types }}
secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Checkout repository
@@ -259,6 +269,7 @@ jobs:
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"
@@ -266,7 +277,7 @@ jobs:
- name: Checkout PR branch
id: checkout-pr
if: |
github.event.pull_request
(github.event.pull_request) || (github.event.issue.pull_request)
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -277,59 +288,10 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/checkout_pr_branch.cjs');
await main();
- name: Generate agentic run info
id: generate_aw_info
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const fs = require('fs');
const awInfo = {
engine_id: "copilot",
engine_name: "GitHub Copilot CLI",
model: process.env.GH_AW_MODEL_AGENT_COPILOT || "",
version: "",
agent_version: "0.0.410",
cli_version: "v0.45.7",
workflow_name: "Resource Staleness Report",
experimental: false,
supports_tools_allowlist: true,
run_id: context.runId,
run_number: context.runNumber,
run_attempt: process.env.GITHUB_RUN_ATTEMPT,
repository: context.repo.owner + '/' + context.repo.repo,
ref: context.ref,
sha: context.sha,
actor: context.actor,
event_name: context.eventName,
staged: false,
allowed_domains: ["defaults"],
firewall_enabled: true,
awf_version: "v0.20.0",
awmg_version: "v0.1.4",
steps: {
firewall: "squid"
},
created_at: new Date().toISOString()
};
// Write to /tmp/gh-aw directory to avoid inclusion in PR
const tmpPath = '/tmp/gh-aw/aw_info.json';
fs.writeFileSync(tmpPath, JSON.stringify(awInfo, null, 2));
console.log('Generated aw_info.json at:', tmpPath);
console.log(JSON.stringify(awInfo, null, 2));
// Set model as output for reuse in other steps/jobs
core.setOutput('model', awInfo.model);
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
run: /opt/gh-aw/actions/install_copilot_cli.sh latest
- name: Install awf binary
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.20.0
run: bash /opt/gh-aw/actions/install_awf_binary.sh v0.23.0
- name: Determine automatic lockdown mode for GitHub MCP Server
id: determine-automatic-lockdown
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
@@ -341,7 +303,7 @@ jobs:
const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs');
await determineAutomaticLockdown(github, context, core);
- name: Download container images
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.0 ghcr.io/github/gh-aw-firewall/squid:0.20.0 ghcr.io/github/gh-aw-mcpg:v0.1.4 ghcr.io/github/github-mcp-server:v0.30.3 node:lts-alpine
run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.23.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.23.0 ghcr.io/github/gh-aw-firewall/squid:0.23.0 ghcr.io/github/gh-aw-mcpg:v0.1.8 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
- name: Write Safe Outputs Config
run: |
mkdir -p /opt/gh-aw/safeoutputs
@@ -361,6 +323,10 @@ jobs:
"description": "Detailed issue description in Markdown. Do NOT repeat the title as a heading since it already appears as the issue's h1. Include context, reproduction steps, or acceptance criteria as appropriate.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"labels": {
"description": "Labels to categorize the issue (e.g., 'bug', 'enhancement'). Labels must exist in the repository.",
"items": {
@@ -375,9 +341,13 @@ jobs:
"string"
]
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"temporary_id": {
"description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 8 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.",
"pattern": "^aw_[A-Za-z0-9]{3,8}$",
"description": "Unique temporary identifier for referencing this issue before it's created. Format: 'aw_' followed by 3 to 12 alphanumeric characters (e.g., 'aw_abc1', 'aw_Test123'). Use '#aw_ID' in body text to reference other issues by their temporary_id; these are replaced with actual issue numbers after creation.",
"pattern": "^aw_[A-Za-z0-9]{3,12}$",
"type": "string"
},
"title": {
@@ -402,10 +372,18 @@ jobs:
"description": "Any workarounds, manual steps, or alternative approaches the user could take (max 256 characters).",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this tool is needed or what information you want to share about the limitation (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
},
"tool": {
"description": "Optional: Name or description of the missing tool or capability (max 128 characters). Be specific about what functionality is needed.",
"type": "string"
@@ -423,9 +401,17 @@ jobs:
"inputSchema": {
"additionalProperties": false,
"properties": {
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"message": {
"description": "Status or completion message to log. Should explain what was analyzed and the outcome (e.g., 'Code review complete - no issues found', 'Analysis complete - all tests passing').",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [
@@ -452,9 +438,17 @@ jobs:
"description": "Type or description of the missing data or information (max 128 characters). Be specific about what data is needed.",
"type": "string"
},
"integrity": {
"description": "Trustworthiness level of the message source (e.g., \"low\", \"medium\", \"high\").",
"type": "string"
},
"reason": {
"description": "Explanation of why this data is needed to complete the task (max 256 characters).",
"type": "string"
},
"secrecy": {
"description": "Confidentiality level of the message content (e.g., \"public\", \"internal\", \"private\").",
"type": "string"
}
},
"required": [],
@@ -499,6 +493,31 @@ jobs:
}
}
},
"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": {
@@ -591,10 +610,11 @@ jobs:
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"
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.4'
export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -v /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.1.8'
mkdir -p /home/runner/.copilot
cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh
@@ -602,7 +622,7 @@ jobs:
"mcpServers": {
"github": {
"type": "stdio",
"container": "ghcr.io/github/github-mcp-server:v0.30.3",
"container": "ghcr.io/github/github-mcp-server:v0.32.0",
"env": {
"GITHUB_LOCKDOWN_MODE": "$GITHUB_MCP_LOCKDOWN",
"GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
@@ -626,17 +646,11 @@ jobs:
}
}
GH_AW_MCP_CONFIG_EOF
- name: Generate workflow overview
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- name: Download activation artifact
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
script: |
const { generateWorkflowOverview } = require('/opt/gh-aw/actions/generate_workflow_overview.cjs');
await generateWorkflowOverview(core);
- name: Download prompt artifact
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: prompt
path: /tmp/gh-aw/aw-prompts
name: activation
path: /tmp/gh-aw
- name: Clean git credentials
run: bash /opt/gh-aw/actions/clean_git_credentials.sh
- name: Execute GitHub Copilot CLI
@@ -645,20 +659,37 @@ jobs:
timeout-minutes: 20
run: |
set -o pipefail
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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 --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.20.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"${GH_AW_MODEL_AGENT_COPILOT:+ --model "$GH_AW_MODEL_AGENT_COPILOT"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-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" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-all-tools --allow-all-paths --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
GH_AW_MODEL_AGENT_COPILOT: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
GH_AW_PHASE: agent
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
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]
XDG_CONFIG_HOME: /home/runner
- name: Detect inference access error
id: detect-inference-error
if: always()
continue-on-error: true
run: bash /opt/gh-aw/actions/detect_inference_access_error.sh
- name: Configure Git credentials
env:
REPO_NAME: ${{ github.repository }}
@@ -666,6 +697,7 @@ jobs:
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"
@@ -711,9 +743,12 @@ jobs:
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 /opt/gh-aw/actions/append_agent_step_summary.sh
- name: Upload Safe Outputs
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output
path: ${{ env.GH_AW_SAFE_OUTPUTS }}
@@ -735,13 +770,13 @@ jobs:
await main();
- name: Upload sanitized agent output
if: always() && env.GH_AW_AGENT_OUTPUT
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-output
path: ${{ env.GH_AW_AGENT_OUTPUT }}
if-no-files-found: warn
- name: Upload engine output files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent_outputs
path: |
@@ -786,45 +821,172 @@ jobs:
- name: Upload agent artifacts
if: always()
continue-on-error: true
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: agent-artifacts
path: |
/tmp/gh-aw/aw-prompts/prompt.txt
/tmp/gh-aw/aw_info.json
/tmp/gh-aw/mcp-logs/
/tmp/gh-aw/sandbox/firewall/logs/
/tmp/gh-aw/agent-stdio.log
/tmp/gh-aw/agent/
if-no-files-found: ignore
# --- Threat Detection (inline) ---
- name: Check if detection needed
id: detection_guard
if: always()
env:
OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
HAS_PATCH: ${{ steps.collect_output.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 configuration for detection
if: always() && steps.detection_guard.outputs.run_detection == 'true'
run: |
rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
rm -f /home/runner/.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
cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
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
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@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Resource Staleness Report"
WORKFLOW_DESCRIPTION: "Weekly report identifying stale and aging resources across agents, prompts, instructions, hooks, and skills folders"
HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/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: Execute GitHub Copilot CLI
if: always() && steps.detection_guard.outputs.run_detection == 'true'
id: detection_agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
touch /tmp/gh-aw/agent-step-summary.md
# shellcheck disable=SC1003
sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --allow-domains "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,github.com,host.docker.internal,raw.githubusercontent.com,registry.npmjs.org,telemetry.enterprise.githubcopilot.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.23.0 --skip-pull --enable-api-proxy \
-- /bin/bash -c '/usr/local/bin/copilot --add-dir /tmp/gh-aw/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --add-dir "${GITHUB_WORKSPACE}" --disable-builtin-mcps --allow-tool '\''shell(cat)'\'' --allow-tool '\''shell(grep)'\'' --allow-tool '\''shell(head)'\'' --allow-tool '\''shell(jq)'\'' --allow-tool '\''shell(ls)'\'' --allow-tool '\''shell(tail)'\'' --allow-tool '\''shell(wc)'\'' --prompt "$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"' 2>&1 | tee -a /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PHASE: detection
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GH_AW_VERSION: v0.57.2
GITHUB_API_URL: ${{ github.api_url }}
GITHUB_AW: true
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]
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_detection_results
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always() && steps.detection_guard.outputs.run_detection == 'true'
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
- name: Set detection conclusion
id: detection_conclusion
if: always()
env:
RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
run: |
if [[ "$RUN_DETECTION" != "true" ]]; then
echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection was not needed, marking as skipped"
elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
echo "conclusion=success" >> "$GITHUB_OUTPUT"
echo "success=true" >> "$GITHUB_OUTPUT"
echo "Detection passed successfully"
else
echo "conclusion=failure" >> "$GITHUB_OUTPUT"
echo "success=false" >> "$GITHUB_OUTPUT"
echo "Detection found issues"
fi
conclusion:
needs:
- activation
- agent
- detection
- safe_outputs
if: (always()) && (needs.agent.result != 'skipped')
runs-on: ubuntu-slim
permissions:
contents: read
issues: write
concurrency:
group: "gh-aw-conclusion-resource-staleness-report"
cancel-in-progress: false
outputs:
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -834,7 +996,7 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
GH_AW_NOOP_MAX: 1
GH_AW_NOOP_MAX: "1"
GH_AW_WORKFLOW_NAME: "Resource Staleness Report"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -865,8 +1027,12 @@ jobs:
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: "resource-staleness-report"
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.agent.outputs.secret_verification_result }}
GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
GH_AW_GROUP_REPORTS: "false"
GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
GH_AW_TIMEOUT_MINUTES: "20"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
script: |
@@ -892,138 +1058,42 @@ jobs:
const { main } = require('/opt/gh-aw/actions/handle_noop_message.cjs');
await main();
detection:
needs: agent
if: needs.agent.outputs.output_types != '' || needs.agent.outputs.has_patch == 'true'
runs-on: ubuntu-latest
permissions: {}
concurrency:
group: "gh-aw-copilot-${{ github.workflow }}"
timeout-minutes: 10
outputs:
success: ${{ steps.parse_results.outputs.success }}
steps:
- name: Setup Scripts
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
with:
destination: /opt/gh-aw/actions
- name: Download agent artifacts
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-artifacts
path: /tmp/gh-aw/threat-detection/
- name: Download agent output artifact
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
with:
name: agent-output
path: /tmp/gh-aw/threat-detection/
- name: Echo agent output types
env:
AGENT_OUTPUT_TYPES: ${{ needs.agent.outputs.output_types }}
run: |
echo "Agent output-types: $AGENT_OUTPUT_TYPES"
- name: Setup threat detection
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
WORKFLOW_NAME: "Resource Staleness Report"
WORKFLOW_DESCRIPTION: "Weekly report identifying stale and aging resources across agents, prompts, instructions, hooks, and skills folders"
HAS_PATCH: ${{ needs.agent.outputs.has_patch }}
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/setup_threat_detection.cjs');
await main();
- name: Ensure threat-detection directory and log
run: |
mkdir -p /tmp/gh-aw/threat-detection
touch /tmp/gh-aw/threat-detection/detection.log
- name: Validate COPILOT_GITHUB_TOKEN secret
id: validate-secret
run: /opt/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
env:
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
- name: Install GitHub Copilot CLI
run: /opt/gh-aw/actions/install_copilot_cli.sh 0.0.410
- name: Execute GitHub Copilot CLI
id: agentic_execution
# Copilot CLI tool arguments (sorted):
# --allow-tool shell(cat)
# --allow-tool shell(grep)
# --allow-tool shell(head)
# --allow-tool shell(jq)
# --allow-tool shell(ls)
# --allow-tool shell(tail)
# --allow-tool shell(wc)
timeout-minutes: 20
run: |
set -o pipefail
COPILOT_CLI_INSTRUCTION="$(cat /tmp/gh-aw/aw-prompts/prompt.txt)"
mkdir -p /tmp/
mkdir -p /tmp/gh-aw/
mkdir -p /tmp/gh-aw/agent/
mkdir -p /tmp/gh-aw/sandbox/agent/logs/
copilot --add-dir /tmp/ --add-dir /tmp/gh-aw/ --add-dir /tmp/gh-aw/agent/ --log-level all --log-dir /tmp/gh-aw/sandbox/agent/logs/ --disable-builtin-mcps --allow-tool 'shell(cat)' --allow-tool 'shell(grep)' --allow-tool 'shell(head)' --allow-tool 'shell(jq)' --allow-tool 'shell(ls)' --allow-tool 'shell(tail)' --allow-tool 'shell(wc)' --share /tmp/gh-aw/sandbox/agent/logs/conversation.md --prompt "$COPILOT_CLI_INSTRUCTION"${GH_AW_MODEL_DETECTION_COPILOT:+ --model "$GH_AW_MODEL_DETECTION_COPILOT"} 2>&1 | tee /tmp/gh-aw/threat-detection/detection.log
env:
COPILOT_AGENT_RUNNER_TYPE: STANDALONE
COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
GH_AW_MODEL_DETECTION_COPILOT: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
GITHUB_HEAD_REF: ${{ github.head_ref }}
GITHUB_REF_NAME: ${{ github.ref_name }}
GITHUB_STEP_SUMMARY: ${{ env.GITHUB_STEP_SUMMARY }}
GITHUB_WORKSPACE: ${{ github.workspace }}
XDG_CONFIG_HOME: /home/runner
- name: Parse threat detection results
id: parse_results
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
with:
script: |
const { setupGlobals } = require('/opt/gh-aw/actions/setup_globals.cjs');
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/parse_threat_detection_results.cjs');
await main();
- name: Upload threat detection log
if: always()
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: threat-detection.log
path: /tmp/gh-aw/threat-detection/detection.log
if-no-files-found: ignore
safe_outputs:
needs:
- agent
- detection
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.detection.outputs.success == 'true')
needs: agent
if: ((!cancelled()) && (needs.agent.result != 'skipped')) && (needs.agent.outputs.detection_success == 'true')
runs-on: ubuntu-slim
permissions:
contents: read
issues: write
timeout-minutes: 15
env:
GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/resource-staleness-report"
GH_AW_ENGINE_ID: "copilot"
GH_AW_WORKFLOW_ID: "resource-staleness-report"
GH_AW_WORKFLOW_NAME: "Resource Staleness Report"
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 }}
create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
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
uses: github/gh-aw/actions/setup@5d8900eb6f6230c9d41a3c30af320150a2361285 # v0.45.7
uses: github/gh-aw/actions/setup@32b3a711a9ee97d38e3989c90af0385aff0066a7 # v0.57.2
with:
destination: /opt/gh-aw/actions
- name: Download agent output artifact
id: download-agent-output
continue-on-error: true
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8
with:
name: agent-output
path: /tmp/gh-aw/safeoutputs/
- name: Setup agent output environment variable
if: steps.download-agent-output.outcome == 'success'
run: |
mkdir -p /tmp/gh-aw/safeoutputs/
find "/tmp/gh-aw/safeoutputs/" -type f -print
@@ -1033,6 +1103,9 @@ jobs:
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
env:
GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
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"
GITHUB_SERVER_URL: ${{ github.server_url }}
GITHUB_API_URL: ${{ github.api_url }}
GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"create_issue\":{\"close_older_issues\":true,\"max\":1},\"missing_data\":{},\"missing_tool\":{}}"
with:
github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
@@ -1041,4 +1114,11 @@ jobs:
setupGlobals(core, github, context, exec, io);
const { main } = require('/opt/gh-aw/actions/safe_output_handler_manager.cjs');
await main();
- name: Upload safe output items manifest
if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
with:
name: safe-output-items
path: /tmp/safe-output-items.jsonl
if-no-files-found: warn