diff options
| author | Ryan Vogel <[email protected]> | 2026-02-09 18:15:06 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-09 18:15:06 -0500 |
| commit | 3118cab2d823920c507d82fa3e5120ddda951e12 (patch) | |
| tree | fe60a0c300f0f3ecfbd8b4c8f17babbe2424fb0e /.github/workflows/vouch-check-pr.yml | |
| parent | 31f893f8cb7cbec11ae743b4ead806c201a396b7 (diff) | |
| download | opencode-3118cab2d823920c507d82fa3e5120ddda951e12.tar.gz opencode-3118cab2d823920c507d82fa3e5120ddda951e12.zip | |
feat: integrate vouch & stricter issue trust management system (#12640)
Diffstat (limited to '.github/workflows/vouch-check-pr.yml')
| -rw-r--r-- | .github/workflows/vouch-check-pr.yml | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/.github/workflows/vouch-check-pr.yml b/.github/workflows/vouch-check-pr.yml new file mode 100644 index 000000000..470b8e0a5 --- /dev/null +++ b/.github/workflows/vouch-check-pr.yml @@ -0,0 +1,93 @@ +name: vouch-check-pr + +on: + pull_request_target: + types: [opened] + +permissions: + contents: read + pull-requests: write + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Check if PR author is denounced + uses: actions/github-script@v7 + with: + script: | + const author = context.payload.pull_request.user.login; + const prNumber = context.payload.pull_request.number; + + // Skip bots + if (author.endsWith('[bot]')) { + core.info(`Skipping bot: ${author}`); + return; + } + + // Read the VOUCHED.td file via API (no checkout needed) + let content; + try { + const response = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: '.github/VOUCHED.td', + }); + content = Buffer.from(response.data.content, 'base64').toString('utf-8'); + } catch (error) { + if (error.status === 404) { + core.info('No .github/VOUCHED.td file found, skipping check.'); + return; + } + throw error; + } + + // Parse the .td file for denounced users + 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(); + 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(); + + // Handle platform:username or bare username + // Only match bare usernames or github: prefix (skip other platforms) + const colonIdx = handle.indexOf(':'); + if (colonIdx !== -1) { + const platform = handle.slice(0, colonIdx).toLowerCase(); + if (platform !== 'github') continue; + } + const username = colonIdx === -1 ? handle : handle.slice(colonIdx + 1); + if (!username) continue; + + denounced.set(username.toLowerCase(), reason); + } + + // Check if the author is denounced + const reason = denounced.get(author.toLowerCase()); + if (reason === undefined) { + core.info(`User ${author} is not denounced. Allowing PR.`); + 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.', + }); + + 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}`); |
