|
1 | 1 | --- |
2 | 2 | title: Safe Outputs (Pull Requests) |
3 | | -description: Reference for create-pull-request and push-to-pull-request-branch safe outputs, including protected files policy. |
| 3 | +description: Reference for pull-request safe outputs including create-pull-request, push-to-pull-request-branch, and add-reviewer. |
4 | 4 | sidebar: |
5 | 5 | order: 801 |
6 | 6 | --- |
7 | 7 |
|
8 | | -This page covers the two safe-output types that write code to a repository: [`create-pull-request`](#pull-request-creation-create-pull-request) and [`push-to-pull-request-branch`](#push-to-pr-branch-push-to-pull-request-branch). Both types enforce [Protected Files](#protected-files) by default. |
| 8 | +This page is the primary reference for pull-request-focused safe outputs: |
| 9 | + |
| 10 | +- [`create-pull-request`](#pull-request-creation-create-pull-request) |
| 11 | +- [`update-pull-request`](#pull-request-updates-update-pull-request) |
| 12 | +- [`close-pull-request`](#close-pull-request-close-pull-request) |
| 13 | +- [`create-pull-request-review-comment`](#pr-review-comments-create-pull-request-review-comment) |
| 14 | +- [`reply-to-pull-request-review-comment`](#reply-to-pr-review-comment-reply-to-pull-request-review-comment) |
| 15 | +- [`resolve-pull-request-review-thread`](#resolve-pr-review-thread-resolve-pull-request-review-thread) |
| 16 | +- [`push-to-pull-request-branch`](#push-to-pr-branch-push-to-pull-request-branch) |
| 17 | +- [`add-reviewer`](#add-reviewer-add-reviewer) |
| 18 | + |
| 19 | +Code-writing types (`create-pull-request` and `push-to-pull-request-branch`) enforce [Protected Files](#protected-files) by default. |
9 | 20 |
|
10 | 21 | For all other safe-output types see [Safe Outputs](/gh-aw/reference/safe-outputs/). |
11 | 22 |
|
@@ -86,6 +97,108 @@ If commits have been pushed to the base branch after the agent started, two outc |
86 | 97 | > [!NOTE] |
87 | 98 | > The fallback to the original base commit requires that commit to be present in the target repository. In cross-repository scenarios where the agent repository's history is unrelated, only the `--3way` attempt is made and a hard failure is returned if that also fails. |
88 | 99 |
|
| 100 | +## Pull Request Updates (`update-pull-request:`) |
| 101 | + |
| 102 | +Updates PR title or body. Both fields are enabled by default. The `operation` field controls how body updates are applied: `append` (default), `prepend`, or `replace`. |
| 103 | + |
| 104 | +```yaml wrap |
| 105 | +safe-outputs: |
| 106 | + update-pull-request: |
| 107 | + title: true # enable title updates (default: true) |
| 108 | + body: true # enable body updates (default: true) |
| 109 | + footer: false # omit AI-generated footer from body updates (default: true) |
| 110 | + max: 1 # max updates (default: 1) |
| 111 | + target: "*" # "triggering" (default), "*", or number |
| 112 | + target-repo: "owner/repo" # cross-repository |
| 113 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 114 | +``` |
| 115 | + |
| 116 | +**Target**: `"triggering"` (requires PR event), `"*"` (any PR), or number (specific PR). |
| 117 | + |
| 118 | +When using `target: "*"`, the agent must provide `pull_request_number` in the output to identify which pull request to update. |
| 119 | + |
| 120 | +**Operation Types**: Same as `update-issue` (`append`, `prepend`, `replace`). Title updates always replace the existing title. Disable fields by setting to `false`. |
| 121 | + |
| 122 | +## Close Pull Request (`close-pull-request:`) |
| 123 | + |
| 124 | +Closes PRs without merging with optional comment. Filter by labels and title prefix. Target: `"triggering"` (PR event), `"*"` (any), or number. |
| 125 | + |
| 126 | +```yaml wrap |
| 127 | +safe-outputs: |
| 128 | + close-pull-request: |
| 129 | + target: "triggering" # "triggering" (default), "*", or number |
| 130 | + required-labels: [automated, stale] # only close with these labels |
| 131 | + required-title-prefix: "[bot]" # only close matching prefix |
| 132 | + max: 10 # max closures (default: 1) |
| 133 | + target-repo: "owner/repo" # cross-repository |
| 134 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 135 | +``` |
| 136 | + |
| 137 | +## PR Review Comments (`create-pull-request-review-comment:`) |
| 138 | + |
| 139 | +Creates review comments on specific code lines in PRs. Supports single-line and multi-line comments. |
| 140 | + |
| 141 | +```yaml wrap |
| 142 | +safe-outputs: |
| 143 | + create-pull-request-review-comment: |
| 144 | + max: 3 # max comments (default: 10) |
| 145 | + side: "RIGHT" # "LEFT" or "RIGHT" (default: "RIGHT") |
| 146 | + target: "*" # "triggering" (default), "*", or number |
| 147 | + target-repo: "owner/repo" # cross-repository |
| 148 | + allowed-repos: ["org/repo1", "org/repo2"] # additional allowed repositories |
| 149 | + footer: "if-body" # footer control: "always", "none", or "if-body" |
| 150 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 151 | +``` |
| 152 | + |
| 153 | +When `target: "*"` is configured, the agent must supply `pull_request_number` in each `create_pull_request_review_comment` tool call to identify which PR to comment on — omitting it will cause the comment to fail. For cross-repository scenarios, the agent can also supply `repo` (in `owner/repo` format) to route the comment to a PR in a different repository; the value must match `target-repo` or appear in `allowed-repos`. |
| 154 | + |
| 155 | +## Reply to PR Review Comment (`reply-to-pull-request-review-comment:`) |
| 156 | + |
| 157 | +Replies to existing review comments on pull requests. Use this to respond to reviewer feedback, answer questions, or acknowledge comments. The `comment_id` must be the numeric ID of an existing review comment. |
| 158 | + |
| 159 | +```yaml wrap |
| 160 | +safe-outputs: |
| 161 | + reply-to-pull-request-review-comment: |
| 162 | + max: 10 # max replies (default: 10) |
| 163 | + target: "triggering" # "triggering" (default), "*", or number |
| 164 | + target-repo: "owner/repo" # cross-repository |
| 165 | + allowed-repos: ["org/other-repo"] # additional allowed repositories |
| 166 | + footer: true # add AI-generated footer (default: true) |
| 167 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 168 | +``` |
| 169 | + |
| 170 | +The `footer` field controls whether AI-generated footers are added to PR review comments: |
| 171 | + |
| 172 | +- `"always"` (default) - Always include footer on review comments |
| 173 | +- `"none"` - Never include footer on review comments |
| 174 | +- `"if-body"` - Only include footer when the review has a body text |
| 175 | + |
| 176 | +With `footer: "if-body"`, approval reviews without body text appear clean without the AI-generated footer, while reviews with explanatory text still include the footer for attribution. |
| 177 | +
|
| 178 | +## Resolve PR Review Thread (`resolve-pull-request-review-thread:`) |
| 179 | + |
| 180 | +Resolves review threads on pull requests. Allows AI agents to mark review conversations as resolved after addressing the feedback. Uses the GitHub GraphQL API with the `resolveReviewThread` mutation. |
| 181 | + |
| 182 | +By default, resolution is scoped to the triggering PR. Use `target`, `target-repo`, and `allowed-repos` for cross-repository thread resolution. |
| 183 | + |
| 184 | +```yaml wrap |
| 185 | +safe-outputs: |
| 186 | + resolve-pull-request-review-thread: |
| 187 | + max: 10 # max threads to resolve (default: 10) |
| 188 | + target: "triggering" # "triggering" (default), "*", or number |
| 189 | + target-repo: "owner/repo" # cross-repository |
| 190 | + allowed-repos: ["org/repo1", "org/repo2"] # additional allowed repositories |
| 191 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 192 | +``` |
| 193 | + |
| 194 | +See [Cross-Repository Operations](/gh-aw/reference/cross-repository/) for documentation on `target-repo`, `allowed-repos`, and cross-repository authentication. |
| 195 | + |
| 196 | +**Agent output format:** |
| 197 | + |
| 198 | +```json |
| 199 | +{"type": "resolve_pull_request_review_thread", "thread_id": "PRRT_kwDOABCD..."} |
| 200 | +``` |
| 201 | + |
89 | 202 | ## Push to PR Branch (`push-to-pull-request-branch:`) |
90 | 203 |
|
91 | 204 | Pushes changes to a PR's branch. Validates via `title-prefix` and `labels` to ensure only approved PRs receive changes. Multiple pushes per run are supported by setting `max` higher than 1. |
@@ -113,7 +226,25 @@ When `push-to-pull-request-branch` is configured, git commands (`checkout`, `bra |
113 | 226 |
|
114 | 227 | Like `create-pull-request`, pushes with GitHub Agentic Workflows do not trigger CI. See [Triggering CI](/gh-aw/reference/triggering-ci/) for how to enable automatic CI triggers. |
115 | 228 |
|
116 | | -### Compile-Time Warnings for `target: "*"` |
| 229 | +## Add Reviewer (`add-reviewer:`) |
| 230 | + |
| 231 | +Adds reviewers to pull requests. Specify `reviewers` to restrict to specific GitHub usernames. |
| 232 | + |
| 233 | +```yaml wrap |
| 234 | +safe-outputs: |
| 235 | + add-reviewer: |
| 236 | + reviewers: [user1, copilot] # restrict to specific reviewers |
| 237 | + max: 3 # max reviewers (default: 3) |
| 238 | + target: "*" # "triggering" (default), "*", or number |
| 239 | + target-repo: "owner/repo" # cross-repository |
| 240 | + github-token: ${{ secrets.SOME_CUSTOM_TOKEN }} # optional custom token for permissions |
| 241 | +``` |
| 242 | + |
| 243 | +**Target**: `"triggering"` (requires PR event), `"*"` (any PR), or number (specific PR). |
| 244 | + |
| 245 | +Use `reviewers: [copilot]` to assign the Copilot PR reviewer bot. See [Assign to Agent](/gh-aw/reference/assign-to-copilot/). |
| 246 | + |
| 247 | +## Compile-Time Warnings for `target: "*"` |
117 | 248 |
|
118 | 249 | When `target: "*"` is used, `gh aw compile` emits warnings for two common misconfigurations: |
119 | 250 |
|
|
0 commit comments