microsoft/hve-core

Public

mirrored from https://github.com/microsoft/hve-coreAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
fix/agent-frontmatter-lint-errors

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

.github/workflows/dependency-pr-review.lock.yml

1178lines · modecode

1# ___ _ _
2# / _ \ | | (_)
3# | |_| | __ _ ___ _ __ | |_ _ ___
4# | _ |/ _` |/ _ \ '_ \| __| |/ __|
5# | | | | (_| | __/ | | | |_| | (__
6# \_| |_/\__, |\___|_| |_|\__|_|\___|
7# __/ |
8# _ _ |___/
9# | | | | / _| |
10# | | | | ___ _ __ _ __| |_| | _____ ____
11# | |/\| |/ _ \ '__| |/ /| _| |/ _ \ \ /\ / / ___|
12# \ /\ / (_) | | | | ( | | | | (_) \ V V /\__ \
13# \/ \/ \___/|_| |_|\_\|_| |_|\___/ \_/\_/ |___/
14#
15# This file was automatically generated by gh-aw (v0.63.1). DO NOT EDIT.
16#
17# To update this file, edit the corresponding .md file and run:
18# gh aw compile
19# Not all edits will cause changes to this file.
20#
21# For more information: https://github.github.com/gh-aw/introduction/overview/
22#
23# Reviews and auto-approves Dependabot version bump PRs after safety validation
24#
25# Resolved workflow manifest:
26# Imports:
27# - ../agents/dependency-reviewer.agent.md
28#
29# gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"6b38135395c9a7ad2115492be6ed04f69ce6d4bf84d4a9598b4b701041d753a9","compiler_version":"v0.63.1","strict":true,"agent_id":"copilot"}
30
31name: "Dependabot PR Review"
32"on":
33 pull_request:
34 paths:
35 - package.json
36 - package-lock.json
37 - "**/requirements.txt"
38 - "**/pyproject.toml"
39 - .github/workflows/*.yml
40 - .devcontainer/**
41 types:
42 - opened
43 - synchronize
44
45permissions: {}
46
47concurrency:
48 group: "gh-aw-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref || github.run_id }}"
49 cancel-in-progress: true
50
51run-name: "Dependabot PR Review"
52
53jobs:
54 activation:
55 needs: pre_activation
56 if: >
57 needs.pre_activation.outputs.activated == 'true' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id)
58 runs-on: ubuntu-slim
59 permissions:
60 contents: read
61 discussions: write
62 issues: write
63 pull-requests: write
64 outputs:
65 body: ${{ steps.sanitized.outputs.body }}
66 comment_id: ""
67 comment_repo: ""
68 lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
69 model: ${{ steps.generate_aw_info.outputs.model }}
70 secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
71 text: ${{ steps.sanitized.outputs.text }}
72 title: ${{ steps.sanitized.outputs.title }}
73 steps:
74 - name: Setup Scripts
75 uses: github/gh-aw-actions/setup@53e09ec0be6271e81a69f51ef93f37212c8834b0 # v0.63.1
76 with:
77 destination: ${{ runner.temp }}/gh-aw/actions
78 - name: Generate agentic run info
79 id: generate_aw_info
80 env:
81 GH_AW_INFO_ENGINE_ID: "copilot"
82 GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
83 GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || 'auto' }}
84 GH_AW_INFO_VERSION: "latest"
85 GH_AW_INFO_AGENT_VERSION: "latest"
86 GH_AW_INFO_CLI_VERSION: "v0.63.1"
87 GH_AW_INFO_WORKFLOW_NAME: "Dependabot PR Review"
88 GH_AW_INFO_EXPERIMENTAL: "false"
89 GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
90 GH_AW_INFO_STAGED: "false"
91 GH_AW_INFO_ALLOWED_DOMAINS: '["defaults"]'
92 GH_AW_INFO_FIREWALL_ENABLED: "true"
93 GH_AW_INFO_AWF_VERSION: "v0.25.0"
94 GH_AW_INFO_AWMG_VERSION: ""
95 GH_AW_INFO_FIREWALL_TYPE: "squid"
96 GH_AW_COMPILED_STRICT: "true"
97 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
98 with:
99 script: |
100 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
101 setupGlobals(core, github, context, exec, io);
102 const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
103 await main(core, context);
104 - name: Add eyes reaction for immediate feedback
105 id: react
106 if: github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id
107 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
108 env:
109 GH_AW_REACTION: "eyes"
110 with:
111 github-token: ${{ secrets.GITHUB_TOKEN }}
112 script: |
113 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
114 setupGlobals(core, github, context, exec, io);
115 const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
116 await main();
117 - name: Validate COPILOT_GITHUB_TOKEN secret
118 id: validate-secret
119 run: ${RUNNER_TEMP}/gh-aw/actions/validate_multi_secret.sh COPILOT_GITHUB_TOKEN 'GitHub Copilot CLI' https://github.github.com/gh-aw/reference/engines/#github-copilot-default
120 env:
121 COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
122 - name: Checkout .github and .agents folders
123 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
124 with:
125 persist-credentials: false
126 sparse-checkout: |
127 .github
128 .agents
129 sparse-checkout-cone-mode: true
130 fetch-depth: 1
131 - name: Check workflow file timestamps
132 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
133 env:
134 GH_AW_WORKFLOW_FILE: "dependency-pr-review.lock.yml"
135 with:
136 script: |
137 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
138 setupGlobals(core, github, context, exec, io);
139 const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
140 await main();
141 - name: Compute current body text
142 id: sanitized
143 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
144 with:
145 script: |
146 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
147 setupGlobals(core, github, context, exec, io);
148 const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs');
149 await main();
150 - name: Create prompt with built-in context
151 env:
152 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
153 GH_AW_SAFE_OUTPUTS: ${{ runner.temp }}/gh-aw/safeoutputs/outputs.jsonl
154 GH_AW_GITHUB_ACTOR: ${{ github.actor }}
155 GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
156 GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
157 GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
158 GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
159 GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
160 GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
161 GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
162 # poutine:ignore untrusted_checkout_exec
163 run: |
164 bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
165 {
166 cat << 'GH_AW_PROMPT_EOF'
167 <system>
168 GH_AW_PROMPT_EOF
169 cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
170 cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
171 cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
172 cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
173 cat << 'GH_AW_PROMPT_EOF'
174 <safe-output-tools>
175 Tools: add_comment(max:2), create_pull_request_review_comment(max:5), submit_pull_request_review, missing_tool, missing_data, noop
176 </safe-output-tools>
177 <github-context>
178 The following GitHub context information is available for this workflow:
179 {{#if __GH_AW_GITHUB_ACTOR__ }}
180 - **actor**: __GH_AW_GITHUB_ACTOR__
181 {{/if}}
182 {{#if __GH_AW_GITHUB_REPOSITORY__ }}
183 - **repository**: __GH_AW_GITHUB_REPOSITORY__
184 {{/if}}
185 {{#if __GH_AW_GITHUB_WORKSPACE__ }}
186 - **workspace**: __GH_AW_GITHUB_WORKSPACE__
187 {{/if}}
188 {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
189 - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
190 {{/if}}
191 {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
192 - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
193 {{/if}}
194 {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
195 - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
196 {{/if}}
197 {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
198 - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
199 {{/if}}
200 {{#if __GH_AW_GITHUB_RUN_ID__ }}
201 - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
202 {{/if}}
203 - **checkouts**: The following repositories have been checked out and are available in the workspace:
204 - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [shallow clone, fetch-depth=1 (default)]
205 - **Note**: If a branch you need is not in the list above and is not listed as an additional fetched ref, it has NOT been checked out. For private repositories you cannot fetch it without proper authentication. If the branch is required and not available, exit with an error and ask the user to add it to the `fetch:` option of the `checkout:` configuration (e.g., `fetch: ["refs/pulls/open/*"]` for all open PR refs, or `fetch: ["main", "feature/my-branch"]` for specific branches).
206 </github-context>
207
208 GH_AW_PROMPT_EOF
209 cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
210 cat << 'GH_AW_PROMPT_EOF'
211 </system>
212 GH_AW_PROMPT_EOF
213 cat << 'GH_AW_PROMPT_EOF'
214 {{#runtime-import .github/agents/dependency-reviewer.agent.md}}
215 GH_AW_PROMPT_EOF
216 cat << 'GH_AW_PROMPT_EOF'
217 {{#runtime-import .github/workflows/dependency-pr-review.md}}
218 GH_AW_PROMPT_EOF
219 } > "$GH_AW_PROMPT"
220 - name: Interpolate variables and render templates
221 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
222 env:
223 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
224 with:
225 script: |
226 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
227 setupGlobals(core, github, context, exec, io);
228 const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
229 await main();
230 - name: Substitute placeholders
231 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
232 env:
233 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
234 GH_AW_GITHUB_ACTOR: ${{ github.actor }}
235 GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
236 GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
237 GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
238 GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
239 GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
240 GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
241 GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
242 GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
243 with:
244 script: |
245 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
246 setupGlobals(core, github, context, exec, io);
247
248 const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
249
250 // Call the substitution function
251 return await substitutePlaceholders({
252 file: process.env.GH_AW_PROMPT,
253 substitutions: {
254 GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
255 GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
256 GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
257 GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
258 GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
259 GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
260 GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
261 GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
262 GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED
263 }
264 });
265 - name: Validate prompt placeholders
266 env:
267 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
268 # poutine:ignore untrusted_checkout_exec
269 run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
270 - name: Print prompt
271 env:
272 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
273 # poutine:ignore untrusted_checkout_exec
274 run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
275 - name: Upload activation artifact
276 if: success()
277 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
278 with:
279 name: activation
280 path: |
281 /tmp/gh-aw/aw_info.json
282 /tmp/gh-aw/aw-prompts/prompt.txt
283 retention-days: 1
284
285 agent:
286 needs: activation
287 runs-on: ubuntu-latest
288 permissions:
289 contents: read
290 pull-requests: read
291 env:
292 DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
293 GH_AW_ASSETS_ALLOWED_EXTS: ""
294 GH_AW_ASSETS_BRANCH: ""
295 GH_AW_ASSETS_MAX_SIZE_KB: 0
296 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
297 GH_AW_WORKFLOW_ID_SANITIZED: dependencyprreview
298 outputs:
299 checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
300 detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
301 detection_success: ${{ steps.detection_conclusion.outputs.success }}
302 has_patch: ${{ steps.collect_output.outputs.has_patch }}
303 inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
304 model: ${{ needs.activation.outputs.model }}
305 output: ${{ steps.collect_output.outputs.output }}
306 output_types: ${{ steps.collect_output.outputs.output_types }}
307 steps:
308 - name: Setup Scripts
309 uses: github/gh-aw-actions/setup@53e09ec0be6271e81a69f51ef93f37212c8834b0 # v0.63.1
310 with:
311 destination: ${{ runner.temp }}/gh-aw/actions
312 - name: Set runtime paths
313 id: set-runtime-paths
314 run: |
315 echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_OUTPUT"
316 echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_OUTPUT"
317 echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_OUTPUT"
318 - name: Checkout repository
319 uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
320 with:
321 persist-credentials: false
322 sparse-checkout: |
323 .github/copilot-instructions.md
324 .github/instructions/coding-standards/
325 .github/instructions/hve-core/
326 .github/instructions/shared/
327 .devcontainer/
328 .github/workflows/copilot-setup-steps.yml
329 package.json
330 package-lock.json
331 **/requirements.txt
332 **/pyproject.toml
333 - name: Merge remote .github folder
334 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
335 env:
336 GH_AW_AGENT_FILE: ".github/agents/dependency-reviewer.agent.md"
337 GH_AW_AGENT_IMPORT_SPEC: "../agents/dependency-reviewer.agent.md"
338 with:
339 script: |
340 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
341 setupGlobals(core, github, context, exec, io);
342 const { main } = require('${{ runner.temp }}/gh-aw/actions/merge_remote_agent_github_folder.cjs');
343 await main();
344 - name: Create gh-aw temp directory
345 run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
346 - name: Configure gh CLI for GitHub Enterprise
347 run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
348 env:
349 GH_TOKEN: ${{ github.token }}
350 - name: Configure Git credentials
351 env:
352 REPO_NAME: ${{ github.repository }}
353 SERVER_URL: ${{ github.server_url }}
354 run: |
355 git config --global user.email "github-actions[bot]@users.noreply.github.com"
356 git config --global user.name "github-actions[bot]"
357 git config --global am.keepcr true
358 # Re-authenticate git with GitHub token
359 SERVER_URL_STRIPPED="${SERVER_URL#https://}"
360 git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
361 echo "Git configured with standard GitHub Actions identity"
362 - name: Checkout PR branch
363 id: checkout-pr
364 if: |
365 github.event.pull_request || github.event.issue.pull_request
366 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
367 env:
368 GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
369 with:
370 github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
371 script: |
372 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
373 setupGlobals(core, github, context, exec, io);
374 const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
375 await main();
376 - name: Install GitHub Copilot CLI
377 run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
378 env:
379 GH_HOST: github.com
380 - name: Install AWF binary
381 run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.25.0
382 - name: Determine automatic lockdown mode for GitHub MCP Server
383 id: determine-automatic-lockdown
384 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
385 env:
386 GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
387 GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
388 with:
389 script: |
390 const determineAutomaticLockdown = require('${{ runner.temp }}/gh-aw/actions/determine_automatic_lockdown.cjs');
391 await determineAutomaticLockdown(github, context, core);
392 - name: Download container images
393 run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.25.0 ghcr.io/github/gh-aw-firewall/api-proxy:0.25.0 ghcr.io/github/gh-aw-firewall/squid:0.25.0 ghcr.io/github/gh-aw-mcpg:v0.2.4 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
394 - name: Write Safe Outputs Config
395 run: |
396 mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
397 mkdir -p /tmp/gh-aw/safeoutputs
398 mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
399 cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
400 {"add_comment":{"max":2,"target":"triggering"},"create_pull_request_review_comment":{"max":5,"side":"RIGHT"},"missing_data":{},"missing_tool":{},"noop":{"max":1,"report-as-issue":"true"},"submit_pull_request_review":{"max":1}}
401 GH_AW_SAFE_OUTPUTS_CONFIG_EOF
402 - name: Write Safe Outputs Tools
403 run: |
404 cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
405 {
406 "description_suffixes": {
407 "add_comment": " CONSTRAINTS: Maximum 2 comment(s) can be added. Target: triggering.",
408 "create_pull_request_review_comment": " CONSTRAINTS: Maximum 5 review comment(s) can be created. Comments will be on the RIGHT side of the diff.",
409 "submit_pull_request_review": " CONSTRAINTS: Maximum 1 review(s) can be submitted."
410 },
411 "repo_params": {},
412 "dynamic_tools": []
413 }
414 GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF
415 cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
416 {
417 "add_comment": {
418 "defaultMax": 1,
419 "fields": {
420 "body": {
421 "required": true,
422 "type": "string",
423 "sanitize": true,
424 "maxLength": 65000
425 },
426 "item_number": {
427 "issueOrPRNumber": true
428 },
429 "repo": {
430 "type": "string",
431 "maxLength": 256
432 }
433 }
434 },
435 "create_pull_request_review_comment": {
436 "defaultMax": 1,
437 "fields": {
438 "body": {
439 "required": true,
440 "type": "string",
441 "sanitize": true,
442 "maxLength": 65000
443 },
444 "line": {
445 "required": true,
446 "positiveInteger": true
447 },
448 "path": {
449 "required": true,
450 "type": "string"
451 },
452 "pull_request_number": {
453 "optionalPositiveInteger": true
454 },
455 "repo": {
456 "type": "string",
457 "maxLength": 256
458 },
459 "side": {
460 "type": "string",
461 "enum": [
462 "LEFT",
463 "RIGHT"
464 ]
465 },
466 "start_line": {
467 "optionalPositiveInteger": true
468 }
469 },
470 "customValidation": "startLineLessOrEqualLine"
471 },
472 "missing_data": {
473 "defaultMax": 20,
474 "fields": {
475 "alternatives": {
476 "type": "string",
477 "sanitize": true,
478 "maxLength": 256
479 },
480 "context": {
481 "type": "string",
482 "sanitize": true,
483 "maxLength": 256
484 },
485 "data_type": {
486 "type": "string",
487 "sanitize": true,
488 "maxLength": 128
489 },
490 "reason": {
491 "type": "string",
492 "sanitize": true,
493 "maxLength": 256
494 }
495 }
496 },
497 "missing_tool": {
498 "defaultMax": 20,
499 "fields": {
500 "alternatives": {
501 "type": "string",
502 "sanitize": true,
503 "maxLength": 512
504 },
505 "reason": {
506 "required": true,
507 "type": "string",
508 "sanitize": true,
509 "maxLength": 256
510 },
511 "tool": {
512 "type": "string",
513 "sanitize": true,
514 "maxLength": 128
515 }
516 }
517 },
518 "noop": {
519 "defaultMax": 1,
520 "fields": {
521 "message": {
522 "required": true,
523 "type": "string",
524 "sanitize": true,
525 "maxLength": 65000
526 }
527 }
528 },
529 "submit_pull_request_review": {
530 "defaultMax": 1,
531 "fields": {
532 "body": {
533 "type": "string",
534 "sanitize": true,
535 "maxLength": 65000
536 },
537 "event": {
538 "type": "string",
539 "enum": [
540 "APPROVE",
541 "REQUEST_CHANGES",
542 "COMMENT"
543 ]
544 }
545 }
546 }
547 }
548 GH_AW_SAFE_OUTPUTS_VALIDATION_EOF
549 node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
550 - name: Generate Safe Outputs MCP Server Config
551 id: safe-outputs-config
552 run: |
553 # Generate a secure random API key (360 bits of entropy, 40+ chars)
554 # Mask immediately to prevent timing vulnerabilities
555 API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
556 echo "::add-mask::${API_KEY}"
557
558 PORT=3001
559
560 # Set outputs for next steps
561 {
562 echo "safe_outputs_api_key=${API_KEY}"
563 echo "safe_outputs_port=${PORT}"
564 } >> "$GITHUB_OUTPUT"
565
566 echo "Safe Outputs MCP server will run on port ${PORT}"
567
568 - name: Start Safe Outputs MCP HTTP Server
569 id: safe-outputs-start
570 env:
571 DEBUG: '*'
572 GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
573 GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
574 GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
575 GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
576 GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
577 run: |
578 # Environment variables are set above to prevent template injection
579 export DEBUG
580 export GH_AW_SAFE_OUTPUTS_PORT
581 export GH_AW_SAFE_OUTPUTS_API_KEY
582 export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
583 export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
584 export GH_AW_MCP_LOG_DIR
585
586 bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
587
588 - name: Start MCP Gateway
589 id: start-mcp-gateway
590 env:
591 GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
592 GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
593 GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
594 GITHUB_MCP_GUARD_MIN_INTEGRITY: ${{ steps.determine-automatic-lockdown.outputs.min_integrity }}
595 GITHUB_MCP_GUARD_REPOS: ${{ steps.determine-automatic-lockdown.outputs.repos }}
596 GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
597 run: |
598 set -eo pipefail
599 mkdir -p /tmp/gh-aw/mcp-config
600
601 # Export gateway environment variables for MCP config and gateway script
602 export MCP_GATEWAY_PORT="80"
603 export MCP_GATEWAY_DOMAIN="host.docker.internal"
604 MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
605 echo "::add-mask::${MCP_GATEWAY_API_KEY}"
606 export MCP_GATEWAY_API_KEY
607 export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
608 mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
609 export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
610 export DEBUG="*"
611
612 export GH_AW_ENGINE="copilot"
613 export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_GUARD_MIN_INTEGRITY -e GITHUB_MCP_GUARD_REPOS -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_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.2.4'
614
615 mkdir -p /home/runner/.copilot
616 cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
617 {
618 "mcpServers": {
619 "github": {
620 "type": "stdio",
621 "container": "ghcr.io/github/github-mcp-server:v0.32.0",
622 "env": {
623 "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
624 "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
625 "GITHUB_READ_ONLY": "1",
626 "GITHUB_TOOLSETS": "context,repos,issues,pull_requests"
627 },
628 "guard-policies": {
629 "allow-only": {
630 "min-integrity": "$GITHUB_MCP_GUARD_MIN_INTEGRITY",
631 "repos": "$GITHUB_MCP_GUARD_REPOS"
632 }
633 }
634 },
635 "safeoutputs": {
636 "type": "http",
637 "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
638 "headers": {
639 "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
640 },
641 "guard-policies": {
642 "write-sink": {
643 "accept": [
644 "*"
645 ]
646 }
647 }
648 }
649 },
650 "gateway": {
651 "port": $MCP_GATEWAY_PORT,
652 "domain": "${MCP_GATEWAY_DOMAIN}",
653 "apiKey": "${MCP_GATEWAY_API_KEY}",
654 "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
655 }
656 }
657 GH_AW_MCP_CONFIG_EOF
658 - name: Download activation artifact
659 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
660 with:
661 name: activation
662 path: /tmp/gh-aw
663 - name: Clean git credentials
664 continue-on-error: true
665 run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
666 - name: Execute GitHub Copilot CLI
667 id: agentic_execution
668 # Copilot CLI tool arguments (sorted):
669 timeout-minutes: 15
670 run: |
671 set -o pipefail
672 touch /tmp/gh-aw/agent-step-summary.md
673 # shellcheck disable=SC1003
674 sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --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,www.googleapis.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.25.0 --skip-pull --enable-api-proxy \
675 -- /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
676 env:
677 COPILOT_AGENT_RUNNER_TYPE: STANDALONE
678 COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
679 COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
680 GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
681 GH_AW_PHASE: agent
682 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
683 GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
684 GH_AW_VERSION: v0.63.1
685 GITHUB_API_URL: ${{ github.api_url }}
686 GITHUB_AW: true
687 GITHUB_HEAD_REF: ${{ github.head_ref }}
688 GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
689 GITHUB_REF_NAME: ${{ github.ref_name }}
690 GITHUB_SERVER_URL: ${{ github.server_url }}
691 GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
692 GITHUB_WORKSPACE: ${{ github.workspace }}
693 GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
694 GIT_AUTHOR_NAME: github-actions[bot]
695 GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
696 GIT_COMMITTER_NAME: github-actions[bot]
697 XDG_CONFIG_HOME: /home/runner
698 - name: Detect inference access error
699 id: detect-inference-error
700 if: always()
701 continue-on-error: true
702 run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
703 - name: Configure Git credentials
704 env:
705 REPO_NAME: ${{ github.repository }}
706 SERVER_URL: ${{ github.server_url }}
707 run: |
708 git config --global user.email "github-actions[bot]@users.noreply.github.com"
709 git config --global user.name "github-actions[bot]"
710 git config --global am.keepcr true
711 # Re-authenticate git with GitHub token
712 SERVER_URL_STRIPPED="${SERVER_URL#https://}"
713 git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
714 echo "Git configured with standard GitHub Actions identity"
715 - name: Copy Copilot session state files to logs
716 if: always()
717 continue-on-error: true
718 run: |
719 # Copy Copilot session state files to logs folder for artifact collection
720 # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them
721 SESSION_STATE_DIR="$HOME/.copilot/session-state"
722 LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs"
723
724 if [ -d "$SESSION_STATE_DIR" ]; then
725 echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR"
726 mkdir -p "$LOGS_DIR"
727 cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true
728 echo "Session state files copied successfully"
729 else
730 echo "No session-state directory found at $SESSION_STATE_DIR"
731 fi
732 - name: Stop MCP Gateway
733 if: always()
734 continue-on-error: true
735 env:
736 MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
737 MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
738 GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
739 run: |
740 bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
741 - name: Redact secrets in logs
742 if: always()
743 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
744 with:
745 script: |
746 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
747 setupGlobals(core, github, context, exec, io);
748 const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
749 await main();
750 env:
751 GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
752 SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
753 SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
754 SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
755 SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
756 - name: Append agent step summary
757 if: always()
758 run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
759 - name: Copy Safe Outputs
760 if: always()
761 env:
762 GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
763 run: |
764 mkdir -p /tmp/gh-aw
765 cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
766 - name: Ingest agent output
767 id: collect_output
768 if: always()
769 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
770 env:
771 GH_AW_SAFE_OUTPUTS: ${{ steps.set-runtime-paths.outputs.GH_AW_SAFE_OUTPUTS }}
772 GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
773 GITHUB_SERVER_URL: ${{ github.server_url }}
774 GITHUB_API_URL: ${{ github.api_url }}
775 with:
776 script: |
777 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
778 setupGlobals(core, github, context, exec, io);
779 const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
780 await main();
781 - name: Parse agent logs for step summary
782 if: always()
783 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
784 env:
785 GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
786 with:
787 script: |
788 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
789 setupGlobals(core, github, context, exec, io);
790 const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
791 await main();
792 - name: Parse MCP Gateway logs for step summary
793 if: always()
794 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
795 with:
796 script: |
797 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
798 setupGlobals(core, github, context, exec, io);
799 const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
800 await main();
801 - name: Print firewall logs
802 if: always()
803 continue-on-error: true
804 env:
805 AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
806 run: |
807 # Fix permissions on firewall logs so they can be uploaded as artifacts
808 # AWF runs with sudo, creating files owned by root
809 sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
810 # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
811 if command -v awf &> /dev/null; then
812 awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
813 else
814 echo 'AWF binary not installed, skipping firewall log summary'
815 fi
816 - name: Write agent output placeholder if missing
817 if: always()
818 run: |
819 if [ ! -f /tmp/gh-aw/agent_output.json ]; then
820 echo '{"items":[]}' > /tmp/gh-aw/agent_output.json
821 fi
822 - name: Upload agent artifacts
823 if: always()
824 continue-on-error: true
825 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
826 with:
827 name: agent
828 path: |
829 /tmp/gh-aw/aw-prompts/prompt.txt
830 /tmp/gh-aw/sandbox/agent/logs/
831 /tmp/gh-aw/redacted-urls.log
832 /tmp/gh-aw/mcp-logs/
833 /tmp/gh-aw/agent-stdio.log
834 /tmp/gh-aw/agent/
835 /tmp/gh-aw/safeoutputs.jsonl
836 /tmp/gh-aw/agent_output.json
837 if-no-files-found: ignore
838 - name: Upload firewall audit logs
839 if: always()
840 continue-on-error: true
841 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
842 with:
843 name: firewall-audit-logs
844 path: /tmp/gh-aw/sandbox/firewall/logs/
845 if-no-files-found: ignore
846 # --- Threat Detection (inline) ---
847 - name: Check if detection needed
848 id: detection_guard
849 if: always()
850 env:
851 OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
852 HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
853 run: |
854 if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
855 echo "run_detection=true" >> "$GITHUB_OUTPUT"
856 echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
857 else
858 echo "run_detection=false" >> "$GITHUB_OUTPUT"
859 echo "Detection skipped: no agent outputs or patches to analyze"
860 fi
861 - name: Clear MCP configuration for detection
862 if: always() && steps.detection_guard.outputs.run_detection == 'true'
863 run: |
864 rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
865 rm -f /home/runner/.copilot/mcp-config.json
866 rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
867 - name: Prepare threat detection files
868 if: always() && steps.detection_guard.outputs.run_detection == 'true'
869 run: |
870 mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
871 cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
872 cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
873 for f in /tmp/gh-aw/aw-*.patch; do
874 [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
875 done
876 echo "Prepared threat detection files:"
877 ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
878 - name: Setup threat detection
879 if: always() && steps.detection_guard.outputs.run_detection == 'true'
880 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
881 env:
882 WORKFLOW_NAME: "Dependabot PR Review"
883 WORKFLOW_DESCRIPTION: "Reviews and auto-approves Dependabot version bump PRs after safety validation"
884 HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
885 with:
886 script: |
887 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
888 setupGlobals(core, github, context, exec, io);
889 const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
890 await main();
891 - name: Ensure threat-detection directory and log
892 if: always() && steps.detection_guard.outputs.run_detection == 'true'
893 run: |
894 mkdir -p /tmp/gh-aw/threat-detection
895 touch /tmp/gh-aw/threat-detection/detection.log
896 - name: Execute GitHub Copilot CLI
897 if: always() && steps.detection_guard.outputs.run_detection == 'true'
898 id: detection_agentic_execution
899 # Copilot CLI tool arguments (sorted):
900 # --allow-tool shell(cat)
901 # --allow-tool shell(grep)
902 # --allow-tool shell(head)
903 # --allow-tool shell(jq)
904 # --allow-tool shell(ls)
905 # --allow-tool shell(tail)
906 # --allow-tool shell(wc)
907 timeout-minutes: 20
908 run: |
909 set -o pipefail
910 touch /tmp/gh-aw/agent-step-summary.md
911 # shellcheck disable=SC1003
912 sudo -E awf --env-all --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" --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.25.0 --skip-pull --enable-api-proxy \
913 -- /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
914 env:
915 COPILOT_AGENT_RUNNER_TYPE: STANDALONE
916 COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
917 COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
918 GH_AW_PHASE: detection
919 GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
920 GH_AW_VERSION: v0.63.1
921 GITHUB_API_URL: ${{ github.api_url }}
922 GITHUB_AW: true
923 GITHUB_HEAD_REF: ${{ github.head_ref }}
924 GITHUB_REF_NAME: ${{ github.ref_name }}
925 GITHUB_SERVER_URL: ${{ github.server_url }}
926 GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
927 GITHUB_WORKSPACE: ${{ github.workspace }}
928 GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
929 GIT_AUTHOR_NAME: github-actions[bot]
930 GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
931 GIT_COMMITTER_NAME: github-actions[bot]
932 XDG_CONFIG_HOME: /home/runner
933 - name: Parse threat detection results
934 id: parse_detection_results
935 if: always() && steps.detection_guard.outputs.run_detection == 'true'
936 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
937 with:
938 script: |
939 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
940 setupGlobals(core, github, context, exec, io);
941 const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
942 await main();
943 - name: Upload threat detection log
944 if: always() && steps.detection_guard.outputs.run_detection == 'true'
945 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
946 with:
947 name: detection
948 path: /tmp/gh-aw/threat-detection/detection.log
949 if-no-files-found: ignore
950 - name: Set detection conclusion
951 id: detection_conclusion
952 if: always()
953 env:
954 RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
955 DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
956 run: |
957 if [[ "$RUN_DETECTION" != "true" ]]; then
958 echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
959 echo "success=true" >> "$GITHUB_OUTPUT"
960 echo "Detection was not needed, marking as skipped"
961 elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
962 echo "conclusion=success" >> "$GITHUB_OUTPUT"
963 echo "success=true" >> "$GITHUB_OUTPUT"
964 echo "Detection passed successfully"
965 else
966 echo "conclusion=failure" >> "$GITHUB_OUTPUT"
967 echo "success=false" >> "$GITHUB_OUTPUT"
968 echo "Detection found issues"
969 fi
970
971 conclusion:
972 needs:
973 - activation
974 - agent
975 - safe_outputs
976 if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
977 runs-on: ubuntu-slim
978 permissions:
979 contents: read
980 discussions: write
981 issues: write
982 pull-requests: write
983 concurrency:
984 group: "gh-aw-conclusion-dependency-pr-review"
985 cancel-in-progress: false
986 outputs:
987 noop_message: ${{ steps.noop.outputs.noop_message }}
988 tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
989 total_count: ${{ steps.missing_tool.outputs.total_count }}
990 steps:
991 - name: Setup Scripts
992 uses: github/gh-aw-actions/setup@53e09ec0be6271e81a69f51ef93f37212c8834b0 # v0.63.1
993 with:
994 destination: ${{ runner.temp }}/gh-aw/actions
995 - name: Download agent output artifact
996 id: download-agent-output
997 continue-on-error: true
998 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
999 with:
1000 name: agent
1001 path: /tmp/gh-aw/
1002 - name: Setup agent output environment variable
1003 id: setup-agent-output-env
1004 if: steps.download-agent-output.outcome == 'success'
1005 run: |
1006 mkdir -p /tmp/gh-aw/
1007 find "/tmp/gh-aw/" -type f -print
1008 echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1009 - name: Process No-Op Messages
1010 id: noop
1011 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1012 env:
1013 GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1014 GH_AW_NOOP_MAX: "1"
1015 GH_AW_WORKFLOW_NAME: "Dependabot PR Review"
1016 with:
1017 github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1018 script: |
1019 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1020 setupGlobals(core, github, context, exec, io);
1021 const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs');
1022 await main();
1023 - name: Record Missing Tool
1024 id: missing_tool
1025 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1026 env:
1027 GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1028 GH_AW_WORKFLOW_NAME: "Dependabot PR Review"
1029 with:
1030 github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1031 script: |
1032 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1033 setupGlobals(core, github, context, exec, io);
1034 const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
1035 await main();
1036 - name: Handle Agent Failure
1037 id: handle_agent_failure
1038 if: always()
1039 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1040 env:
1041 GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1042 GH_AW_WORKFLOW_NAME: "Dependabot PR Review"
1043 GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1044 GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1045 GH_AW_WORKFLOW_ID: "dependency-pr-review"
1046 GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
1047 GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
1048 GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
1049 GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1050 GH_AW_GROUP_REPORTS: "false"
1051 GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
1052 GH_AW_TIMEOUT_MINUTES: "15"
1053 with:
1054 github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1055 script: |
1056 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1057 setupGlobals(core, github, context, exec, io);
1058 const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
1059 await main();
1060 - name: Handle No-Op Message
1061 id: handle_noop_message
1062 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1063 env:
1064 GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1065 GH_AW_WORKFLOW_NAME: "Dependabot PR Review"
1066 GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1067 GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1068 GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }}
1069 GH_AW_NOOP_REPORT_AS_ISSUE: "true"
1070 with:
1071 github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1072 script: |
1073 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1074 setupGlobals(core, github, context, exec, io);
1075 const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
1076 await main();
1077
1078 pre_activation:
1079 if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.id == github.repository_id
1080 runs-on: ubuntu-slim
1081 outputs:
1082 activated: ${{ steps.check_membership.outputs.is_team_member == 'true' }}
1083 matched_command: ''
1084 steps:
1085 - name: Setup Scripts
1086 uses: github/gh-aw-actions/setup@53e09ec0be6271e81a69f51ef93f37212c8834b0 # v0.63.1
1087 with:
1088 destination: ${{ runner.temp }}/gh-aw/actions
1089 - name: Check team membership for workflow
1090 id: check_membership
1091 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1092 env:
1093 GH_AW_REQUIRED_ROLES: admin,maintainer,write
1094 with:
1095 github-token: ${{ secrets.GITHUB_TOKEN }}
1096 script: |
1097 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1098 setupGlobals(core, github, context, exec, io);
1099 const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
1100 await main();
1101
1102 safe_outputs:
1103 needs: agent
1104 if: (!cancelled()) && needs.agent.result != 'skipped' && needs.agent.outputs.detection_success == 'true'
1105 runs-on: ubuntu-slim
1106 permissions:
1107 contents: read
1108 discussions: write
1109 issues: write
1110 pull-requests: write
1111 timeout-minutes: 15
1112 env:
1113 GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/dependency-pr-review"
1114 GH_AW_ENGINE_ID: "copilot"
1115 GH_AW_ENGINE_MODEL: ${{ needs.agent.outputs.model }}
1116 GH_AW_WORKFLOW_ID: "dependency-pr-review"
1117 GH_AW_WORKFLOW_NAME: "Dependabot PR Review"
1118 outputs:
1119 code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
1120 code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
1121 comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
1122 comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
1123 create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
1124 create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
1125 process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
1126 process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
1127 steps:
1128 - name: Setup Scripts
1129 uses: github/gh-aw-actions/setup@53e09ec0be6271e81a69f51ef93f37212c8834b0 # v0.63.1
1130 with:
1131 destination: ${{ runner.temp }}/gh-aw/actions
1132 - name: Download agent output artifact
1133 id: download-agent-output
1134 continue-on-error: true
1135 uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1136 with:
1137 name: agent
1138 path: /tmp/gh-aw/
1139 - name: Setup agent output environment variable
1140 id: setup-agent-output-env
1141 if: steps.download-agent-output.outcome == 'success'
1142 run: |
1143 mkdir -p /tmp/gh-aw/
1144 find "/tmp/gh-aw/" -type f -print
1145 echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_OUTPUT"
1146 - name: Configure GH_HOST for enterprise compatibility
1147 id: ghes-host-config
1148 shell: bash
1149 run: |
1150 # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1151 # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1152 GH_HOST="${GITHUB_SERVER_URL#https://}"
1153 GH_HOST="${GH_HOST#http://}"
1154 echo "GH_HOST=${GH_HOST}" >> "$GITHUB_OUTPUT"
1155 - name: Process Safe Outputs
1156 id: process_safe_outputs
1157 uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1158 env:
1159 GH_AW_AGENT_OUTPUT: ${{ steps.setup-agent-output-env.outputs.GH_AW_AGENT_OUTPUT }}
1160 GH_AW_ALLOWED_DOMAINS: "api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.snapcraft.io,archive.ubuntu.com,azure.archive.ubuntu.com,crl.geotrust.com,crl.globalsign.com,crl.identrust.com,crl.sectigo.com,crl.thawte.com,crl.usertrust.com,crl.verisign.com,crl3.digicert.com,crl4.digicert.com,crls.ssl.com,github.com,host.docker.internal,json-schema.org,json.schemastore.org,keyserver.ubuntu.com,ocsp.digicert.com,ocsp.geotrust.com,ocsp.globalsign.com,ocsp.identrust.com,ocsp.sectigo.com,ocsp.ssl.com,ocsp.thawte.com,ocsp.usertrust.com,ocsp.verisign.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,ppa.launchpad.net,raw.githubusercontent.com,registry.npmjs.org,s.symcb.com,s.symcd.com,security.ubuntu.com,telemetry.enterprise.githubcopilot.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com"
1161 GITHUB_SERVER_URL: ${{ github.server_url }}
1162 GITHUB_API_URL: ${{ github.api_url }}
1163 GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"max\":2,\"target\":\"triggering\"},\"create_pull_request_review_comment\":{\"max\":5,\"side\":\"RIGHT\"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"submit_pull_request_review\":{\"max\":1}}"
1164 with:
1165 github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1166 script: |
1167 const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1168 setupGlobals(core, github, context, exec, io);
1169 const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
1170 await main();
1171 - name: Upload Safe Output Items
1172 if: always()
1173 uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7
1174 with:
1175 name: safe-output-items
1176 path: /tmp/gh-aw/safe-output-items.jsonl
1177 if-no-files-found: ignore
1178
1179