mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-16 05:20:22 +08:00
113 lines
4.4 KiB
YAML
113 lines
4.4 KiB
YAML
name: Vouch Check
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, reopened]
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
|
|
jobs:
|
|
vouch-gate:
|
|
if: github.repository_owner == 'NVIDIA'
|
|
runs-on: ubuntu-latest
|
|
env:
|
|
ORG_READ_TOKEN: ${{ secrets.ORG_READ_TOKEN }}
|
|
steps:
|
|
- name: Check org membership
|
|
id: org-check
|
|
if: env.ORG_READ_TOKEN != ''
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
|
with:
|
|
github-token: ${{ secrets.ORG_READ_TOKEN }}
|
|
result-encoding: string
|
|
script: |
|
|
const author = context.payload.pull_request.user.login;
|
|
try {
|
|
const { status } = await github.rest.orgs.checkMembershipForUser({
|
|
org: context.repo.owner,
|
|
username: author,
|
|
});
|
|
if (status === 204 || status === 302) {
|
|
console.log(`${author} is an org member. Skipping vouch check.`);
|
|
return 'skip';
|
|
}
|
|
} catch (e) {
|
|
if (e.status !== 404) {
|
|
console.log(`Org membership check error (status=${e.status}): ${e.message}`);
|
|
}
|
|
}
|
|
return '';
|
|
|
|
- name: Check if contributor is vouched
|
|
if: steps.org-check.outputs.result != 'skip'
|
|
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
|
with:
|
|
script: |
|
|
const author = context.payload.pull_request.user.login;
|
|
const authorType = context.payload.pull_request.user.type;
|
|
|
|
// Skip bots (dependabot, renovate, github-actions, etc.).
|
|
if (authorType === 'Bot') {
|
|
console.log(`${author} is a bot. Skipping vouch check.`);
|
|
return;
|
|
}
|
|
|
|
// Check the VOUCHED.td file on the dedicated "vouched" branch.
|
|
// NOT the PR branch — the PR author could add themselves in their fork.
|
|
let vouched = false;
|
|
try {
|
|
const { data } = await github.rest.repos.getContent({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
path: '.github/VOUCHED.td',
|
|
ref: 'vouched',
|
|
});
|
|
const content = Buffer.from(data.content, 'base64').toString('utf-8');
|
|
const usernames = content
|
|
.split('\n')
|
|
.map(line => line.trim())
|
|
.filter(line => line && !line.startsWith('#') && !line.startsWith('-'));
|
|
vouched = usernames.some(
|
|
name => name.toLowerCase() === author.toLowerCase()
|
|
);
|
|
} catch (e) {
|
|
console.log(`Could not read VOUCHED.td: ${e.message}`);
|
|
}
|
|
|
|
if (vouched) {
|
|
console.log(`${author} is in VOUCHED.td. Approved.`);
|
|
return;
|
|
}
|
|
|
|
// Not vouched — close the PR with an explanation.
|
|
console.log(`${author} is not vouched. Closing PR.`);
|
|
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.payload.pull_request.number,
|
|
body: [
|
|
`Thank you for your interest in contributing to OpenShell, @${author}.`,
|
|
'',
|
|
'This project uses a **vouch system** for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer.',
|
|
'',
|
|
'**To get vouched:**',
|
|
'1. Open a [Vouch Request](https://github.com/NVIDIA/OpenShell/discussions/new?category=vouch-request) discussion.',
|
|
'2. Describe what you want to change and why.',
|
|
'3. Write in your own words — do not have an AI generate the request.',
|
|
'4. A maintainer will comment `/vouch` if approved.',
|
|
'5. Once vouched, open a new PR (preferred) or reopen this one after a few minutes.',
|
|
'',
|
|
'See [CONTRIBUTING.md](https://github.com/NVIDIA/OpenShell/blob/main/CONTRIBUTING.md#first-time-contributors) for details.',
|
|
].join('\n'),
|
|
});
|
|
|
|
await github.rest.pulls.update({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: context.payload.pull_request.number,
|
|
state: 'closed',
|
|
});
|