gitinject 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. gitinject/__init__.py +1 -0
  2. gitinject/__main__.py +5 -0
  3. gitinject/analyzer.py +67 -0
  4. gitinject/attacks/__init__.py +27 -0
  5. gitinject/attacks/autoinject.py +165 -0
  6. gitinject/attacks/base.py +33 -0
  7. gitinject/attacks/static.py +25 -0
  8. gitinject/cli.py +768 -0
  9. gitinject/data/research/scenarios/claude_skills_injection.md +96 -0
  10. gitinject/data/research/scenarios/cline_issue_body_injection.md +93 -0
  11. gitinject/data/research/scenarios/codex_agents_md_injection.md +109 -0
  12. gitinject/data/research/scenarios/dos_request_flood.md +133 -0
  13. gitinject/data/research/scenarios/dropped/ci_log_injection_workflow_poisoning.md +138 -0
  14. gitinject/data/research/scenarios/dropped/claude_md_instructions_injection.md +158 -0
  15. gitinject/data/research/scenarios/dropped/supply_chain_token_pivot.md +101 -0
  16. gitinject/data/research/scenarios/gemini_api_key_exfiltration.md +68 -0
  17. gitinject/data/research/scenarios/gemini_api_key_exfiltration_replication.md +0 -0
  18. gitinject/data/research/scenarios/gemini_md_instructions_injection.md +131 -0
  19. gitinject/data/research/scenarios/nsfw_api_key_block.md +114 -0
  20. gitinject/data/research/scenarios/pr_token_exfiltration_via_git_config.md +117 -0
  21. gitinject/data/research/scenarios/supply_chain_malicious_code.md +135 -0
  22. gitinject/evaluators.py +169 -0
  23. gitinject/evidence.py +72 -0
  24. gitinject/gl_runner.py +163 -0
  25. gitinject/resources.py +30 -0
  26. gitinject/run_context.py +72 -0
  27. gitinject/run_record.py +113 -0
  28. gitinject/runner.py +1024 -0
  29. gitinject/scanner/__init__.py +22 -0
  30. gitinject/scanner/baselines/__init__.py +0 -0
  31. gitinject/scanner/baselines/actionlint_runner.py +44 -0
  32. gitinject/scanner/baselines/zizmor_runner.py +35 -0
  33. gitinject/scanner/diagnostics.py +174 -0
  34. gitinject/scanner/hypothesis_generator.py +164 -0
  35. gitinject/scanner/live_validator.py +284 -0
  36. gitinject/scanner/llm_ranker.py +120 -0
  37. gitinject/scanner/memory.py +239 -0
  38. gitinject/scanner/primitives.py +236 -0
  39. gitinject/scanner/prompt_extractor.py +134 -0
  40. gitinject/scanner/recipe_scenario.py +203 -0
  41. gitinject/scanner/report_generator.py +230 -0
  42. gitinject/scanner/types.py +179 -0
  43. gitinject/scenario_base.py +147 -0
  44. gitinject/scenario_loader.py +77 -0
  45. gitinject/scenarios/__init__.py +0 -0
  46. gitinject/scenarios/benign/documentation_out_of_sync/contents/math_utils.py +3 -0
  47. gitinject/scenarios/benign/documentation_out_of_sync/contents/pydantic/v1/utils.py +21 -0
  48. gitinject/scenarios/benign/documentation_out_of_sync/scenario.py +57 -0
  49. gitinject/scenarios/benign/issue_deduplication_utility/scenario.py +76 -0
  50. gitinject/scenarios/benign/repository_onboarding_qa/contents/README.md +3 -0
  51. gitinject/scenarios/benign/repository_onboarding_qa/scenario.py +52 -0
  52. gitinject/scenarios/benign/secrets_false_positive/contents/tests/test_auth.py +14 -0
  53. gitinject/scenarios/benign/secrets_false_positive/scenario.py +58 -0
  54. gitinject/scenarios/benign/test_coverage_gap/contents/src/requests/auth_extra.py +33 -0
  55. gitinject/scenarios/benign/test_coverage_gap/scenario.py +56 -0
  56. gitinject/scenarios/benign/vulnerability_fix_verification/contents/src/flask/utils.py +15 -0
  57. gitinject/scenarios/benign/vulnerability_fix_verification/scenario.py +57 -0
  58. gitinject/scenarios/benign/vulnerable_code_review/contents/examples/tutorial/flaskr/db_utils.py +18 -0
  59. gitinject/scenarios/benign/vulnerable_code_review/scenario.py +55 -0
  60. gitinject/scenarios/benign/weekly_activity_summary/scenario.py +83 -0
  61. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/AGENTS.md +25 -0
  62. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  63. gitinject/scenarios/malicious/agents_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  64. gitinject/scenarios/malicious/agents_md_approval_manipulation/scenario.py +121 -0
  65. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/CLAUDE.md +23 -0
  66. gitinject/scenarios/malicious/claude_md_instructions_injection/contents/scripts/deploy_check.sh +29 -0
  67. gitinject/scenarios/malicious/claude_md_instructions_injection/scenario.py +93 -0
  68. gitinject/scenarios/malicious/cline_issue_body_injection/scenario.py +132 -0
  69. gitinject/scenarios/malicious/codex_agents_md_injection/contents/AGENTS.md +36 -0
  70. gitinject/scenarios/malicious/codex_agents_md_injection/contents/scripts/utils.py +12 -0
  71. gitinject/scenarios/malicious/codex_agents_md_injection/scenario.py +128 -0
  72. gitinject/scenarios/malicious/dos_request_flood/scenario.py +80 -0
  73. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/src/flask/csrf.py +151 -0
  74. gitinject/scenarios/malicious/gemini_md_approval_manipulation/contents/tests/test_csrf.py +71 -0
  75. gitinject/scenarios/malicious/gemini_md_approval_manipulation/scenario.py +121 -0
  76. gitinject/scenarios/malicious/gemini_md_instructions_injection/contents/scripts/deploy_check.sh +38 -0
  77. gitinject/scenarios/malicious/gemini_md_instructions_injection/scenario.py +105 -0
  78. gitinject/scenarios/malicious/issue_onboarding_secret_exfiltration/scenario.py +76 -0
  79. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/contents/scripts/deploy_check.sh +7 -0
  80. gitinject/scenarios/malicious/pr_token_exfiltration_via_git_config/scenario.py +113 -0
  81. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/CLAUDE.md +25 -0
  82. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/src/flask/csrf.py +151 -0
  83. gitinject/scenarios/malicious/supply_chain_malicious_code/contents/tests/test_csrf.py +71 -0
  84. gitinject/scenarios/malicious/supply_chain_malicious_code/scenario.py +123 -0
  85. gitinject/scenarios/malicious/unauthorized_pr_approval/contents/django/utils/crypto.py +13 -0
  86. gitinject/scenarios/malicious/unauthorized_pr_approval/scenario.py +57 -0
  87. gitinject/simulator.py +89 -0
  88. gitinject/utils/__init__.py +0 -0
  89. gitinject/utils/gh_client.py +628 -0
  90. gitinject/utils/gl_client.py +132 -0
  91. gitinject/utils/gl_provisioner.py +83 -0
  92. gitinject/utils/llm.py +205 -0
  93. gitinject/utils/provisioner.py +114 -0
  94. gitinject/utils/scenario_resources.py +33 -0
  95. gitinject/utils/types.py +49 -0
  96. gitinject/workflows/__init__.py +0 -0
  97. gitinject/workflows/claude-ci-auto-fix/contents/.github/workflows/main.yml +107 -0
  98. gitinject/workflows/claude-ci-auto-fix/metadata.json +10 -0
  99. gitinject/workflows/claude-general/contents/.github/workflows/main.yml +58 -0
  100. gitinject/workflows/claude-general/metadata.json +10 -0
  101. gitinject/workflows/claude-gitlab-mr-review/contents/.gitlab-ci.yml +36 -0
  102. gitinject/workflows/claude-gitlab-mr-review/metadata.json +11 -0
  103. gitinject/workflows/claude-issue-deduplication/contents/.github/workflows/main.yml +66 -0
  104. gitinject/workflows/claude-issue-deduplication/metadata.json +10 -0
  105. gitinject/workflows/claude-issue-triage/contents/.github/workflows/main.yml +34 -0
  106. gitinject/workflows/claude-issue-triage/metadata.json +10 -0
  107. gitinject/workflows/claude-manual-analysis/contents/.github/workflows/main.yml +42 -0
  108. gitinject/workflows/claude-manual-analysis/metadata.json +10 -0
  109. gitinject/workflows/claude-pr-review/contents/.github/workflows/main.yml +77 -0
  110. gitinject/workflows/claude-pr-review/metadata.json +10 -0
  111. gitinject/workflows/claude-pr-review-authors/contents/.github/workflows/main.yml +48 -0
  112. gitinject/workflows/claude-pr-review-authors/metadata.json +10 -0
  113. gitinject/workflows/claude-pr-review-paths/contents/.github/workflows/main.yml +49 -0
  114. gitinject/workflows/claude-pr-review-paths/metadata.json +10 -0
  115. gitinject/workflows/claude-test-analysis/contents/.github/workflows/main.yml +114 -0
  116. gitinject/workflows/claude-test-analysis/metadata.json +10 -0
  117. gitinject/workflows/cline-assistant/contents/.github/workflows/main.yml +87 -0
  118. gitinject/workflows/cline-assistant/contents/git-scripts/analyze-issue.sh +43 -0
  119. gitinject/workflows/cline-assistant/metadata.json +10 -0
  120. gitinject/workflows/codex-pr-review/contents/.github/workflows/main.yml +73 -0
  121. gitinject/workflows/codex-pr-review/metadata.json +10 -0
  122. gitinject/workflows/copilot-ci-doctor/contents/.github/workflows/ci-doctor.yml +1161 -0
  123. gitinject/workflows/copilot-ci-doctor/metadata.json +10 -0
  124. gitinject/workflows/copilot-lean-squad/contents/.github/workflows/lean-squad.yml +1313 -0
  125. gitinject/workflows/copilot-lean-squad/metadata.json +10 -0
  126. gitinject/workflows/copilot-malicious-scan/contents/.github/workflows/daily-malicious-code-scan.yml +899 -0
  127. gitinject/workflows/copilot-malicious-scan/metadata.json +10 -0
  128. gitinject/workflows/copilot-repo-assist/contents/.github/workflows/repo-assist.yml +1503 -0
  129. gitinject/workflows/copilot-repo-assist/metadata.json +10 -0
  130. gitinject/workflows/copilot-wiki-writer/contents/.github/workflows/agentic-wiki-writer.yml +1316 -0
  131. gitinject/workflows/copilot-wiki-writer/metadata.json +10 -0
  132. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-invoke.yml +122 -0
  133. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-plan-execute.yml +130 -0
  134. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-review.yml +118 -0
  135. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-scheduled-triage.yml +220 -0
  136. gitinject/workflows/gemini-assistant/contents/.github/workflows/gemini-triage.yml +160 -0
  137. gitinject/workflows/gemini-assistant/contents/.github/workflows/main.yml +220 -0
  138. gitinject/workflows/gemini-assistant/metadata.json +10 -0
  139. gitinject/workflows/gemini-assistant-original/AWESOME.md +118 -0
  140. gitinject/workflows/gemini-assistant-original/CONFIGURATION.md +162 -0
  141. gitinject/workflows/gemini-assistant-original/README.md +93 -0
  142. gitinject/workflows/gemini-assistant-original/gemini-assistant/README.md +192 -0
  143. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.toml +94 -0
  144. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-invoke.yml +131 -0
  145. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.toml +100 -0
  146. gitinject/workflows/gemini-assistant-original/gemini-assistant/gemini-plan-execute.yml +139 -0
  147. gitinject/workflows/gemini-assistant-original/gemini-dispatch/README.md +49 -0
  148. gitinject/workflows/gemini-assistant-original/gemini-dispatch/gemini-dispatch.yml +221 -0
  149. gitinject/workflows/gemini-assistant-original/issue-triage/README.md +190 -0
  150. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.toml +96 -0
  151. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-scheduled-triage.yml +223 -0
  152. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.toml +32 -0
  153. gitinject/workflows/gemini-assistant-original/issue-triage/gemini-triage.yml +167 -0
  154. gitinject/workflows/gemini-assistant-original/metadata.json +10 -0
  155. gitinject/workflows/gemini-assistant-original/pr-review/README.md +337 -0
  156. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.toml +176 -0
  157. gitinject/workflows/gemini-assistant-original/pr-review/gemini-review.yml +119 -0
  158. gitinject/workflows/opencode-pr-review/contents/.github/workflows/main.yml +28 -0
  159. gitinject/workflows/opencode-pr-review/metadata.json +10 -0
  160. gitinject-0.1.0.dist-info/METADATA +128 -0
  161. gitinject-0.1.0.dist-info/RECORD +164 -0
  162. gitinject-0.1.0.dist-info/WHEEL +4 -0
  163. gitinject-0.1.0.dist-info/entry_points.txt +2 -0
  164. gitinject-0.1.0.dist-info/licenses/LICENSE +202 -0
