aboutsummaryrefslogtreecommitdiff
path: root/.github/workflows
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-29 02:54:38 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-29 02:54:53 +0300
commit73d92004f50d3f5fafe64e0f9b7fddbcf4d99965 (patch)
tree73038acf832d0595d7deca6fc26b66bc1bd0a3ff /.github/workflows
parenta5920bee86f47023b74133dad7464b07af77ce69 (diff)
ci: remove approved contributor bypass
Diffstat (limited to '.github/workflows')
-rw-r--r--.github/workflows/approve-contributor.yml114
-rw-r--r--.github/workflows/approve-merged-contributor.yml64
-rw-r--r--.github/workflows/ci.yml1
-rw-r--r--.github/workflows/pr-gate.yml27
4 files changed, 8 insertions, 198 deletions
diff --git a/.github/workflows/approve-contributor.yml b/.github/workflows/approve-contributor.yml
deleted file mode 100644
index 28a6914d..00000000
--- a/.github/workflows/approve-contributor.yml
+++ /dev/null
@@ -1,114 +0,0 @@
-name: Approve Contributor
-
-on:
- issue_comment:
- types: [created, edited]
-
-jobs:
- approve:
- if: ${{ !github.event.issue.pull_request && github.event.comment.user.login != 'kangal-bot' }}
- runs-on: ubuntu-latest
- permissions:
- contents: read
- steps:
- - name: Checkout
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- with:
- ref: ${{ github.event.repository.default_branch }}
- persist-credentials: false
-
- - name: Add contributor to approved list
- id: update
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
- with:
- github-token: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- script: |
- const fs = require('fs');
-
- const issueAuthor = context.payload.issue.user.login;
- const commenter = context.payload.comment.user.login;
- const commentBody = context.payload.comment.body || '';
- const action = context.payload.action;
- const approvedFile = '.github/APPROVED_CONTRIBUTORS';
- const approveMatch = commentBody.match(/(^|\s)\/approve(?:\s+@([A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?))?(?=$|\s)/i);
- const maintainerPermissions = ['admin', 'maintain', 'write'];
-
- if (!approveMatch) {
- console.log('Comment does not contain /approve');
- core.setOutput('status', 'skipped');
- return;
- }
-
- const approvedUser = approveMatch[2] || issueAuthor;
- core.setOutput('approved_user', approvedUser);
-
- try {
- const { data: permissionLevel } = await github.rest.repos.getCollaboratorPermissionLevel({
- owner: context.repo.owner,
- repo: context.repo.repo,
- username: commenter,
- });
-
- if (!maintainerPermissions.includes(permissionLevel.permission)) {
- console.log(`${commenter} does not have maintainer access`);
- core.setOutput('status', 'skipped');
- return;
- }
- } catch (error) {
- console.log(`${commenter} does not have collaborator access`);
- core.setOutput('status', 'skipped');
- return;
- }
-
- let content = fs.readFileSync(approvedFile, 'utf8');
- const approvedList = content
- .split('\n')
- .map(line => line.trim().toLowerCase())
- .filter(line => line && !line.startsWith('#'));
-
- if (approvedList.includes(approvedUser.toLowerCase())) {
- console.log(`${approvedUser} is already approved`);
- if (action === 'edited') {
- core.setOutput('status', 'skipped');
- return;
- }
- core.setOutput('status', 'already');
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.issue.number,
- body: `@${approvedUser} is already in the approved contributors list.`,
- });
- return;
- }
-
- content = content.trimEnd() + '\n' + approvedUser + '\n';
- fs.writeFileSync(approvedFile, content);
-
- console.log(`Added ${approvedUser} to approved contributors`);
- core.setOutput('status', 'added');
-
- - name: Commit and push
- if: steps.update.outputs.status == 'added'
- env:
- KANGAL_GITHUB_TOKEN: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- run: |
- git config user.name "kangal-bot"
- git config user.email "285672167+kangal-bot@users.noreply.github.com"
- git add .github/APPROVED_CONTRIBUTORS
- git diff --staged --quiet || git commit -m "chore: approve contributor ${{ steps.update.outputs.approved_user }}"
- git push "https://x-access-token:${KANGAL_GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:${{ github.event.repository.default_branch }}
-
- - name: Comment on issue
- if: steps.update.outputs.status == 'added'
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
- with:
- github-token: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- script: |
- const approvedUser = '${{ steps.update.outputs.approved_user }}';
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: context.issue.number,
- body: `@${approvedUser} has been added to the approved contributors list. You can now submit PRs for maintainer-approved work. Thanks for contributing!`,
- });
diff --git a/.github/workflows/approve-merged-contributor.yml b/.github/workflows/approve-merged-contributor.yml
deleted file mode 100644
index 6bcec009..00000000
--- a/.github/workflows/approve-merged-contributor.yml
+++ /dev/null
@@ -1,64 +0,0 @@
-name: Approve Merged Contributor
-
-on:
- pull_request_target:
- types: [closed]
-
-jobs:
- approve:
- if: ${{ github.event.pull_request.merged == true }}
- runs-on: ubuntu-latest
- permissions:
- contents: read
- steps:
- - name: Checkout
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
- with:
- ref: ${{ github.event.repository.default_branch }}
- persist-credentials: false
-
- - name: Add merged contributor to approved list
- id: update
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
- with:
- github-token: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- script: |
- const fs = require('fs');
-
- const prAuthor = context.payload.pull_request.user.login;
- const approvedFile = '.github/APPROVED_CONTRIBUTORS';
-
- if (prAuthor.endsWith('[bot]') || prAuthor === 'dependabot[bot]') {
- console.log(`Skipping bot: ${prAuthor}`);
- core.setOutput('status', 'skipped');
- return;
- }
-
- let content = fs.readFileSync(approvedFile, 'utf8');
- const approvedList = content
- .split('\n')
- .map(line => line.trim().toLowerCase())
- .filter(line => line && !line.startsWith('#'));
-
- if (approvedList.includes(prAuthor.toLowerCase())) {
- console.log(`${prAuthor} is already approved`);
- core.setOutput('status', 'already');
- return;
- }
-
- content = content.trimEnd() + '\n' + prAuthor + '\n';
- fs.writeFileSync(approvedFile, content);
-
- console.log(`Added ${prAuthor} to approved contributors`);
- core.setOutput('status', 'added');
-
- - name: Commit and push
- if: steps.update.outputs.status == 'added'
- env:
- KANGAL_GITHUB_TOKEN: ${{ secrets.KANGAL_GITHUB_TOKEN }}
- run: |
- git config user.name "kangal-bot"
- git config user.email "285672167+kangal-bot@users.noreply.github.com"
- git add .github/APPROVED_CONTRIBUTORS
- git diff --staged --quiet || git commit -m "chore: approve merged contributor ${{ github.event.pull_request.user.login }}"
- git push "https://x-access-token:${KANGAL_GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" HEAD:${{ github.event.repository.default_branch }}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 16fc5c2f..912ff332 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -7,7 +7,6 @@ on:
branches: [master, windows]
paths-ignore:
- "website/**"
- - ".github/APPROVED_CONTRIBUTORS"
permissions:
contents: read
diff --git a/.github/workflows/pr-gate.yml b/.github/workflows/pr-gate.yml
index 192168ad..6d2e25be 100644
--- a/.github/workflows/pr-gate.yml
+++ b/.github/workflows/pr-gate.yml
@@ -23,8 +23,8 @@ jobs:
49699333, // dependabot[bot]
41898282, // github-actions[bot]
]);
- const MAX_UNAPPROVED_CHANGED_FILES = 20;
- const MAX_UNAPPROVED_CHANGED_LINES = 1000;
+ const MAX_EXTERNAL_CHANGED_FILES = 20;
+ const MAX_EXTERNAL_CHANGED_LINES = 1000;
const REVIEW_LABELS = ['greptile-review', 'coderabbit-review'];
const MAINTAINER_APPROVED_LABEL = 'maintainer-approved';
const COMMENT_MARKER = '<!-- herdr:pr-gate -->';
@@ -88,12 +88,7 @@ jobs:
.filter(line => line && !line.startsWith('#')));
}
- const [maintainersContent, approvedContent] = await Promise.all([
- getTextFile('.github/MAINTAINERS'),
- getTextFile('.github/APPROVED_CONTRIBUTORS'),
- ]);
- const maintainers = parseUserList(maintainersContent);
- const approvedContributors = parseUserList(approvedContent);
+ const maintainers = parseUserList(await getTextFile('.github/MAINTAINERS'));
async function isVerifiedMaintainer(username) {
if (!username || !maintainers.has(username.toLowerCase())) return false;
@@ -183,11 +178,11 @@ jobs:
const message = [
`Hi @${prAuthor}, thanks for your interest in contributing!`,
'',
- `Herdr automatically admits focused bug fixes from unapproved contributors when the title uses \`fix: ...\` or \`fix(scope): ...\` and the patch changes no more than ${MAX_UNAPPROVED_CHANGED_FILES} files and ${MAX_UNAPPROVED_CHANGED_LINES.toLocaleString('en-US')} total added or deleted lines.`,
+ `Herdr automatically admits focused bug fixes from contributors who are not maintainers when the title uses \`fix: ...\` or \`fix(scope): ...\` and the patch changes no more than ${MAX_EXTERNAL_CHANGED_FILES} files and ${MAX_EXTERNAL_CHANGED_LINES.toLocaleString('en-US')} total added or deleted lines.`,
'',
reason,
'',
- 'Feature requests, behavior changes, and other proposals belong in GitHub Discussions and require maintainer approval before a pull request. Membership in `.github/APPROVED_CONTRIBUTORS` bypasses this automatic intake gate, but does not grant maintainer authority or guarantee that a change will be accepted.',
+ 'Feature requests, behavior changes, and other proposals belong in GitHub Discussions and require maintainer approval before a pull request.',
'',
'If this gate classified the pull request incorrectly, reply and tag a maintainer listed in `.github/MAINTAINERS`. A verified maintainer can reopen it; reopening by anyone else will be closed again automatically.',
'',
@@ -233,12 +228,6 @@ jobs:
return;
}
- if (approvedContributors.has(prAuthor.toLowerCase())) {
- core.info(`${prAuthor} is in the approved contributors list`);
- await addReviewLabels();
- return;
- }
-
if ((await currentLabels()).has(MAINTAINER_APPROVED_LABEL)) {
core.info(`PR #${pullNumber} has a maintainer scope override`);
await addReviewLabels();
@@ -248,13 +237,13 @@ jobs:
const hasFixTitle = /^fix(?:\([^)]+\))?:\s+\S/.test(pr.title);
if (!hasFixTitle) {
await closePullRequest(
- 'Unapproved contributors may submit only focused bug fixes. If this pull request fixes a bug, rename it to use a conventional `fix: ...` or `fix(scope): ...` title, then tag a maintainer to review and reopen it.',
+ 'Contributors who are not maintainers may submit only focused bug fixes. If this pull request fixes a bug, rename it to use a conventional `fix: ...` or `fix(scope): ...` title, then tag a maintainer to review and reopen it.',
);
return;
}
- const exceedsBudget = pr.changed_files > MAX_UNAPPROVED_CHANGED_FILES ||
- changedLines > MAX_UNAPPROVED_CHANGED_LINES;
+ const exceedsBudget = pr.changed_files > MAX_EXTERNAL_CHANGED_FILES ||
+ changedLines > MAX_EXTERNAL_CHANGED_LINES;
if (exceedsBudget) {
await closePullRequest('The current patch exceeds the automatic intake budget and needs maintainer alignment before review.');
return;