summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRyan Vogel <[email protected]>2026-02-25 09:42:52 -0500
committeropencode <[email protected]>2026-02-25 14:56:03 +0000
commite48c1ccf0714a2a78a8bbf27e8ade0b8bcbdcf3b (patch)
tree57b1877ae7770cc2263398b3bb0a6c78f7f2f480
parent5e5823ed85ff83e1e3461b861fb582f27cc38969 (diff)
downloadopencode-e48c1ccf0714a2a78a8bbf27e8ade0b8bcbdcf3b.tar.gz
opencode-e48c1ccf0714a2a78a8bbf27e8ade0b8bcbdcf3b.zip
chore(workflows): label vouched users and restrict vouch managers (#15075)
-rw-r--r--.github/workflows/vouch-check-issue.yml58
-rw-r--r--.github/workflows/vouch-check-pr.yml55
-rw-r--r--.github/workflows/vouch-manage-by-issue.yml1
3 files changed, 78 insertions, 36 deletions
diff --git a/.github/workflows/vouch-check-issue.yml b/.github/workflows/vouch-check-issue.yml
index 94569f473..4c2aa960b 100644
--- a/.github/workflows/vouch-check-issue.yml
+++ b/.github/workflows/vouch-check-issue.yml
@@ -42,15 +42,17 @@ jobs:
throw error;
}
- // Parse the .td file for denounced users
+ // Parse the .td file for vouched and denounced users
+ const vouched = new Set();
const denounced = new Map();
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
- if (!trimmed.startsWith('-')) continue;
- const rest = trimmed.slice(1).trim();
+ const isDenounced = trimmed.startsWith('-');
+ const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
if (!rest) continue;
+
const spaceIdx = rest.indexOf(' ');
const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();
@@ -65,32 +67,50 @@ jobs:
const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
if (!username) continue;
- denounced.set(username.toLowerCase(), reason);
+ if (isDenounced) {
+ denounced.set(username.toLowerCase(), reason);
+ continue;
+ }
+
+ vouched.add(username.toLowerCase());
}
// Check if the author is denounced
const reason = denounced.get(author.toLowerCase());
- if (reason === undefined) {
- core.info(`User ${author} is not denounced. Allowing issue.`);
+ if (reason !== undefined) {
+ // Author is denounced — close the issue
+ const body = 'This issue has been automatically closed.';
+
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issueNumber,
+ body,
+ });
+
+ await github.rest.issues.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: issueNumber,
+ state: 'closed',
+ state_reason: 'not_planned',
+ });
+
+ core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
return;
}
- // Author is denounced — close the issue
- const body = 'This issue has been automatically closed.';
-
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issueNumber,
- body,
- });
+ // Author is positively vouched — add label
+ if (!vouched.has(author.toLowerCase())) {
+ core.info(`User ${author} is not denounced or vouched. Allowing issue.`);
+ return;
+ }
- await github.rest.issues.update({
+ await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issueNumber,
- state: 'closed',
- state_reason: 'not_planned',
+ labels: ['Vouched'],
});
- core.info(`Closed issue #${issueNumber} from denounced user ${author}`);
+ core.info(`Added vouched label to issue #${issueNumber} from ${author}`);
diff --git a/.github/workflows/vouch-check-pr.yml b/.github/workflows/vouch-check-pr.yml
index 470b8e0a5..51816dfb7 100644
--- a/.github/workflows/vouch-check-pr.yml
+++ b/.github/workflows/vouch-check-pr.yml
@@ -6,6 +6,7 @@ on:
permissions:
contents: read
+ issues: write
pull-requests: write
jobs:
@@ -42,15 +43,17 @@ jobs:
throw error;
}
- // Parse the .td file for denounced users
+ // Parse the .td file for vouched and denounced users
+ const vouched = new Set();
const denounced = new Map();
for (const line of content.split('\n')) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
- if (!trimmed.startsWith('-')) continue;
- const rest = trimmed.slice(1).trim();
+ const isDenounced = trimmed.startsWith('-');
+ const rest = isDenounced ? trimmed.slice(1).trim() : trimmed;
if (!rest) continue;
+
const spaceIdx = rest.indexOf(' ');
const handle = spaceIdx === -1 ? rest : rest.slice(0, spaceIdx);
const reason = spaceIdx === -1 ? null : rest.slice(spaceIdx + 1).trim();
@@ -65,29 +68,47 @@ jobs:
const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1);
if (!username) continue;
- denounced.set(username.toLowerCase(), reason);
+ if (isDenounced) {
+ denounced.set(username.toLowerCase(), reason);
+ continue;
+ }
+
+ vouched.add(username.toLowerCase());
}
// Check if the author is denounced
const reason = denounced.get(author.toLowerCase());
- if (reason === undefined) {
- core.info(`User ${author} is not denounced. Allowing PR.`);
+ if (reason !== undefined) {
+ // Author is denounced — close the PR
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: prNumber,
+ body: 'This pull request has been automatically closed.',
+ });
+
+ await github.rest.pulls.update({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ pull_number: prNumber,
+ state: 'closed',
+ });
+
+ core.info(`Closed PR #${prNumber} from denounced user ${author}`);
return;
}
- // Author is denounced — close the PR
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: prNumber,
- body: 'This pull request has been automatically closed.',
- });
+ // Author is positively vouched — add label
+ if (!vouched.has(author.toLowerCase())) {
+ core.info(`User ${author} is not denounced or vouched. Allowing PR.`);
+ return;
+ }
- await github.rest.pulls.update({
+ await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
- pull_number: prNumber,
- state: 'closed',
+ issue_number: prNumber,
+ labels: ['Vouched'],
});
- core.info(`Closed PR #${prNumber} from denounced user ${author}`);
+ core.info(`Added vouched label to PR #${prNumber} from ${author}`);
diff --git a/.github/workflows/vouch-manage-by-issue.yml b/.github/workflows/vouch-manage-by-issue.yml
index cf0524c21..9604bf87f 100644
--- a/.github/workflows/vouch-manage-by-issue.yml
+++ b/.github/workflows/vouch-manage-by-issue.yml
@@ -33,5 +33,6 @@ jobs:
with:
issue-id: ${{ github.event.issue.number }}
comment-id: ${{ github.event.comment.id }}
+ roles: admin,maintain
env:
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}