fix(coding-agent): guard undici install under Bun #1276
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Gate | |
| on: | |
| pull_request_target: | |
| types: [opened] | |
| jobs: | |
| check-contributor: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| steps: | |
| - name: Check if contributor is approved | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const APPROVED_FILE = '.github/APPROVED_CONTRIBUTORS'; | |
| const VALID_CAPABILITIES = new Set(['issue', 'pr']); | |
| const prAuthor = context.payload.pull_request.user.login; | |
| const defaultBranch = context.payload.repository.default_branch; | |
| if (prAuthor.endsWith('[bot]') || prAuthor === 'dependabot[bot]') { | |
| console.log(`Skipping bot: ${prAuthor}`); | |
| return; | |
| } | |
| async function getPermission(username) { | |
| try { | |
| const { data: permissionLevel } = await github.rest.repos.getCollaboratorPermissionLevel({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| username, | |
| }); | |
| return permissionLevel.permission; | |
| } catch { | |
| return null; | |
| } | |
| } | |
| async function getTextFile(path) { | |
| const { data: fileContent } = await github.rest.repos.getContent({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| path, | |
| ref: defaultBranch, | |
| }); | |
| if (!('content' in fileContent) || typeof fileContent.content !== 'string') { | |
| throw new Error(`Expected file content for ${path}`); | |
| } | |
| return Buffer.from(fileContent.content, 'base64').toString('utf8'); | |
| } | |
| function parseApprovedUsers(content) { | |
| const users = new Map(); | |
| for (const rawLine of content.split('\n')) { | |
| const line = rawLine.trim(); | |
| if (!line || line.startsWith('#')) continue; | |
| const parts = line.split(/\s+/); | |
| if (parts.length !== 2) { | |
| console.log(`Skipping malformed line: ${rawLine}`); | |
| continue; | |
| } | |
| const [username, capability] = parts; | |
| const normalizedCapability = capability.toLowerCase(); | |
| if (!VALID_CAPABILITIES.has(normalizedCapability)) { | |
| console.log(`Skipping line with invalid capability: ${rawLine}`); | |
| continue; | |
| } | |
| users.set(username.toLowerCase(), normalizedCapability); | |
| } | |
| return users; | |
| } | |
| async function closePullRequest(message) { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.payload.pull_request.number, | |
| body: message, | |
| }); | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: context.payload.pull_request.number, | |
| state: 'closed', | |
| }); | |
| } | |
| const permission = await getPermission(prAuthor); | |
| if (['admin', 'maintain', 'write'].includes(permission)) { | |
| console.log(`${prAuthor} is a collaborator with ${permission} access`); | |
| return; | |
| } | |
| const approvedContent = await getTextFile(APPROVED_FILE); | |
| const approvedUsers = parseApprovedUsers(approvedContent); | |
| const capability = approvedUsers.get(prAuthor.toLowerCase()); | |
| if (capability === 'pr') { | |
| console.log(`${prAuthor} is approved for PRs`); | |
| return; | |
| } | |
| console.log(`${prAuthor} is not approved, closing PR`); | |
| const message = [ | |
| 'This PR was auto-closed. Only contributors approved with `lgtm` can open PRs. Open an issue first.', | |
| '', | |
| `Maintainers review auto-closed issues daily. Issues that do not meet the quality bar in [CONTRIBUTING.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/${defaultBranch}/CONTRIBUTING.md) will not be reopened or receive a reply.`, | |
| '', | |
| 'If a maintainer replies `lgtmi`, your future issues will stay open. If a maintainer replies `lgtm`, your future issues and PRs will stay open.', | |
| '', | |
| `See [CONTRIBUTING.md](https://github.com/${context.repo.owner}/${context.repo.repo}/blob/${defaultBranch}/CONTRIBUTING.md).`, | |
| ].join('\n'); | |
| await closePullRequest(message); |