Skip to content

Commit ceb793f

Browse files
committed
Update README for v1.1.2 permission validation
- Move usage examples to job-level permissions (not top-level) - Document the new upfront permission validation step - Update verification strategy and required permissions sections - Note that v1.1.2+ gives clear error messages for missing permissions
1 parent 9e80d38 commit ceb793f

1 file changed

Lines changed: 42 additions & 25 deletions

File tree

README.md

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ review once all required checks pass.
1111
## How it works
1212

1313
1. You open a draft PR and add a trigger label (default: `Mark Ready When Ready`)
14-
2. The action checks preconditions — if the PR isn't a draft or doesn't have the
14+
2. The action validates that the token has all required permissions upfront — if
15+
anything is missing, it fails immediately with a clear error showing the exact
16+
`permissions:` block to add
17+
3. It checks preconditions — if the PR isn't a draft or doesn't have the
1518
label, it exits immediately with `result=skipped`
16-
3. If the repo has no required checks configured, the action skips gracefully
17-
4. Otherwise, it watches for all required checks to complete successfully
18-
5. It pauses briefly, then watches again to catch any late-arriving checks
19-
6. It verifies results via the GitHub GraphQL API (paginated, handles large check suites)
20-
7. It confirms the PR has no merge conflicts
21-
8. If everything looks good, it marks the PR as ready for review and removes the label
19+
4. If the repo has no required checks configured, the action skips gracefully
20+
5. Otherwise, it watches for all required checks to complete successfully
21+
6. It pauses briefly, then watches again to catch any late-arriving checks
22+
7. It verifies results via the GitHub GraphQL API (paginated, handles large check suites)
23+
8. It confirms the PR has no merge conflicts
24+
9. If everything looks good, it marks the PR as ready for review and removes the label
2225

2326
This is especially useful for repos with long CI suites — open your PR as a
2427
draft, slap on the label, and walk away. The PR will be marked ready for review
@@ -33,32 +36,33 @@ on:
3336
pull_request:
3437
types: [opened, edited, labeled, unlabeled, synchronize]
3538

36-
permissions:
37-
checks: read
38-
contents: write
39-
pull-requests: write
40-
statuses: read
41-
4239
concurrency:
4340
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
4441
cancel-in-progress: true
4542

4643
jobs:
4744
mark-ready:
4845
runs-on: ubuntu-latest
46+
permissions:
47+
checks: read
48+
contents: write
49+
pull-requests: write
50+
statuses: read
4951
steps:
5052
- uses: kenyonj/mark-ready-when-ready@v1
5153
with:
5254
github-token: ${{ secrets.GITHUB_TOKEN }}
5355
```
5456
55-
That's it. The action checks for the trigger label and draft status
56-
internally — if the PR isn't a draft or doesn't have the label, the action
57-
exits immediately with `result=skipped`.
57+
That's it. The action validates permissions upfront, checks for the trigger
58+
label and draft status internally — if anything isn't right, you'll get a
59+
clear error message or the action exits with `result=skipped`.
5860

59-
> **Important:** The workflow must include `contents: write` — without it,
60-
> `GITHUB_TOKEN` cannot call the `markPullRequestReadyForReview` GraphQL
61-
> mutation and will fail with `Resource not accessible by integration`.
61+
> **Important:** The workflow must include `contents: write` at the **job
62+
> level** — without it, `GITHUB_TOKEN` cannot call the
63+
> `markPullRequestReadyForReview` GraphQL mutation and will fail with
64+
> `Resource not accessible by integration`. As of v1.1.2, the action validates
65+
> permissions upfront and will tell you exactly what's missing.
6266

6367
### Saving runner costs with a job-level guard
6468

@@ -75,6 +79,11 @@ cost:
7579
jobs:
7680
mark-ready:
7781
runs-on: ubuntu-latest
82+
permissions:
83+
checks: read
84+
contents: write
85+
pull-requests: write
86+
statuses: read
7887
if: |
7988
contains(github.event.pull_request.labels.*.name, 'Mark Ready When Ready') &&
8089
github.event.pull_request.draft == true
@@ -143,21 +152,29 @@ permissions:
143152
> **Note:** `contents: write` is required even though the action doesn't modify
144153
> repository contents. Without it, `GITHUB_TOKEN` cannot call the
145154
> `markPullRequestReadyForReview` GraphQL mutation.
155+
>
156+
> As of v1.1.2, the action validates these permissions at the start of every run.
157+
> If any are missing, it fails immediately with a clear error message showing the
158+
> exact `permissions:` block to add to your workflow. Permissions should be set at
159+
> the **job level**, not the top-level workflow `permissions:` key.
146160

147161
## Verification strategy
148162

149163
The action uses a "trust but verify" approach:
150164

151-
1. **Precondition check** — exits early if the PR isn't a draft or the trigger
165+
1. **Permission validation** — verifies the token has all required permissions
166+
(`contents:write`, `pull-requests:write`, `checks:read`, `statuses:read`)
167+
and fails fast with an actionable error message if any are missing
168+
2. **Precondition check** — exits early if the PR isn't a draft or the trigger
152169
label isn't present
153-
2. **`gh pr checks --watch`** watches for required checks to complete (skips
170+
3. **`gh pr checks --watch`** watches for required checks to complete (skips
154171
gracefully if no required checks are configured)
155-
3. A configurable **pause** catches checks that are re-triggered or start late
156-
4. **`gh pr checks --watch`** runs again to confirm everything is still green
157-
5. A **GraphQL query** independently verifies that no required check suites have
172+
4. A configurable **pause** catches checks that are re-triggered or start late
173+
5. **`gh pr checks --watch`** runs again to confirm everything is still green
174+
6. A **GraphQL query** independently verifies that no required check suites have
158175
failing conclusions (`ACTION_REQUIRED`, `TIMED_OUT`, `CANCELLED`, `FAILURE`,
159176
`STARTUP_FAILURE`) and no required commit statuses are in a `FAILURE` state
160-
6. The **mergeable state** is checked to ensure the PR doesn't have conflicts
177+
7. The **mergeable state** is checked to ensure the PR doesn't have conflicts
161178

162179
This multi-layered approach prevents marking a PR as ready when there are
163180
transient or late-arriving failures.

0 commit comments

Comments
 (0)