Skip to content

Commit 9bfd5ad

Browse files
ci+docs: Add draft PR enforcement
Add workflow to auto-convert non-draft PRs to draft on open/reopen. Add Pull Requests section to CONTRIBUTING.md documenting the draft requirement and linking to the code submission standard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a5d04d6 commit 9bfd5ad

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Enforce Draft PR
2+
3+
on:
4+
pull_request_target:
5+
types: [opened, reopened]
6+
7+
permissions:
8+
pull-requests: write
9+
10+
jobs:
11+
enforce-draft:
12+
name: Enforce Draft PR
13+
runs-on: ubuntu-24.04
14+
if: github.event.pull_request.draft == false
15+
steps:
16+
- name: Convert PR to draft
17+
uses: actions/github-script@v7
18+
with:
19+
script: |
20+
const pullRequest = context.payload.pull_request;
21+
const repo = context.repo;
22+
23+
// Convert to draft via GraphQL (REST API doesn't support this)
24+
try {
25+
await github.graphql(`
26+
mutation($pullRequestId: ID!) {
27+
convertPullRequestToDraft(input: { pullRequestId: $pullRequestId }) {
28+
pullRequest {
29+
isDraft
30+
}
31+
}
32+
}
33+
`, {
34+
pullRequestId: pullRequest.node_id
35+
});
36+
} catch (error) {
37+
core.warning(`Failed to convert PR to draft: ${error.message}`);
38+
return;
39+
}
40+
41+
// Check for existing bot comment to avoid duplicates on reopen
42+
const comments = await github.rest.issues.listComments({
43+
...repo,
44+
issue_number: pullRequest.number,
45+
});
46+
const botComment = comments.data.find(c =>
47+
c.user.type === 'Bot' &&
48+
c.body.includes('automatically converted to draft')
49+
);
50+
if (botComment) {
51+
core.info('Bot comment already exists, skipping.');
52+
return;
53+
}
54+
55+
const contributingUrl = `https://github.com/${repo.owner}/${repo.repo}/blob/master/CONTRIBUTING.md`;
56+
57+
await github.rest.issues.createComment({
58+
...repo,
59+
issue_number: pullRequest.number,
60+
body: [
61+
`This PR has been automatically converted to draft. All PRs must start as drafts per our [contributing guidelines](${contributingUrl}).`,
62+
'',
63+
'**Next steps:**',
64+
'1. Ensure CI passes',
65+
'2. Fill in the PR description completely',
66+
'3. Mark as "Ready for review" when you\'re done'
67+
].join('\n')
68+
});

CONTRIBUTING.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ We will review your pull request as soon as possible. Thank you for contributing
2121

2222
You are welcome to use whatever tools you prefer for making a contribution. However, any changes you propose have to be reviewed and tested by you, a human, first, before you submit a pull request with them for the Sentry team to review. If we feel like that didn't happen, we will close the PR outright. For example, we won't review visibly AI-generated PRs from an agent instructed to look for and "fix" open issues in the repo.
2323

24+
## Pull Requests
25+
26+
All PRs must be created as **drafts**. Non-draft PRs will be automatically converted to draft. Mark your PR as "Ready for review" once:
27+
28+
- CI passes
29+
- The PR description is complete (what, why, and links to relevant issues)
30+
- You've personally reviewed your own changes
31+
32+
A PR should do one thing well. Don't mix functional changes with unrelated refactors or cleanup. Smaller, focused PRs are easier to review, reason about, and revert if needed.
33+
34+
For the full set of PR standards, see the [code submission standard](https://develop.sentry.dev/sdk/getting-started/standards/code-submission/#pull-requests).
35+
2436
## Development Environment
2537

2638
### Set up Python

0 commit comments

Comments
 (0)