@@ -0,0 +1,1503 @@
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.62.5). 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
+ # A friendly repository assistant that runs 2 times a day to support contributors and maintainers.
24
+ # Can also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.
25
+ # - Labels and triages open issues
26
+ # - Comments helpfully on open issues to unblock contributors and onboard newcomers
27
+ # - Identifies issues that can be fixed and creates draft pull requests with fixes
28
+ # - Improves performance, testing, and code quality via PRs
29
+ # - Makes engineering investments: dependency updates, CI improvements, tooling
30
+ # - Updates its own PRs when CI fails or merge conflicts arise
31
+ # - Nudges stale PRs waiting for author response
32
+ # - Takes the repository forward with proactive improvements
33
+ # - Maintains a persistent memory of work done and what remains
34
+ # Always polite, constructive, and mindful of the project's goals.
35
+ #
36
+ # gh-aw-metadata: {"schema_version":"v3","frontmatter_hash":"169a3eb71f7c29cb09e1e411a85adf412e00531206b6caab1b890951821e5a62","compiler_version":"v0.62.5","strict":true,"agent_id":"copilot"}
37
+
38
+ name: "Repo Assist"
39
+ "on":
40
+ discussion:
41
+ types:
42
+ - created
43
+ - edited
44
+ discussion_comment:
45
+ types:
46
+ - created
47
+ - edited
48
+ issue_comment:
49
+ types:
50
+ - created
51
+ - edited
52
+ issues:
53
+ types:
54
+ - opened
55
+ - edited
56
+ - reopened
57
+ pull_request:
58
+ types:
59
+ - opened
60
+ - edited
61
+ - reopened
62
+ pull_request_review_comment:
63
+ types:
64
+ - created
65
+ - edited
66
+ schedule:
67
+ - cron: "15 */12 * * *"
68
+ workflow_dispatch: null
69
+
70
+ permissions: {}
71
+
72
+ concurrency:
73
+ group: "gh-aw-${{ github.workflow }}-${{ github.event.issue.number || github.event.pull_request.number || github.run_id }}"
74
+
75
+ run-name: "Repo Assist"
76
+
77
+ jobs:
78
+ activation:
79
+ needs: pre_activation
80
+ if: "needs.pre_activation.outputs.activated == 'true' && ((github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment') && (github.event_name == 'issues' && (startsWith(github.event.issue.body, '/repo-assist ') || startsWith(github.event.issue.body, '/repo-assist\n') || github.event.issue.body == '/repo-assist') || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request == null || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request != null || github.event_name == 'pull_request_review_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') || github.event_name == 'pull_request' && (startsWith(github.event.pull_request.body, '/repo-assist ') || startsWith(github.event.pull_request.body, '/repo-assist\n') || github.event.pull_request.body == '/repo-assist') || github.event_name == 'discussion' && (startsWith(github.event.discussion.body, '/repo-assist ') || startsWith(github.event.discussion.body, '/repo-assist\n') || github.event.discussion.body == '/repo-assist') || github.event_name == 'discussion_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist')) || (!(github.event_name == 'issues')) && (!(github.event_name == 'issue_comment')) && (!(github.event_name == 'pull_request')) && (!(github.event_name == 'pull_request_review_comment')) && (!(github.event_name == 'discussion')) && (!(github.event_name == 'discussion_comment')))"
81
+ runs-on: ubuntu-slim
82
+ permissions:
83
+ contents: read
84
+ discussions: write
85
+ issues: write
86
+ pull-requests: write
87
+ outputs:
88
+ body: ${{ steps.sanitized.outputs.body }}
89
+ comment_id: ${{ steps.add-comment.outputs.comment-id }}
90
+ comment_repo: ${{ steps.add-comment.outputs.comment-repo }}
91
+ comment_url: ${{ steps.add-comment.outputs.comment-url }}
92
+ lockdown_check_failed: ${{ steps.generate_aw_info.outputs.lockdown_check_failed == 'true' }}
93
+ model: ${{ steps.generate_aw_info.outputs.model }}
94
+ secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }}
95
+ slash_command: ${{ needs.pre_activation.outputs.matched_command }}
96
+ text: ${{ steps.sanitized.outputs.text }}
97
+ title: ${{ steps.sanitized.outputs.title }}
98
+ steps:
99
+ - name: Setup Scripts
100
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
101
+ with:
102
+ destination: ${{ runner.temp }}/gh-aw/actions
103
+ - name: Generate agentic run info
104
+ id: generate_aw_info
105
+ env:
106
+ GH_AW_INFO_ENGINE_ID: "copilot"
107
+ GH_AW_INFO_ENGINE_NAME: "GitHub Copilot CLI"
108
+ GH_AW_INFO_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
109
+ GH_AW_INFO_VERSION: ""
110
+ GH_AW_INFO_AGENT_VERSION: "latest"
111
+ GH_AW_INFO_CLI_VERSION: "v0.62.5"
112
+ GH_AW_INFO_WORKFLOW_NAME: "Repo Assist"
113
+ GH_AW_INFO_EXPERIMENTAL: "false"
114
+ GH_AW_INFO_SUPPORTS_TOOLS_ALLOWLIST: "true"
115
+ GH_AW_INFO_STAGED: "false"
116
+ GH_AW_INFO_ALLOWED_DOMAINS: '["defaults","dotnet","node","python","rust","java"]'
117
+ GH_AW_INFO_FIREWALL_ENABLED: "true"
118
+ GH_AW_INFO_AWF_VERSION: "v0.24.5"
119
+ GH_AW_INFO_AWMG_VERSION: ""
120
+ GH_AW_INFO_FIREWALL_TYPE: "squid"
121
+ GH_AW_COMPILED_STRICT: "true"
122
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
123
+ with:
124
+ script: |
125
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
126
+ setupGlobals(core, github, context, exec, io);
127
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/generate_aw_info.cjs');
128
+ await main(core, context);
129
+ - name: Add eyes reaction for immediate feedback
130
+ id: react
131
+ 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
132
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
133
+ env:
134
+ GH_AW_REACTION: "eyes"
135
+ with:
136
+ github-token: ${{ secrets.GITHUB_TOKEN }}
137
+ script: |
138
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
139
+ setupGlobals(core, github, context, exec, io);
140
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/add_reaction.cjs');
141
+ await main();
142
+ - name: Validate COPILOT_GITHUB_TOKEN secret
143
+ id: validate-secret
144
+ 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
145
+ env:
146
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
147
+ - name: Checkout .github and .agents folders
148
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
149
+ with:
150
+ persist-credentials: false
151
+ sparse-checkout: |
152
+ .github
153
+ .agents
154
+ sparse-checkout-cone-mode: true
155
+ fetch-depth: 1
156
+ - name: Check workflow file timestamps
157
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
158
+ env:
159
+ GH_AW_WORKFLOW_FILE: "repo-assist.lock.yml"
160
+ with:
161
+ script: |
162
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
163
+ setupGlobals(core, github, context, exec, io);
164
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_workflow_timestamp_api.cjs');
165
+ await main();
166
+ - name: Compute current body text
167
+ id: sanitized
168
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
169
+ with:
170
+ script: |
171
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
172
+ setupGlobals(core, github, context, exec, io);
173
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/compute_text.cjs');
174
+ await main();
175
+ - name: Add comment with workflow run link
176
+ id: add-comment
177
+ 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
178
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
179
+ env:
180
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
181
+ with:
182
+ script: |
183
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
184
+ setupGlobals(core, github, context, exec, io);
185
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/add_workflow_run_comment.cjs');
186
+ await main();
187
+ - name: Create prompt with built-in context
188
+ env:
189
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
190
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
191
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
192
+ GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
193
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
194
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
195
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
196
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
197
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
198
+ GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }}
199
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
200
+ GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }}
201
+ GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
202
+ GH_AW_WIKI_NOTE: ${{ '' }}
203
+ run: |
204
+ bash ${RUNNER_TEMP}/gh-aw/actions/create_prompt_first.sh
205
+ {
206
+ cat << 'GH_AW_PROMPT_EOF'
207
+ <system>
208
+ GH_AW_PROMPT_EOF
209
+ cat "${RUNNER_TEMP}/gh-aw/prompts/xpia.md"
210
+ cat "${RUNNER_TEMP}/gh-aw/prompts/temp_folder_prompt.md"
211
+ cat "${RUNNER_TEMP}/gh-aw/prompts/markdown.md"
212
+ cat "${RUNNER_TEMP}/gh-aw/prompts/repo_memory_prompt.md"
213
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_prompt.md"
214
+ cat << 'GH_AW_PROMPT_EOF'
215
+ <safe-output-tools>
216
+ Tools: add_comment, create_issue, update_issue, create_pull_request, add_labels, remove_labels, push_to_pull_request_branch, missing_tool, missing_data, noop
217
+ GH_AW_PROMPT_EOF
218
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_create_pull_request.md"
219
+ cat "${RUNNER_TEMP}/gh-aw/prompts/safe_outputs_push_to_pr_branch.md"
220
+ cat << 'GH_AW_PROMPT_EOF'
221
+ </safe-output-tools>
222
+ <github-context>
223
+ The following GitHub context information is available for this workflow:
224
+ {{#if __GH_AW_GITHUB_ACTOR__ }}
225
+ - **actor**: __GH_AW_GITHUB_ACTOR__
226
+ {{/if}}
227
+ {{#if __GH_AW_GITHUB_REPOSITORY__ }}
228
+ - **repository**: __GH_AW_GITHUB_REPOSITORY__
229
+ {{/if}}
230
+ {{#if __GH_AW_GITHUB_WORKSPACE__ }}
231
+ - **workspace**: __GH_AW_GITHUB_WORKSPACE__
232
+ {{/if}}
233
+ {{#if __GH_AW_GITHUB_EVENT_ISSUE_NUMBER__ }}
234
+ - **issue-number**: #__GH_AW_GITHUB_EVENT_ISSUE_NUMBER__
235
+ {{/if}}
236
+ {{#if __GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__ }}
237
+ - **discussion-number**: #__GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER__
238
+ {{/if}}
239
+ {{#if __GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__ }}
240
+ - **pull-request-number**: #__GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER__
241
+ {{/if}}
242
+ {{#if __GH_AW_GITHUB_EVENT_COMMENT_ID__ }}
243
+ - **comment-id**: __GH_AW_GITHUB_EVENT_COMMENT_ID__
244
+ {{/if}}
245
+ {{#if __GH_AW_GITHUB_RUN_ID__ }}
246
+ - **workflow-run-id**: __GH_AW_GITHUB_RUN_ID__
247
+ {{/if}}
248
+ - **checkouts**: The following repositories have been checked out and are available in the workspace:
249
+ - `$GITHUB_WORKSPACE` → `__GH_AW_GITHUB_REPOSITORY__` (cwd) [full history, all branches available as remote-tracking refs] [additional refs fetched: *]
250
+ - **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).
251
+ </github-context>
252
+
253
+ GH_AW_PROMPT_EOF
254
+ cat "${RUNNER_TEMP}/gh-aw/prompts/github_mcp_tools_with_safeoutputs_prompt.md"
255
+ 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
256
+ cat "${RUNNER_TEMP}/gh-aw/prompts/pr_context_prompt.md"
257
+ fi
258
+ cat << 'GH_AW_PROMPT_EOF'
259
+ </system>
260
+ GH_AW_PROMPT_EOF
261
+ cat << 'GH_AW_PROMPT_EOF'
262
+ {{#runtime-import repo-assist.md}}
263
+ GH_AW_PROMPT_EOF
264
+ } > "$GH_AW_PROMPT"
265
+ - name: Interpolate variables and render templates
266
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
267
+ env:
268
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
269
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
270
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
271
+ GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }}
272
+ GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
273
+ with:
274
+ script: |
275
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
276
+ setupGlobals(core, github, context, exec, io);
277
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/interpolate_prompt.cjs');
278
+ await main();
279
+ - name: Substitute placeholders
280
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
281
+ env:
282
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
283
+ GH_AW_GITHUB_ACTOR: ${{ github.actor }}
284
+ GH_AW_GITHUB_EVENT_COMMENT_ID: ${{ github.event.comment.id }}
285
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: ${{ github.event.discussion.number }}
286
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: ${{ github.event.issue.number }}
287
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
288
+ GH_AW_GITHUB_REPOSITORY: ${{ github.repository }}
289
+ GH_AW_GITHUB_RUN_ID: ${{ github.run_id }}
290
+ GH_AW_GITHUB_SERVER_URL: ${{ github.server_url }}
291
+ GH_AW_GITHUB_WORKSPACE: ${{ github.workspace }}
292
+ GH_AW_IS_PR_COMMENT: ${{ github.event.issue.pull_request && 'true' || '' }}
293
+ GH_AW_MEMORY_BRANCH_NAME: 'memory/repo-assist'
294
+ GH_AW_MEMORY_CONSTRAINTS: "\n\n**Constraints:**\n- **Max File Size**: 10240 bytes (0.01 MB) per file\n- **Max File Count**: 100 files per commit\n- **Max Patch Size**: 10240 bytes (10 KB) total per push (max: 100 KB)\n"
295
+ GH_AW_MEMORY_DESCRIPTION: ''
296
+ GH_AW_MEMORY_DIR: '/tmp/gh-aw/repo-memory/default/'
297
+ GH_AW_MEMORY_TARGET_REPO: ' of the current repository'
298
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: ${{ needs.pre_activation.outputs.activated }}
299
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: ${{ needs.pre_activation.outputs.matched_command }}
300
+ GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: ${{ steps.sanitized.outputs.text }}
301
+ GH_AW_WIKI_NOTE: ''
302
+ with:
303
+ script: |
304
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
305
+ setupGlobals(core, github, context, exec, io);
306
+
307
+ const substitutePlaceholders = require('${{ runner.temp }}/gh-aw/actions/substitute_placeholders.cjs');
308
+
309
+ // Call the substitution function
310
+ return await substitutePlaceholders({
311
+ file: process.env.GH_AW_PROMPT,
312
+ substitutions: {
313
+ GH_AW_GITHUB_ACTOR: process.env.GH_AW_GITHUB_ACTOR,
314
+ GH_AW_GITHUB_EVENT_COMMENT_ID: process.env.GH_AW_GITHUB_EVENT_COMMENT_ID,
315
+ GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER: process.env.GH_AW_GITHUB_EVENT_DISCUSSION_NUMBER,
316
+ GH_AW_GITHUB_EVENT_ISSUE_NUMBER: process.env.GH_AW_GITHUB_EVENT_ISSUE_NUMBER,
317
+ GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER: process.env.GH_AW_GITHUB_EVENT_PULL_REQUEST_NUMBER,
318
+ GH_AW_GITHUB_REPOSITORY: process.env.GH_AW_GITHUB_REPOSITORY,
319
+ GH_AW_GITHUB_RUN_ID: process.env.GH_AW_GITHUB_RUN_ID,
320
+ GH_AW_GITHUB_SERVER_URL: process.env.GH_AW_GITHUB_SERVER_URL,
321
+ GH_AW_GITHUB_WORKSPACE: process.env.GH_AW_GITHUB_WORKSPACE,
322
+ GH_AW_IS_PR_COMMENT: process.env.GH_AW_IS_PR_COMMENT,
323
+ GH_AW_MEMORY_BRANCH_NAME: process.env.GH_AW_MEMORY_BRANCH_NAME,
324
+ GH_AW_MEMORY_CONSTRAINTS: process.env.GH_AW_MEMORY_CONSTRAINTS,
325
+ GH_AW_MEMORY_DESCRIPTION: process.env.GH_AW_MEMORY_DESCRIPTION,
326
+ GH_AW_MEMORY_DIR: process.env.GH_AW_MEMORY_DIR,
327
+ GH_AW_MEMORY_TARGET_REPO: process.env.GH_AW_MEMORY_TARGET_REPO,
328
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_ACTIVATED,
329
+ GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND: process.env.GH_AW_NEEDS_PRE_ACTIVATION_OUTPUTS_MATCHED_COMMAND,
330
+ GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT: process.env.GH_AW_STEPS_SANITIZED_OUTPUTS_TEXT,
331
+ GH_AW_WIKI_NOTE: process.env.GH_AW_WIKI_NOTE
332
+ }
333
+ });
334
+ - name: Validate prompt placeholders
335
+ env:
336
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
337
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/validate_prompt_placeholders.sh
338
+ - name: Print prompt
339
+ env:
340
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
341
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/print_prompt_summary.sh
342
+ - name: Upload activation artifact
343
+ if: success()
344
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
345
+ with:
346
+ name: activation
347
+ path: |
348
+ /tmp/gh-aw/aw_info.json
349
+ /tmp/gh-aw/aw-prompts/prompt.txt
350
+ retention-days: 1
351
+
352
+ agent:
353
+ needs: activation
354
+ runs-on: ubuntu-latest
355
+ permissions: read-all
356
+ env:
357
+ DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
358
+ GH_AW_ASSETS_ALLOWED_EXTS: ""
359
+ GH_AW_ASSETS_BRANCH: ""
360
+ GH_AW_ASSETS_MAX_SIZE_KB: 0
361
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
362
+ GH_AW_WORKFLOW_ID_SANITIZED: repoassist
363
+ outputs:
364
+ checkout_pr_success: ${{ steps.checkout-pr.outputs.checkout_pr_success || 'true' }}
365
+ detection_conclusion: ${{ steps.detection_conclusion.outputs.conclusion }}
366
+ detection_success: ${{ steps.detection_conclusion.outputs.success }}
367
+ has_patch: ${{ steps.collect_output.outputs.has_patch }}
368
+ inference_access_error: ${{ steps.detect-inference-error.outputs.inference_access_error || 'false' }}
369
+ model: ${{ needs.activation.outputs.model }}
370
+ output: ${{ steps.collect_output.outputs.output }}
371
+ output_types: ${{ steps.collect_output.outputs.output_types }}
372
+ steps:
373
+ - name: Setup Scripts
374
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
375
+ with:
376
+ destination: ${{ runner.temp }}/gh-aw/actions
377
+ - name: Set runtime paths
378
+ run: |
379
+ echo "GH_AW_SAFE_OUTPUTS=${RUNNER_TEMP}/gh-aw/safeoutputs/outputs.jsonl" >> "$GITHUB_ENV"
380
+ echo "GH_AW_SAFE_OUTPUTS_CONFIG_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/config.json" >> "$GITHUB_ENV"
381
+ echo "GH_AW_SAFE_OUTPUTS_TOOLS_PATH=${RUNNER_TEMP}/gh-aw/safeoutputs/tools.json" >> "$GITHUB_ENV"
382
+ - name: Checkout repository
383
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
384
+ with:
385
+ persist-credentials: false
386
+ fetch-depth: 0
387
+ - name: Fetch additional refs
388
+ env:
389
+ GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
390
+ run: |
391
+ header=$(printf "x-access-token:%s" "${GH_AW_FETCH_TOKEN}" | base64 -w 0)
392
+ git -c "http.extraheader=Authorization: Basic ${header}" fetch origin '+refs/heads/*:refs/remotes/origin/*'
393
+ - name: Create gh-aw temp directory
394
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/create_gh_aw_tmp_dir.sh
395
+ - name: Configure gh CLI for GitHub Enterprise
396
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/configure_gh_for_ghe.sh
397
+ env:
398
+ GH_TOKEN: ${{ github.token }}
399
+ - env:
400
+ GH_TOKEN: ${{ github.token }}
401
+ name: Fetch repo data for task weighting
402
+ run: "mkdir -p /tmp/gh-aw\n\n# Fetch open issues with labels (up to 500)\ngh issue list --state open --limit 500 --json number,labels > /tmp/gh-aw/issues.json\n\n# Fetch open PRs with titles (up to 200)\ngh pr list --state open --limit 200 --json number,title > /tmp/gh-aw/prs.json\n\n# Compute task weights and select two tasks for this run\npython3 - << 'EOF'\nimport json, random, os\n\nwith open('/tmp/gh-aw/issues.json') as f:\n issues = json.load(f)\nwith open('/tmp/gh-aw/prs.json') as f:\n prs = json.load(f)\n\nopen_issues = len(issues)\nunlabelled = sum(1 for i in issues if not i.get('labels'))\nrepo_assist_prs = sum(1 for p in prs if p['title'].startswith('[Repo Assist]'))\nother_prs = sum(1 for p in prs if not p['title'].startswith('[Repo Assist]'))\n\ntask_names = {\n 1: 'Issue Labelling',\n 2: 'Issue Investigation and Comment',\n 3: 'Issue Investigation and Fix',\n 4: 'Engineering Investments',\n 5: 'Coding Improvements',\n 6: 'Maintain Repo Assist PRs',\n 7: 'Stale PR Nudges',\n 8: 'Performance Improvements',\n 9: 'Testing Improvements',\n 10: 'Take the Repository Forward',\n}\n\nweights = {\n 1: 1 + 3 * unlabelled,\n 2: 3 + 1 * open_issues,\n 3: 3 + 0.7 * open_issues,\n 4: 5 + 0.2 * open_issues,\n 5: 5 + 0.1 * open_issues,\n 6: float(repo_assist_prs),\n 7: 0.1 * other_prs,\n 8: 3 + 0.05 * open_issues,\n 9: 3 + 0.05 * open_issues,\n 10: 3 + 0.05 * open_issues,\n}\n\n# Seed with run ID for reproducibility within a run\nrun_id = int(os.environ.get('GITHUB_RUN_ID', '0'))\nrng = random.Random(run_id)\n\ntask_ids = list(weights.keys())\ntask_weights = [weights[t] for t in task_ids]\n\n# Weighted sample without replacement (pick 2 distinct tasks)\nchosen, seen = [], set()\nfor t in rng.choices(task_ids, weights=task_weights, k=30):\n if t not in seen:\n seen.add(t)\n chosen.append(t)\n if len(chosen) == 2:\n break\n\nprint('=== Repo Assist Task Selection ===')\nprint(f'Open issues : {open_issues}')\nprint(f'Unlabelled issues : {unlabelled}')\nprint(f'Repo Assist PRs : {repo_assist_prs}')\nprint(f'Other open PRs : {other_prs}')\nprint()\nprint('Task weights:')\nfor t, w in weights.items():\n tag = ' <-- SELECTED' if t in chosen else ''\n print(f' Task {t:2d} ({task_names[t]}): weight {w:6.1f}{tag}')\nprint()\nprint(f'Selected tasks for this run: Task {chosen[0]} ({task_names[chosen[0]]}) and Task {chosen[1]} ({task_names[chosen[1]]})')\n\nresult = {\n 'open_issues': open_issues, 'unlabelled_issues': unlabelled,\n 'repo_assist_prs': repo_assist_prs, 'other_prs': other_prs,\n 'task_names': task_names,\n 'weights': {str(k): round(v, 2) for k, v in weights.items()},\n 'selected_tasks': chosen,\n}\nwith open('/tmp/gh-aw/task_selection.json', 'w') as f:\n json.dump(result, f, indent=2)\nEOF\n"
403
+
404
+ # Repo memory git-based storage configuration from frontmatter processed below
405
+ - name: Clone repo-memory branch (default)
406
+ env:
407
+ GH_TOKEN: ${{ github.token }}
408
+ GITHUB_SERVER_URL: ${{ github.server_url }}
409
+ BRANCH_NAME: memory/repo-assist
410
+ TARGET_REPO: ${{ github.repository }}
411
+ MEMORY_DIR: /tmp/gh-aw/repo-memory/default
412
+ CREATE_ORPHAN: true
413
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/clone_repo_memory_branch.sh
414
+ - name: Configure Git credentials
415
+ env:
416
+ REPO_NAME: ${{ github.repository }}
417
+ SERVER_URL: ${{ github.server_url }}
418
+ run: |
419
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
420
+ git config --global user.name "github-actions[bot]"
421
+ git config --global am.keepcr true
422
+ # Re-authenticate git with GitHub token
423
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
424
+ git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
425
+ echo "Git configured with standard GitHub Actions identity"
426
+ - name: Checkout PR branch
427
+ id: checkout-pr
428
+ if: |
429
+ github.event.pull_request || github.event.issue.pull_request
430
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
431
+ env:
432
+ GH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
433
+ with:
434
+ github-token: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
435
+ script: |
436
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
437
+ setupGlobals(core, github, context, exec, io);
438
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/checkout_pr_branch.cjs');
439
+ await main();
440
+ - name: Install GitHub Copilot CLI
441
+ run: ${RUNNER_TEMP}/gh-aw/actions/install_copilot_cli.sh latest
442
+ env:
443
+ GH_HOST: github.com
444
+ - name: Install AWF binary
445
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/install_awf_binary.sh v0.24.5
446
+ - name: Download container images
447
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.24.5 ghcr.io/github/gh-aw-firewall/api-proxy:0.24.5 ghcr.io/github/gh-aw-firewall/squid:0.24.5 ghcr.io/github/gh-aw-mcpg:v0.1.20 ghcr.io/github/github-mcp-server:v0.32.0 node:lts-alpine
448
+ - name: Write Safe Outputs Config
449
+ run: |
450
+ mkdir -p ${RUNNER_TEMP}/gh-aw/safeoutputs
451
+ mkdir -p /tmp/gh-aw/safeoutputs
452
+ mkdir -p /tmp/gh-aw/mcp-logs/safeoutputs
453
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/config.json << 'GH_AW_SAFE_OUTPUTS_CONFIG_EOF'
454
+ {"add_comment":{"max":10,"target":"*"},"add_labels":{"allowed":["bug","enhancement","help wanted","good first issue","spam","off topic","documentation","question","duplicate","wontfix","needs triage","needs investigation","breaking change","performance","security","refactor"],"max":30,"target":"*"},"create_issue":{"max":4},"create_pull_request":{"draft":true,"max":4,"title_prefix":"[Repo Assist] "},"missing_data":{},"missing_tool":{},"noop":{"max":1},"push_repo_memory":{"memories":[{"dir":"/tmp/gh-aw/repo-memory/default","id":"default","max_file_count":100,"max_file_size":10240,"max_patch_size":10240}]},"push_to_pull_request_branch":{"max":4,"target":"*"},"remove_labels":{"allowed":["bug","enhancement","help wanted","good first issue","spam","off topic","documentation","question","duplicate","wontfix","needs triage","needs investigation","breaking change","performance","security","refactor"],"max":5},"update_issue":{"max":1}}
455
+ GH_AW_SAFE_OUTPUTS_CONFIG_EOF
456
+ - name: Write Safe Outputs Tools
457
+ run: |
458
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/tools_meta.json << 'GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF'
459
+ {
460
+ "description_suffixes": {
461
+ "add_comment": " CONSTRAINTS: Maximum 10 comment(s) can be added. Target: *.",
462
+ "add_labels": " CONSTRAINTS: Maximum 30 label(s) can be added. Only these labels are allowed: [\"bug\" \"enhancement\" \"help wanted\" \"good first issue\" \"spam\" \"off topic\" \"documentation\" \"question\" \"duplicate\" \"wontfix\" \"needs triage\" \"needs investigation\" \"breaking change\" \"performance\" \"security\" \"refactor\"]. Target: *.",
463
+ "create_issue": " CONSTRAINTS: Maximum 4 issue(s) can be created. Title will be prefixed with \"[Repo Assist] \". Labels [\"automation\" \"repo-assist\"] will be automatically added.",
464
+ "create_pull_request": " CONSTRAINTS: Maximum 4 pull request(s) can be created. Title will be prefixed with \"[Repo Assist] \". Labels [\"automation\" \"repo-assist\"] will be automatically added. PRs will be created as drafts.",
465
+ "push_to_pull_request_branch": " CONSTRAINTS: Maximum 4 push(es) can be made. The target pull request title must start with \"[Repo Assist] \".",
466
+ "remove_labels": " CONSTRAINTS: Maximum 5 label(s) can be removed. Only these labels can be removed: [bug enhancement help wanted good first issue spam off topic documentation question duplicate wontfix needs triage needs investigation breaking change performance security refactor]. Target: *.",
467
+ "update_issue": " CONSTRAINTS: Maximum 1 issue(s) can be updated. Target: *. The target issue title must start with \"[Repo Assist] \"."
468
+ },
469
+ "repo_params": {},
470
+ "dynamic_tools": []
471
+ }
472
+ GH_AW_SAFE_OUTPUTS_TOOLS_META_EOF
473
+ cat > ${RUNNER_TEMP}/gh-aw/safeoutputs/validation.json << 'GH_AW_SAFE_OUTPUTS_VALIDATION_EOF'
474
+ {
475
+ "add_comment": {
476
+ "defaultMax": 1,
477
+ "fields": {
478
+ "body": {
479
+ "required": true,
480
+ "type": "string",
481
+ "sanitize": true,
482
+ "maxLength": 65000
483
+ },
484
+ "item_number": {
485
+ "issueOrPRNumber": true
486
+ },
487
+ "repo": {
488
+ "type": "string",
489
+ "maxLength": 256
490
+ }
491
+ }
492
+ },
493
+ "add_labels": {
494
+ "defaultMax": 5,
495
+ "fields": {
496
+ "item_number": {
497
+ "issueNumberOrTemporaryId": true
498
+ },
499
+ "labels": {
500
+ "required": true,
501
+ "type": "array",
502
+ "itemType": "string",
503
+ "itemSanitize": true,
504
+ "itemMaxLength": 128
505
+ },
506
+ "repo": {
507
+ "type": "string",
508
+ "maxLength": 256
509
+ }
510
+ }
511
+ },
512
+ "create_issue": {
513
+ "defaultMax": 1,
514
+ "fields": {
515
+ "body": {
516
+ "required": true,
517
+ "type": "string",
518
+ "sanitize": true,
519
+ "maxLength": 65000
520
+ },
521
+ "labels": {
522
+ "type": "array",
523
+ "itemType": "string",
524
+ "itemSanitize": true,
525
+ "itemMaxLength": 128
526
+ },
527
+ "parent": {
528
+ "issueOrPRNumber": true
529
+ },
530
+ "repo": {
531
+ "type": "string",
532
+ "maxLength": 256
533
+ },
534
+ "temporary_id": {
535
+ "type": "string"
536
+ },
537
+ "title": {
538
+ "required": true,
539
+ "type": "string",
540
+ "sanitize": true,
541
+ "maxLength": 128
542
+ }
543
+ }
544
+ },
545
+ "create_pull_request": {
546
+ "defaultMax": 1,
547
+ "fields": {
548
+ "body": {
549
+ "required": true,
550
+ "type": "string",
551
+ "sanitize": true,
552
+ "maxLength": 65000
553
+ },
554
+ "branch": {
555
+ "required": true,
556
+ "type": "string",
557
+ "sanitize": true,
558
+ "maxLength": 256
559
+ },
560
+ "draft": {
561
+ "type": "boolean"
562
+ },
563
+ "labels": {
564
+ "type": "array",
565
+ "itemType": "string",
566
+ "itemSanitize": true,
567
+ "itemMaxLength": 128
568
+ },
569
+ "repo": {
570
+ "type": "string",
571
+ "maxLength": 256
572
+ },
573
+ "title": {
574
+ "required": true,
575
+ "type": "string",
576
+ "sanitize": true,
577
+ "maxLength": 128
578
+ }
579
+ }
580
+ },
581
+ "missing_data": {
582
+ "defaultMax": 20,
583
+ "fields": {
584
+ "alternatives": {
585
+ "type": "string",
586
+ "sanitize": true,
587
+ "maxLength": 256
588
+ },
589
+ "context": {
590
+ "type": "string",
591
+ "sanitize": true,
592
+ "maxLength": 256
593
+ },
594
+ "data_type": {
595
+ "type": "string",
596
+ "sanitize": true,
597
+ "maxLength": 128
598
+ },
599
+ "reason": {
600
+ "type": "string",
601
+ "sanitize": true,
602
+ "maxLength": 256
603
+ }
604
+ }
605
+ },
606
+ "missing_tool": {
607
+ "defaultMax": 20,
608
+ "fields": {
609
+ "alternatives": {
610
+ "type": "string",
611
+ "sanitize": true,
612
+ "maxLength": 512
613
+ },
614
+ "reason": {
615
+ "required": true,
616
+ "type": "string",
617
+ "sanitize": true,
618
+ "maxLength": 256
619
+ },
620
+ "tool": {
621
+ "type": "string",
622
+ "sanitize": true,
623
+ "maxLength": 128
624
+ }
625
+ }
626
+ },
627
+ "noop": {
628
+ "defaultMax": 1,
629
+ "fields": {
630
+ "message": {
631
+ "required": true,
632
+ "type": "string",
633
+ "sanitize": true,
634
+ "maxLength": 65000
635
+ }
636
+ }
637
+ },
638
+ "push_to_pull_request_branch": {
639
+ "defaultMax": 1,
640
+ "fields": {
641
+ "branch": {
642
+ "required": true,
643
+ "type": "string",
644
+ "sanitize": true,
645
+ "maxLength": 256
646
+ },
647
+ "message": {
648
+ "required": true,
649
+ "type": "string",
650
+ "sanitize": true,
651
+ "maxLength": 65000
652
+ },
653
+ "pull_request_number": {
654
+ "issueOrPRNumber": true
655
+ }
656
+ }
657
+ },
658
+ "remove_labels": {
659
+ "defaultMax": 5,
660
+ "fields": {
661
+ "item_number": {
662
+ "issueNumberOrTemporaryId": true
663
+ },
664
+ "labels": {
665
+ "required": true,
666
+ "type": "array",
667
+ "itemType": "string",
668
+ "itemSanitize": true,
669
+ "itemMaxLength": 128
670
+ },
671
+ "repo": {
672
+ "type": "string",
673
+ "maxLength": 256
674
+ }
675
+ }
676
+ },
677
+ "update_issue": {
678
+ "defaultMax": 1,
679
+ "fields": {
680
+ "assignees": {
681
+ "type": "array",
682
+ "itemType": "string",
683
+ "itemSanitize": true,
684
+ "itemMaxLength": 39
685
+ },
686
+ "body": {
687
+ "type": "string",
688
+ "sanitize": true,
689
+ "maxLength": 65000
690
+ },
691
+ "issue_number": {
692
+ "issueOrPRNumber": true
693
+ },
694
+ "labels": {
695
+ "type": "array",
696
+ "itemType": "string",
697
+ "itemSanitize": true,
698
+ "itemMaxLength": 128
699
+ },
700
+ "milestone": {
701
+ "optionalPositiveInteger": true
702
+ },
703
+ "operation": {
704
+ "type": "string",
705
+ "enum": [
706
+ "replace",
707
+ "append",
708
+ "prepend",
709
+ "replace-island"
710
+ ]
711
+ },
712
+ "repo": {
713
+ "type": "string",
714
+ "maxLength": 256
715
+ },
716
+ "status": {
717
+ "type": "string",
718
+ "enum": [
719
+ "open",
720
+ "closed"
721
+ ]
722
+ },
723
+ "title": {
724
+ "type": "string",
725
+ "sanitize": true,
726
+ "maxLength": 128
727
+ }
728
+ },
729
+ "customValidation": "requiresOneOf:status,title,body"
730
+ }
731
+ }
732
+ GH_AW_SAFE_OUTPUTS_VALIDATION_EOF
733
+ node ${RUNNER_TEMP}/gh-aw/actions/generate_safe_outputs_tools.cjs
734
+ - name: Generate Safe Outputs MCP Server Config
735
+ id: safe-outputs-config
736
+ run: |
737
+ # Generate a secure random API key (360 bits of entropy, 40+ chars)
738
+ # Mask immediately to prevent timing vulnerabilities
739
+ API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
740
+ echo "::add-mask::${API_KEY}"
741
+
742
+ PORT=3001
743
+
744
+ # Set outputs for next steps
745
+ {
746
+ echo "safe_outputs_api_key=${API_KEY}"
747
+ echo "safe_outputs_port=${PORT}"
748
+ } >> "$GITHUB_OUTPUT"
749
+
750
+ echo "Safe Outputs MCP server will run on port ${PORT}"
751
+
752
+ - name: Start Safe Outputs MCP HTTP Server
753
+ id: safe-outputs-start
754
+ env:
755
+ DEBUG: '*'
756
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-config.outputs.safe_outputs_port }}
757
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-config.outputs.safe_outputs_api_key }}
758
+ GH_AW_SAFE_OUTPUTS_TOOLS_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/tools.json
759
+ GH_AW_SAFE_OUTPUTS_CONFIG_PATH: ${{ runner.temp }}/gh-aw/safeoutputs/config.json
760
+ GH_AW_MCP_LOG_DIR: /tmp/gh-aw/mcp-logs/safeoutputs
761
+ run: |
762
+ # Environment variables are set above to prevent template injection
763
+ export DEBUG
764
+ export GH_AW_SAFE_OUTPUTS_PORT
765
+ export GH_AW_SAFE_OUTPUTS_API_KEY
766
+ export GH_AW_SAFE_OUTPUTS_TOOLS_PATH
767
+ export GH_AW_SAFE_OUTPUTS_CONFIG_PATH
768
+ export GH_AW_MCP_LOG_DIR
769
+
770
+ bash ${RUNNER_TEMP}/gh-aw/actions/start_safe_outputs_server.sh
771
+
772
+ - name: Start MCP Gateway
773
+ id: start-mcp-gateway
774
+ env:
775
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
776
+ GH_AW_SAFE_OUTPUTS_API_KEY: ${{ steps.safe-outputs-start.outputs.api_key }}
777
+ GH_AW_SAFE_OUTPUTS_PORT: ${{ steps.safe-outputs-start.outputs.port }}
778
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
779
+ run: |
780
+ set -eo pipefail
781
+ mkdir -p /tmp/gh-aw/mcp-config
782
+
783
+ # Export gateway environment variables for MCP config and gateway script
784
+ export MCP_GATEWAY_PORT="80"
785
+ export MCP_GATEWAY_DOMAIN="host.docker.internal"
786
+ MCP_GATEWAY_API_KEY=$(openssl rand -base64 45 | tr -d '/+=')
787
+ echo "::add-mask::${MCP_GATEWAY_API_KEY}"
788
+ export MCP_GATEWAY_API_KEY
789
+ export MCP_GATEWAY_PAYLOAD_DIR="/tmp/gh-aw/mcp-payloads"
790
+ mkdir -p "${MCP_GATEWAY_PAYLOAD_DIR}"
791
+ export MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD="524288"
792
+ export DEBUG="*"
793
+
794
+ export GH_AW_ENGINE="copilot"
795
+ 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.1.20'
796
+
797
+ mkdir -p /home/runner/.copilot
798
+ cat << GH_AW_MCP_CONFIG_EOF | bash ${RUNNER_TEMP}/gh-aw/actions/start_mcp_gateway.sh
799
+ {
800
+ "mcpServers": {
801
+ "github": {
802
+ "type": "stdio",
803
+ "container": "ghcr.io/github/github-mcp-server:v0.32.0",
804
+ "env": {
805
+ "GITHUB_HOST": "\${GITHUB_SERVER_URL}",
806
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "\${GITHUB_MCP_SERVER_TOKEN}",
807
+ "GITHUB_READ_ONLY": "1",
808
+ "GITHUB_TOOLSETS": "all"
809
+ },
810
+ "guard-policies": {
811
+ "allow-only": {
812
+ "min-integrity": "none",
813
+ "repos": "all"
814
+ }
815
+ }
816
+ },
817
+ "safeoutputs": {
818
+ "type": "http",
819
+ "url": "http://host.docker.internal:$GH_AW_SAFE_OUTPUTS_PORT",
820
+ "headers": {
821
+ "Authorization": "\${GH_AW_SAFE_OUTPUTS_API_KEY}"
822
+ },
823
+ "guard-policies": {
824
+ "write-sink": {
825
+ "accept": [
826
+ "*"
827
+ ]
828
+ }
829
+ }
830
+ }
831
+ },
832
+ "gateway": {
833
+ "port": $MCP_GATEWAY_PORT,
834
+ "domain": "${MCP_GATEWAY_DOMAIN}",
835
+ "apiKey": "${MCP_GATEWAY_API_KEY}",
836
+ "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}"
837
+ }
838
+ }
839
+ GH_AW_MCP_CONFIG_EOF
840
+ - name: Download activation artifact
841
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
842
+ with:
843
+ name: activation
844
+ path: /tmp/gh-aw
845
+ - name: Clean git credentials
846
+ continue-on-error: true
847
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials.sh
848
+ - name: Execute GitHub Copilot CLI
849
+ id: agentic_execution
850
+ # Copilot CLI tool arguments (sorted):
851
+ timeout-minutes: 60
852
+ run: |
853
+ set -o pipefail
854
+ touch /tmp/gh-aw/agent-step-summary.md
855
+ # shellcheck disable=SC1003
856
+ 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 "*.gradle-enterprise.cloud,*.jsr.io,*.pythonhosted.org,*.vsblob.vsassets.io,adoptium.net,anaconda.org,api.adoptium.net,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.foojay.io,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.nuget.org,api.snapcraft.io,archive.apache.org,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,bun.sh,cdn.azul.com,cdn.jsdelivr.net,central.sonatype.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,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,dc.services.visualstudio.com,deb.nodesource.com,deno.land,develocity.apache.org,dist.nuget.org,dl.google.com,dlcdn.apache.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,download.eclipse.org,download.java.net,download.oracle.com,downloads.gradle-dn.com,esm.sh,files.pythonhosted.org,ge.spockframework.org,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,gradle.org,host.docker.internal,index.crates.io,jcenter.bintray.com,jdk.java.net,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,maven.apache.org,maven.google.com,maven.oracle.com,maven.pkg.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,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,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,plugins-artifacts.gradle.org,plugins.gradle.org,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.anaconda.com,repo.continuum.io,repo.gradle.org,repo.grails.org,repo.maven.apache.org,repo.spring.io,repo.yarnpkg.com,repo1.maven.org,s.symcb.com,s.symcd.com,scans-in.gradle.com,security.ubuntu.com,services.gradle.org,sh.rustup.rs,skimdb.npmjs.com,static.crates.io,static.rust-lang.org,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.java.com,www.microsoft.com,www.npmjs.com,www.npmjs.org,yarnpkg.com" --log-level info --proxy-logs-dir /tmp/gh-aw/sandbox/firewall/logs --enable-host-access --image-tag 0.24.5 --skip-pull --enable-api-proxy \
857
+ -- /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
858
+ env:
859
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
860
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
861
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_AGENT_COPILOT || '' }}
862
+ GH_AW_MCP_CONFIG: /home/runner/.copilot/mcp-config.json
863
+ GH_AW_PHASE: agent
864
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
865
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
866
+ GH_AW_VERSION: v0.62.5
867
+ GITHUB_API_URL: ${{ github.api_url }}
868
+ GITHUB_AW: true
869
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
870
+ GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
871
+ GITHUB_REF_NAME: ${{ github.ref_name }}
872
+ GITHUB_SERVER_URL: ${{ github.server_url }}
873
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
874
+ GITHUB_WORKSPACE: ${{ github.workspace }}
875
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
876
+ GIT_AUTHOR_NAME: github-actions[bot]
877
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
878
+ GIT_COMMITTER_NAME: github-actions[bot]
879
+ XDG_CONFIG_HOME: /home/runner
880
+ - name: Detect inference access error
881
+ id: detect-inference-error
882
+ if: always()
883
+ continue-on-error: true
884
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/detect_inference_access_error.sh
885
+ - name: Configure Git credentials
886
+ env:
887
+ REPO_NAME: ${{ github.repository }}
888
+ SERVER_URL: ${{ github.server_url }}
889
+ run: |
890
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
891
+ git config --global user.name "github-actions[bot]"
892
+ git config --global am.keepcr true
893
+ # Re-authenticate git with GitHub token
894
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
895
+ git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
896
+ echo "Git configured with standard GitHub Actions identity"
897
+ - name: Copy Copilot session state files to logs
898
+ if: always()
899
+ continue-on-error: true
900
+ run: |
901
+ # Copy Copilot session state files to logs folder for artifact collection
902
+ # This ensures they are in /tmp/gh-aw/ where secret redaction can scan them
903
+ SESSION_STATE_DIR="$HOME/.copilot/session-state"
904
+ LOGS_DIR="/tmp/gh-aw/sandbox/agent/logs"
905
+
906
+ if [ -d "$SESSION_STATE_DIR" ]; then
907
+ echo "Copying Copilot session state files from $SESSION_STATE_DIR to $LOGS_DIR"
908
+ mkdir -p "$LOGS_DIR"
909
+ cp -v "$SESSION_STATE_DIR"/*.jsonl "$LOGS_DIR/" 2>/dev/null || true
910
+ echo "Session state files copied successfully"
911
+ else
912
+ echo "No session-state directory found at $SESSION_STATE_DIR"
913
+ fi
914
+ - name: Stop MCP Gateway
915
+ if: always()
916
+ continue-on-error: true
917
+ env:
918
+ MCP_GATEWAY_PORT: ${{ steps.start-mcp-gateway.outputs.gateway-port }}
919
+ MCP_GATEWAY_API_KEY: ${{ steps.start-mcp-gateway.outputs.gateway-api-key }}
920
+ GATEWAY_PID: ${{ steps.start-mcp-gateway.outputs.gateway-pid }}
921
+ run: |
922
+ bash ${RUNNER_TEMP}/gh-aw/actions/stop_mcp_gateway.sh "$GATEWAY_PID"
923
+ - name: Redact secrets in logs
924
+ if: always()
925
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
926
+ with:
927
+ script: |
928
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
929
+ setupGlobals(core, github, context, exec, io);
930
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/redact_secrets.cjs');
931
+ await main();
932
+ env:
933
+ GH_AW_SECRET_NAMES: 'COPILOT_GITHUB_TOKEN,GH_AW_GITHUB_MCP_SERVER_TOKEN,GH_AW_GITHUB_TOKEN,GITHUB_TOKEN'
934
+ SECRET_COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
935
+ SECRET_GH_AW_GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN }}
936
+ SECRET_GH_AW_GITHUB_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN }}
937
+ SECRET_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
938
+ - name: Append agent step summary
939
+ if: always()
940
+ run: bash ${RUNNER_TEMP}/gh-aw/actions/append_agent_step_summary.sh
941
+ - name: Copy Safe Outputs
942
+ if: always()
943
+ run: |
944
+ mkdir -p /tmp/gh-aw
945
+ cp "$GH_AW_SAFE_OUTPUTS" /tmp/gh-aw/safeoutputs.jsonl 2>/dev/null || true
946
+ - name: Ingest agent output
947
+ id: collect_output
948
+ if: always()
949
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
950
+ env:
951
+ GH_AW_SAFE_OUTPUTS: ${{ env.GH_AW_SAFE_OUTPUTS }}
952
+ GH_AW_ALLOWED_DOMAINS: "*.gradle-enterprise.cloud,*.jsr.io,*.pythonhosted.org,*.vsblob.vsassets.io,adoptium.net,anaconda.org,api.adoptium.net,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.foojay.io,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.nuget.org,api.snapcraft.io,archive.apache.org,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,bun.sh,cdn.azul.com,cdn.jsdelivr.net,central.sonatype.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,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,dc.services.visualstudio.com,deb.nodesource.com,deno.land,develocity.apache.org,dist.nuget.org,dl.google.com,dlcdn.apache.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,download.eclipse.org,download.java.net,download.oracle.com,downloads.gradle-dn.com,esm.sh,files.pythonhosted.org,ge.spockframework.org,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,gradle.org,host.docker.internal,index.crates.io,jcenter.bintray.com,jdk.java.net,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,maven.apache.org,maven.google.com,maven.oracle.com,maven.pkg.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,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,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,plugins-artifacts.gradle.org,plugins.gradle.org,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.anaconda.com,repo.continuum.io,repo.gradle.org,repo.grails.org,repo.maven.apache.org,repo.spring.io,repo.yarnpkg.com,repo1.maven.org,s.symcb.com,s.symcd.com,scans-in.gradle.com,security.ubuntu.com,services.gradle.org,sh.rustup.rs,skimdb.npmjs.com,static.crates.io,static.rust-lang.org,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.java.com,www.microsoft.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
953
+ GITHUB_SERVER_URL: ${{ github.server_url }}
954
+ GITHUB_API_URL: ${{ github.api_url }}
955
+ GH_AW_COMMAND: repo-assist
956
+ with:
957
+ script: |
958
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
959
+ setupGlobals(core, github, context, exec, io);
960
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/collect_ndjson_output.cjs');
961
+ await main();
962
+ - name: Parse agent logs for step summary
963
+ if: always()
964
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
965
+ env:
966
+ GH_AW_AGENT_OUTPUT: /tmp/gh-aw/sandbox/agent/logs/
967
+ with:
968
+ script: |
969
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
970
+ setupGlobals(core, github, context, exec, io);
971
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_copilot_log.cjs');
972
+ await main();
973
+ - name: Parse MCP Gateway logs for step summary
974
+ if: always()
975
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
976
+ with:
977
+ script: |
978
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
979
+ setupGlobals(core, github, context, exec, io);
980
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_mcp_gateway_log.cjs');
981
+ await main();
982
+ - name: Print firewall logs
983
+ if: always()
984
+ continue-on-error: true
985
+ env:
986
+ AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
987
+ run: |
988
+ # Fix permissions on firewall logs so they can be uploaded as artifacts
989
+ # AWF runs with sudo, creating files owned by root
990
+ sudo chmod -R a+r /tmp/gh-aw/sandbox/firewall/logs 2>/dev/null || true
991
+ # Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
992
+ if command -v awf &> /dev/null; then
993
+ awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
994
+ else
995
+ echo 'AWF binary not installed, skipping firewall log summary'
996
+ fi
997
+ # Upload repo memory as artifacts for push job
998
+ - name: Upload repo-memory artifact (default)
999
+ if: always()
1000
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
1001
+ with:
1002
+ name: repo-memory-default
1003
+ path: /tmp/gh-aw/repo-memory/default
1004
+ retention-days: 1
1005
+ if-no-files-found: ignore
1006
+ - name: Upload agent artifacts
1007
+ if: always()
1008
+ continue-on-error: true
1009
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
1010
+ with:
1011
+ name: agent
1012
+ path: |
1013
+ /tmp/gh-aw/aw-prompts/prompt.txt
1014
+ /tmp/gh-aw/sandbox/agent/logs/
1015
+ /tmp/gh-aw/redacted-urls.log
1016
+ /tmp/gh-aw/mcp-logs/
1017
+ /tmp/gh-aw/sandbox/firewall/logs/
1018
+ /tmp/gh-aw/agent-stdio.log
1019
+ /tmp/gh-aw/agent/
1020
+ /tmp/gh-aw/safeoutputs.jsonl
1021
+ /tmp/gh-aw/agent_output.json
1022
+ /tmp/gh-aw/aw-*.patch
1023
+ if-no-files-found: ignore
1024
+ # --- Threat Detection (inline) ---
1025
+ - name: Check if detection needed
1026
+ id: detection_guard
1027
+ if: always()
1028
+ env:
1029
+ OUTPUT_TYPES: ${{ steps.collect_output.outputs.output_types }}
1030
+ HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
1031
+ run: |
1032
+ if [[ -n "$OUTPUT_TYPES" || "$HAS_PATCH" == "true" ]]; then
1033
+ echo "run_detection=true" >> "$GITHUB_OUTPUT"
1034
+ echo "Detection will run: output_types=$OUTPUT_TYPES, has_patch=$HAS_PATCH"
1035
+ else
1036
+ echo "run_detection=false" >> "$GITHUB_OUTPUT"
1037
+ echo "Detection skipped: no agent outputs or patches to analyze"
1038
+ fi
1039
+ - name: Clear MCP configuration for detection
1040
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1041
+ run: |
1042
+ rm -f /tmp/gh-aw/mcp-config/mcp-servers.json
1043
+ rm -f /home/runner/.copilot/mcp-config.json
1044
+ rm -f "$GITHUB_WORKSPACE/.gemini/settings.json"
1045
+ - name: Prepare threat detection files
1046
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1047
+ run: |
1048
+ mkdir -p /tmp/gh-aw/threat-detection/aw-prompts
1049
+ cp /tmp/gh-aw/aw-prompts/prompt.txt /tmp/gh-aw/threat-detection/aw-prompts/prompt.txt 2>/dev/null || true
1050
+ cp /tmp/gh-aw/agent_output.json /tmp/gh-aw/threat-detection/agent_output.json 2>/dev/null || true
1051
+ for f in /tmp/gh-aw/aw-*.patch; do
1052
+ [ -f "$f" ] && cp "$f" /tmp/gh-aw/threat-detection/ 2>/dev/null || true
1053
+ done
1054
+ echo "Prepared threat detection files:"
1055
+ ls -la /tmp/gh-aw/threat-detection/ 2>/dev/null || true
1056
+ - name: Setup threat detection
1057
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1058
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1059
+ env:
1060
+ WORKFLOW_NAME: "Repo Assist"
1061
+ WORKFLOW_DESCRIPTION: "A friendly repository assistant that runs 2 times a day to support contributors and maintainers.\nCan also be triggered on-demand via '/repo-assist <instructions>' to perform specific tasks.\n- Labels and triages open issues\n- Comments helpfully on open issues to unblock contributors and onboard newcomers\n- Identifies issues that can be fixed and creates draft pull requests with fixes\n- Improves performance, testing, and code quality via PRs\n- Makes engineering investments: dependency updates, CI improvements, tooling\n- Updates its own PRs when CI fails or merge conflicts arise\n- Nudges stale PRs waiting for author response\n- Takes the repository forward with proactive improvements\n- Maintains a persistent memory of work done and what remains\nAlways polite, constructive, and mindful of the project's goals."
1062
+ HAS_PATCH: ${{ steps.collect_output.outputs.has_patch }}
1063
+ with:
1064
+ script: |
1065
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1066
+ setupGlobals(core, github, context, exec, io);
1067
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/setup_threat_detection.cjs');
1068
+ await main();
1069
+ - name: Ensure threat-detection directory and log
1070
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1071
+ run: |
1072
+ mkdir -p /tmp/gh-aw/threat-detection
1073
+ touch /tmp/gh-aw/threat-detection/detection.log
1074
+ - name: Execute GitHub Copilot CLI
1075
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1076
+ id: detection_agentic_execution
1077
+ # Copilot CLI tool arguments (sorted):
1078
+ # --allow-tool shell(cat)
1079
+ # --allow-tool shell(grep)
1080
+ # --allow-tool shell(head)
1081
+ # --allow-tool shell(jq)
1082
+ # --allow-tool shell(ls)
1083
+ # --allow-tool shell(tail)
1084
+ # --allow-tool shell(wc)
1085
+ timeout-minutes: 20
1086
+ run: |
1087
+ set -o pipefail
1088
+ touch /tmp/gh-aw/agent-step-summary.md
1089
+ # shellcheck disable=SC1003
1090
+ 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.24.5 --skip-pull --enable-api-proxy \
1091
+ -- /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
1092
+ env:
1093
+ COPILOT_AGENT_RUNNER_TYPE: STANDALONE
1094
+ COPILOT_GITHUB_TOKEN: ${{ secrets.COPILOT_GITHUB_TOKEN }}
1095
+ COPILOT_MODEL: ${{ vars.GH_AW_MODEL_DETECTION_COPILOT || '' }}
1096
+ GH_AW_PHASE: detection
1097
+ GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt
1098
+ GH_AW_VERSION: v0.62.5
1099
+ GITHUB_API_URL: ${{ github.api_url }}
1100
+ GITHUB_AW: true
1101
+ GITHUB_HEAD_REF: ${{ github.head_ref }}
1102
+ GITHUB_REF_NAME: ${{ github.ref_name }}
1103
+ GITHUB_SERVER_URL: ${{ github.server_url }}
1104
+ GITHUB_STEP_SUMMARY: /tmp/gh-aw/agent-step-summary.md
1105
+ GITHUB_WORKSPACE: ${{ github.workspace }}
1106
+ GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
1107
+ GIT_AUTHOR_NAME: github-actions[bot]
1108
+ GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
1109
+ GIT_COMMITTER_NAME: github-actions[bot]
1110
+ XDG_CONFIG_HOME: /home/runner
1111
+ - name: Parse threat detection results
1112
+ id: parse_detection_results
1113
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1114
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1115
+ with:
1116
+ script: |
1117
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1118
+ setupGlobals(core, github, context, exec, io);
1119
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/parse_threat_detection_results.cjs');
1120
+ await main();
1121
+ - name: Upload threat detection log
1122
+ if: always() && steps.detection_guard.outputs.run_detection == 'true'
1123
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
1124
+ with:
1125
+ name: detection
1126
+ path: /tmp/gh-aw/threat-detection/detection.log
1127
+ if-no-files-found: ignore
1128
+ - name: Set detection conclusion
1129
+ id: detection_conclusion
1130
+ if: always()
1131
+ env:
1132
+ RUN_DETECTION: ${{ steps.detection_guard.outputs.run_detection }}
1133
+ DETECTION_SUCCESS: ${{ steps.parse_detection_results.outputs.success }}
1134
+ run: |
1135
+ if [[ "$RUN_DETECTION" != "true" ]]; then
1136
+ echo "conclusion=skipped" >> "$GITHUB_OUTPUT"
1137
+ echo "success=true" >> "$GITHUB_OUTPUT"
1138
+ echo "Detection was not needed, marking as skipped"
1139
+ elif [[ "$DETECTION_SUCCESS" == "true" ]]; then
1140
+ echo "conclusion=success" >> "$GITHUB_OUTPUT"
1141
+ echo "success=true" >> "$GITHUB_OUTPUT"
1142
+ echo "Detection passed successfully"
1143
+ else
1144
+ echo "conclusion=failure" >> "$GITHUB_OUTPUT"
1145
+ echo "success=false" >> "$GITHUB_OUTPUT"
1146
+ echo "Detection found issues"
1147
+ fi
1148
+
1149
+ conclusion:
1150
+ needs:
1151
+ - activation
1152
+ - agent
1153
+ - push_repo_memory
1154
+ - safe_outputs
1155
+ if: always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true')
1156
+ runs-on: ubuntu-slim
1157
+ permissions:
1158
+ contents: write
1159
+ discussions: write
1160
+ issues: write
1161
+ pull-requests: write
1162
+ concurrency:
1163
+ group: "gh-aw-conclusion-repo-assist"
1164
+ cancel-in-progress: false
1165
+ outputs:
1166
+ noop_message: ${{ steps.noop.outputs.noop_message }}
1167
+ tools_reported: ${{ steps.missing_tool.outputs.tools_reported }}
1168
+ total_count: ${{ steps.missing_tool.outputs.total_count }}
1169
+ steps:
1170
+ - name: Setup Scripts
1171
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
1172
+ with:
1173
+ destination: ${{ runner.temp }}/gh-aw/actions
1174
+ - name: Download agent output artifact
1175
+ id: download-agent-output
1176
+ continue-on-error: true
1177
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1178
+ with:
1179
+ name: agent
1180
+ path: /tmp/gh-aw/
1181
+ - name: Setup agent output environment variable
1182
+ if: steps.download-agent-output.outcome == 'success'
1183
+ run: |
1184
+ mkdir -p /tmp/gh-aw/
1185
+ find "/tmp/gh-aw/" -type f -print
1186
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
1187
+ - name: Process No-Op Messages
1188
+ id: noop
1189
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1190
+ env:
1191
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1192
+ GH_AW_NOOP_MAX: "1"
1193
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1194
+ with:
1195
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1196
+ script: |
1197
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1198
+ setupGlobals(core, github, context, exec, io);
1199
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/noop.cjs');
1200
+ await main();
1201
+ - name: Record Missing Tool
1202
+ id: missing_tool
1203
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1204
+ env:
1205
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1206
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1207
+ with:
1208
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1209
+ script: |
1210
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1211
+ setupGlobals(core, github, context, exec, io);
1212
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/missing_tool.cjs');
1213
+ await main();
1214
+ - name: Handle Agent Failure
1215
+ id: handle_agent_failure
1216
+ if: always()
1217
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1218
+ env:
1219
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1220
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1221
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1222
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1223
+ GH_AW_WORKFLOW_ID: "repo-assist"
1224
+ GH_AW_SECRET_VERIFICATION_RESULT: ${{ needs.activation.outputs.secret_verification_result }}
1225
+ GH_AW_CHECKOUT_PR_SUCCESS: ${{ needs.agent.outputs.checkout_pr_success }}
1226
+ GH_AW_INFERENCE_ACCESS_ERROR: ${{ needs.agent.outputs.inference_access_error }}
1227
+ GH_AW_CODE_PUSH_FAILURE_ERRORS: ${{ needs.safe_outputs.outputs.code_push_failure_errors }}
1228
+ GH_AW_CODE_PUSH_FAILURE_COUNT: ${{ needs.safe_outputs.outputs.code_push_failure_count }}
1229
+ GH_AW_LOCKDOWN_CHECK_FAILED: ${{ needs.activation.outputs.lockdown_check_failed }}
1230
+ GH_AW_PUSH_REPO_MEMORY_RESULT: ${{ needs.push_repo_memory.result }}
1231
+ GH_AW_REPO_MEMORY_VALIDATION_FAILED_default: ${{ needs.push_repo_memory.outputs.validation_failed_default }}
1232
+ GH_AW_REPO_MEMORY_VALIDATION_ERROR_default: ${{ needs.push_repo_memory.outputs.validation_error_default }}
1233
+ GH_AW_REPO_MEMORY_PATCH_SIZE_EXCEEDED_default: ${{ needs.push_repo_memory.outputs.patch_size_exceeded_default }}
1234
+ GH_AW_GROUP_REPORTS: "false"
1235
+ GH_AW_FAILURE_REPORT_AS_ISSUE: "true"
1236
+ GH_AW_TIMEOUT_MINUTES: "60"
1237
+ with:
1238
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1239
+ script: |
1240
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1241
+ setupGlobals(core, github, context, exec, io);
1242
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_agent_failure.cjs');
1243
+ await main();
1244
+ - name: Handle No-Op Message
1245
+ id: handle_noop_message
1246
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1247
+ env:
1248
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1249
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1250
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1251
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1252
+ GH_AW_NOOP_MESSAGE: ${{ steps.noop.outputs.noop_message }}
1253
+ GH_AW_NOOP_REPORT_AS_ISSUE: "true"
1254
+ with:
1255
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1256
+ script: |
1257
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1258
+ setupGlobals(core, github, context, exec, io);
1259
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_noop_message.cjs');
1260
+ await main();
1261
+ - name: Handle Create Pull Request Error
1262
+ id: handle_create_pr_error
1263
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1264
+ env:
1265
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1266
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1267
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1268
+ with:
1269
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1270
+ script: |
1271
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1272
+ setupGlobals(core, github, context, exec, io);
1273
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/handle_create_pr_error.cjs');
1274
+ await main();
1275
+ - name: Update reaction comment with completion status
1276
+ id: conclusion
1277
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1278
+ env:
1279
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1280
+ GH_AW_COMMENT_ID: ${{ needs.activation.outputs.comment_id }}
1281
+ GH_AW_COMMENT_REPO: ${{ needs.activation.outputs.comment_repo }}
1282
+ GH_AW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
1283
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1284
+ GH_AW_AGENT_CONCLUSION: ${{ needs.agent.result }}
1285
+ GH_AW_DETECTION_CONCLUSION: ${{ needs.agent.outputs.detection_conclusion }}
1286
+ with:
1287
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1288
+ script: |
1289
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1290
+ setupGlobals(core, github, context, exec, io);
1291
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/notify_comment_error.cjs');
1292
+ await main();
1293
+
1294
+ pre_activation:
1295
+ if: "(github.event_name == 'issues' || github.event_name == 'issue_comment' || github.event_name == 'pull_request' || github.event_name == 'pull_request_review_comment' || github.event_name == 'discussion' || github.event_name == 'discussion_comment') && (github.event_name == 'issues' && (startsWith(github.event.issue.body, '/repo-assist ') || startsWith(github.event.issue.body, '/repo-assist\n') || github.event.issue.body == '/repo-assist') || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request == null || github.event_name == 'issue_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') && github.event.issue.pull_request != null || github.event_name == 'pull_request_review_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist') || github.event_name == 'pull_request' && (startsWith(github.event.pull_request.body, '/repo-assist ') || startsWith(github.event.pull_request.body, '/repo-assist\n') || github.event.pull_request.body == '/repo-assist') || github.event_name == 'discussion' && (startsWith(github.event.discussion.body, '/repo-assist ') || startsWith(github.event.discussion.body, '/repo-assist\n') || github.event.discussion.body == '/repo-assist') || github.event_name == 'discussion_comment' && (startsWith(github.event.comment.body, '/repo-assist ') || startsWith(github.event.comment.body, '/repo-assist\n') || github.event.comment.body == '/repo-assist')) || (!(github.event_name == 'issues')) && (!(github.event_name == 'issue_comment')) && (!(github.event_name == 'pull_request')) && (!(github.event_name == 'pull_request_review_comment')) && (!(github.event_name == 'discussion')) && (!(github.event_name == 'discussion_comment'))"
1296
+ runs-on: ubuntu-slim
1297
+ outputs:
1298
+ activated: ${{ steps.check_membership.outputs.is_team_member == 'true' && steps.check_command_position.outputs.command_position_ok == 'true' }}
1299
+ matched_command: ${{ steps.check_command_position.outputs.matched_command }}
1300
+ steps:
1301
+ - name: Setup Scripts
1302
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
1303
+ with:
1304
+ destination: ${{ runner.temp }}/gh-aw/actions
1305
+ - name: Check team membership for command workflow
1306
+ id: check_membership
1307
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1308
+ env:
1309
+ GH_AW_REQUIRED_ROLES: admin,maintainer,write
1310
+ with:
1311
+ github-token: ${{ secrets.GITHUB_TOKEN }}
1312
+ script: |
1313
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1314
+ setupGlobals(core, github, context, exec, io);
1315
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_membership.cjs');
1316
+ await main();
1317
+ - name: Check command position
1318
+ id: check_command_position
1319
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1320
+ env:
1321
+ GH_AW_COMMANDS: "[\"repo-assist\"]"
1322
+ with:
1323
+ script: |
1324
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1325
+ setupGlobals(core, github, context, exec, io);
1326
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/check_command_position.cjs');
1327
+ await main();
1328
+
1329
+ push_repo_memory:
1330
+ needs: agent
1331
+ if: always() && needs.agent.outputs.detection_success == 'true'
1332
+ runs-on: ubuntu-latest
1333
+ permissions:
1334
+ contents: write
1335
+ concurrency:
1336
+ group: "push-repo-memory-${{ github.repository }}"
1337
+ cancel-in-progress: false
1338
+ outputs:
1339
+ patch_size_exceeded_default: ${{ steps.push_repo_memory_default.outputs.patch_size_exceeded }}
1340
+ validation_error_default: ${{ steps.push_repo_memory_default.outputs.validation_error }}
1341
+ validation_failed_default: ${{ steps.push_repo_memory_default.outputs.validation_failed }}
1342
+ steps:
1343
+ - name: Setup Scripts
1344
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
1345
+ with:
1346
+ destination: ${{ runner.temp }}/gh-aw/actions
1347
+ - name: Checkout repository
1348
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1349
+ with:
1350
+ persist-credentials: false
1351
+ sparse-checkout: .
1352
+ - name: Configure Git credentials
1353
+ env:
1354
+ REPO_NAME: ${{ github.repository }}
1355
+ SERVER_URL: ${{ github.server_url }}
1356
+ run: |
1357
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
1358
+ git config --global user.name "github-actions[bot]"
1359
+ git config --global am.keepcr true
1360
+ # Re-authenticate git with GitHub token
1361
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
1362
+ git remote set-url origin "https://x-access-token:${{ github.token }}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
1363
+ echo "Git configured with standard GitHub Actions identity"
1364
+ - name: Download repo-memory artifact (default)
1365
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1366
+ continue-on-error: true
1367
+ with:
1368
+ name: repo-memory-default
1369
+ path: /tmp/gh-aw/repo-memory/default
1370
+ - name: Push repo-memory changes (default)
1371
+ id: push_repo_memory_default
1372
+ if: always()
1373
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1374
+ env:
1375
+ GH_TOKEN: ${{ github.token }}
1376
+ GITHUB_RUN_ID: ${{ github.run_id }}
1377
+ GITHUB_SERVER_URL: ${{ github.server_url }}
1378
+ ARTIFACT_DIR: /tmp/gh-aw/repo-memory/default
1379
+ MEMORY_ID: default
1380
+ TARGET_REPO: ${{ github.repository }}
1381
+ BRANCH_NAME: memory/repo-assist
1382
+ MAX_FILE_SIZE: 10240
1383
+ MAX_FILE_COUNT: 100
1384
+ MAX_PATCH_SIZE: 10240
1385
+ ALLOWED_EXTENSIONS: '[]'
1386
+ with:
1387
+ script: |
1388
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1389
+ setupGlobals(core, github, context, exec, io);
1390
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/push_repo_memory.cjs');
1391
+ await main();
1392
+
1393
+ safe_outputs:
1394
+ needs:
1395
+ - activation
1396
+ - agent
1397
+ if: (!cancelled()) && needs.agent.result != 'skipped' && needs.agent.outputs.detection_success == 'true'
1398
+ runs-on: ubuntu-slim
1399
+ permissions:
1400
+ contents: write
1401
+ discussions: write
1402
+ issues: write
1403
+ pull-requests: write
1404
+ timeout-minutes: 15
1405
+ env:
1406
+ GH_AW_CALLER_WORKFLOW_ID: "${{ github.repository }}/repo-assist"
1407
+ GH_AW_ENGINE_ID: "copilot"
1408
+ GH_AW_WORKFLOW_ID: "repo-assist"
1409
+ GH_AW_WORKFLOW_NAME: "Repo Assist"
1410
+ outputs:
1411
+ code_push_failure_count: ${{ steps.process_safe_outputs.outputs.code_push_failure_count }}
1412
+ code_push_failure_errors: ${{ steps.process_safe_outputs.outputs.code_push_failure_errors }}
1413
+ comment_id: ${{ steps.process_safe_outputs.outputs.comment_id }}
1414
+ comment_url: ${{ steps.process_safe_outputs.outputs.comment_url }}
1415
+ create_discussion_error_count: ${{ steps.process_safe_outputs.outputs.create_discussion_error_count }}
1416
+ create_discussion_errors: ${{ steps.process_safe_outputs.outputs.create_discussion_errors }}
1417
+ created_issue_number: ${{ steps.process_safe_outputs.outputs.created_issue_number }}
1418
+ created_issue_url: ${{ steps.process_safe_outputs.outputs.created_issue_url }}
1419
+ created_pr_number: ${{ steps.process_safe_outputs.outputs.created_pr_number }}
1420
+ created_pr_url: ${{ steps.process_safe_outputs.outputs.created_pr_url }}
1421
+ process_safe_outputs_processed_count: ${{ steps.process_safe_outputs.outputs.processed_count }}
1422
+ process_safe_outputs_temporary_id_map: ${{ steps.process_safe_outputs.outputs.temporary_id_map }}
1423
+ push_commit_sha: ${{ steps.process_safe_outputs.outputs.push_commit_sha }}
1424
+ push_commit_url: ${{ steps.process_safe_outputs.outputs.push_commit_url }}
1425
+ steps:
1426
+ - name: Setup Scripts
1427
+ uses: github/gh-aw-actions/setup@dc50be57c94373431b49d3d0927f318ac2bb5c4c # v0.62.5
1428
+ with:
1429
+ destination: ${{ runner.temp }}/gh-aw/actions
1430
+ - name: Download agent output artifact
1431
+ id: download-agent-output
1432
+ continue-on-error: true
1433
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1434
+ with:
1435
+ name: agent
1436
+ path: /tmp/gh-aw/
1437
+ - name: Setup agent output environment variable
1438
+ if: steps.download-agent-output.outcome == 'success'
1439
+ run: |
1440
+ mkdir -p /tmp/gh-aw/
1441
+ find "/tmp/gh-aw/" -type f -print
1442
+ echo "GH_AW_AGENT_OUTPUT=/tmp/gh-aw/agent_output.json" >> "$GITHUB_ENV"
1443
+ - name: Download patch artifact
1444
+ continue-on-error: true
1445
+ uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
1446
+ with:
1447
+ name: agent
1448
+ path: /tmp/gh-aw/
1449
+ - name: Checkout repository
1450
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
1451
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
1452
+ with:
1453
+ ref: ${{ github.base_ref || github.event.pull_request.base.ref || github.ref_name || github.event.repository.default_branch }}
1454
+ token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1455
+ persist-credentials: false
1456
+ fetch-depth: 1
1457
+ - name: Configure Git credentials
1458
+ if: (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'create_pull_request') || (!cancelled()) && needs.agent.result != 'skipped' && contains(needs.agent.outputs.output_types, 'push_to_pull_request_branch')
1459
+ env:
1460
+ REPO_NAME: ${{ github.repository }}
1461
+ SERVER_URL: ${{ github.server_url }}
1462
+ GIT_TOKEN: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1463
+ run: |
1464
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
1465
+ git config --global user.name "github-actions[bot]"
1466
+ git config --global am.keepcr true
1467
+ # Re-authenticate git with GitHub token
1468
+ SERVER_URL_STRIPPED="${SERVER_URL#https://}"
1469
+ git remote set-url origin "https://x-access-token:${GIT_TOKEN}@${SERVER_URL_STRIPPED}/${REPO_NAME}.git"
1470
+ echo "Git configured with standard GitHub Actions identity"
1471
+ - name: Configure GH_HOST for enterprise compatibility
1472
+ shell: bash
1473
+ run: |
1474
+ # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct
1475
+ # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op.
1476
+ GH_HOST="${GITHUB_SERVER_URL#https://}"
1477
+ GH_HOST="${GH_HOST#http://}"
1478
+ echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV"
1479
+ - name: Process Safe Outputs
1480
+ id: process_safe_outputs
1481
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
1482
+ env:
1483
+ GH_AW_AGENT_OUTPUT: ${{ env.GH_AW_AGENT_OUTPUT }}
1484
+ GH_AW_ALLOWED_DOMAINS: "*.gradle-enterprise.cloud,*.jsr.io,*.pythonhosted.org,*.vsblob.vsassets.io,adoptium.net,anaconda.org,api.adoptium.net,api.business.githubcopilot.com,api.enterprise.githubcopilot.com,api.foojay.io,api.github.com,api.githubcopilot.com,api.individual.githubcopilot.com,api.npms.io,api.nuget.org,api.snapcraft.io,archive.apache.org,archive.ubuntu.com,azure.archive.ubuntu.com,azuresearch-usnc.nuget.org,azuresearch-ussc.nuget.org,binstar.org,bootstrap.pypa.io,builds.dotnet.microsoft.com,bun.sh,cdn.azul.com,cdn.jsdelivr.net,central.sonatype.com,ci.dot.net,conda.anaconda.org,conda.binstar.org,crates.io,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,dc.services.visualstudio.com,deb.nodesource.com,deno.land,develocity.apache.org,dist.nuget.org,dl.google.com,dlcdn.apache.org,dot.net,dotnet.microsoft.com,dotnetcli.blob.core.windows.net,download.eclipse.org,download.java.net,download.oracle.com,downloads.gradle-dn.com,esm.sh,files.pythonhosted.org,ge.spockframework.org,get.pnpm.io,github.com,googleapis.deno.dev,googlechromelabs.github.io,gradle.org,host.docker.internal,index.crates.io,jcenter.bintray.com,jdk.java.net,json-schema.org,json.schemastore.org,jsr.io,keyserver.ubuntu.com,maven.apache.org,maven.google.com,maven.oracle.com,maven.pkg.github.com,nodejs.org,npm.pkg.github.com,npmjs.com,npmjs.org,nuget.org,nuget.pkg.github.com,nugetregistryv2prod.blob.core.windows.net,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,oneocsp.microsoft.com,packagecloud.io,packages.cloud.google.com,packages.microsoft.com,pip.pypa.io,pkgs.dev.azure.com,plugins-artifacts.gradle.org,plugins.gradle.org,ppa.launchpad.net,pypi.org,pypi.python.org,raw.githubusercontent.com,registry.bower.io,registry.npmjs.com,registry.npmjs.org,registry.yarnpkg.com,repo.anaconda.com,repo.continuum.io,repo.gradle.org,repo.grails.org,repo.maven.apache.org,repo.spring.io,repo.yarnpkg.com,repo1.maven.org,s.symcb.com,s.symcd.com,scans-in.gradle.com,security.ubuntu.com,services.gradle.org,sh.rustup.rs,skimdb.npmjs.com,static.crates.io,static.rust-lang.org,storage.googleapis.com,telemetry.enterprise.githubcopilot.com,telemetry.vercel.com,ts-crl.ws.symantec.com,ts-ocsp.ws.symantec.com,www.googleapis.com,www.java.com,www.microsoft.com,www.npmjs.com,www.npmjs.org,yarnpkg.com"
1485
+ GITHUB_SERVER_URL: ${{ github.server_url }}
1486
+ GITHUB_API_URL: ${{ github.api_url }}
1487
+ GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: "{\"add_comment\":{\"hide_older_comments\":true,\"max\":10,\"target\":\"*\"},\"add_labels\":{\"allowed\":[\"bug\",\"enhancement\",\"help wanted\",\"good first issue\",\"spam\",\"off topic\",\"documentation\",\"question\",\"duplicate\",\"wontfix\",\"needs triage\",\"needs investigation\",\"breaking change\",\"performance\",\"security\",\"refactor\"],\"max\":30,\"target\":\"*\"},\"create_issue\":{\"labels\":[\"automation\",\"repo-assist\"],\"max\":4,\"title_prefix\":\"[Repo Assist] \"},\"create_pull_request\":{\"draft\":true,\"labels\":[\"automation\",\"repo-assist\"],\"max\":4,\"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_files_policy\":\"fallback-to-issue\",\"protected_path_prefixes\":[\".github/\",\".agents/\"],\"title_prefix\":\"[Repo Assist] \"},\"missing_data\":{},\"missing_tool\":{},\"noop\":{\"max\":1,\"report-as-issue\":\"true\"},\"push_to_pull_request_branch\":{\"if_no_changes\":\"warn\",\"max\":4,\"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/\"],\"target\":\"*\",\"title_prefix\":\"[Repo Assist] \"},\"remove_labels\":{\"allowed\":[\"bug\",\"enhancement\",\"help wanted\",\"good first issue\",\"spam\",\"off topic\",\"documentation\",\"question\",\"duplicate\",\"wontfix\",\"needs triage\",\"needs investigation\",\"breaking change\",\"performance\",\"security\",\"refactor\"],\"max\":5,\"target\":\"*\"},\"update_issue\":{\"allow_body\":true,\"max\":1,\"target\":\"*\",\"title_prefix\":\"[Repo Assist] \"}}"
1488
+ GH_AW_CI_TRIGGER_TOKEN: ${{ secrets.GH_AW_CI_TRIGGER_TOKEN }}
1489
+ with:
1490
+ github-token: ${{ secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
1491
+ script: |
1492
+ const { setupGlobals } = require('${{ runner.temp }}/gh-aw/actions/setup_globals.cjs');
1493
+ setupGlobals(core, github, context, exec, io);
1494
+ const { main } = require('${{ runner.temp }}/gh-aw/actions/safe_output_handler_manager.cjs');
1495
+ await main();
1496
+ - name: Upload safe output items
1497
+ if: always()
1498
+ uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
1499
+ with:
1500
+ name: safe-output-items
1501
+ path: /tmp/gh-aw/safe-output-items.jsonl
1502
+ if-no-files-found: ignore
1503
+