Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 0 additions & 72 deletions .github/workflows/enforce-draft-pr.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Close Unvetted Non-Maintainer PRs
name: Validate PR

on:
pull_request_target:
types: [opened]
types: [opened, reopened]

jobs:
validate-non-maintainer-pr:
Expand All @@ -11,6 +11,8 @@ jobs:
permissions:
pull-requests: write
contents: write
outputs:
was-closed: ${{ steps.validate.outputs.was-closed }}
steps:
- name: Generate GitHub App token
id: app-token
Expand All @@ -20,6 +22,7 @@ jobs:
private-key: ${{ secrets.SDK_MAINTAINER_BOT_PRIVATE_KEY }}

- name: Validate PR
id: validate
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
Expand Down Expand Up @@ -101,12 +104,12 @@ jobs:

core.info(`Found ${issueRefs.length} issue reference(s): ${[...seen].join(', ')}`);

// --- Helper: close PR with comment and label ---
async function closePR(message) {
// --- Helper: close PR with comment and labels ---
async function closePR(message, reasonLabel) {
await github.rest.issues.addLabels({
...repo,
issue_number: pullRequest.number,
labels: ['violating-contribution-guidelines'],
labels: ['violating-contribution-guidelines', reasonLabel],
});

await github.rest.issues.createComment({
Expand All @@ -120,6 +123,8 @@ jobs:
pull_number: pullRequest.number,
state: 'closed',
});

core.setOutput('was-closed', 'true');
}

// --- Step 3: No issue references ---
Expand All @@ -134,7 +139,7 @@ jobs:
'3. Once a maintainer has acknowledged your proposed approach, open a new PR referencing the issue',
'',
`Please review our [contributing guidelines](${contributingUrl}) for more details.`,
].join('\n'));
].join('\n'), 'missing-issue-reference');
return;
}

Expand Down Expand Up @@ -222,7 +227,7 @@ jobs:
'If you believe this assignment is outdated, please comment on the issue to discuss before opening a new PR.',
'',
`Please review our [contributing guidelines](${contributingUrl}) for more details.`,
].join('\n'));
].join('\n'), 'issue-already-assigned');
return;
}

Expand All @@ -234,7 +239,7 @@ jobs:
'To avoid wasted effort on both sides, please discuss your proposed approach in the issue first and wait for a maintainer to respond before opening a PR.',
'',
`Please review our [contributing guidelines](${contributingUrl}) for more details.`,
].join('\n'));
].join('\n'), 'missing-maintainer-discussion');
return;
}

Expand All @@ -249,4 +254,74 @@ jobs:
'3. Once a maintainer has acknowledged your proposed approach, open a new PR referencing the issue',
'',
`Please review our [contributing guidelines](${contributingUrl}) for more details.`,
].join('\n'));
].join('\n'), 'missing-issue-reference');

enforce-draft:
name: Enforce Draft PR
needs: [validate-non-maintainer-pr]
if: |
always()
&& github.event.pull_request.draft == false
&& needs.validate-non-maintainer-pr.outputs.was-closed != 'true'
runs-on: ubuntu-24.04
permissions:
pull-requests: write
contents: write
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v2
with:
app-id: ${{ vars.SDK_MAINTAINER_BOT_APP_ID }}
private-key: ${{ secrets.SDK_MAINTAINER_BOT_PRIVATE_KEY }}

- name: Convert PR to draft
env:
GH_TOKEN: ${{github.token}}
PR_URL: ${{ github.event.pull_request.html_url }}
run: |
gh pr ready "$PR_URL" --undo

- name: Label and comment
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ steps.app-token.outputs.token }}
script: |
const pullRequest = context.payload.pull_request;
const repo = context.repo;

// Label the PR so maintainers can filter/track violations
await github.rest.issues.addLabels({
...repo,
issue_number: pullRequest.number,
labels: ['converted-to-draft'],
});

// Check for existing bot comment to avoid duplicates on reopen
const comments = await github.rest.issues.listComments({
...repo,
issue_number: pullRequest.number,
});
const botComment = comments.data.find(c =>
c.user.type === 'Bot' &&
c.body.includes('automatically converted to draft')
);
if (botComment) {
core.info('Bot comment already exists, skipping.');
return;
}

const contributingUrl = `https://github.com/${repo.owner}/${repo.repo}/blob/master/CONTRIBUTING.md`;

await github.rest.issues.createComment({
...repo,
issue_number: pullRequest.number,
body: [
`This PR has been automatically converted to draft. All PRs must start as drafts per our [contributing guidelines](${contributingUrl}).`,
'',
'**Next steps:**',
'1. Ensure CI passes',
'2. Fill in the PR description completely',
'3. Mark as "Ready for review" when you\'re done'
].join('\n')
});
Loading