From af39aac1a211e932944f181f9dbbdea74f972371 Mon Sep 17 00:00:00 2001 From: boykopovar Date: Fri, 9 Oct 2026 19:46:43 +0300 Subject: [PATCH] ci(prs): close prs from new contributors while intake is paused --- .github/workflows/labels.yml | 1 + .github/workflows/pr-intake.yml | 64 +++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 .github/workflows/pr-intake.yml diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml index 3429cb6ff..58741d09c 100644 --- a/.github/workflows/labels.yml +++ b/.github/workflows/labels.yml @@ -23,6 +23,7 @@ jobs: force_label() { gh label create "$1" --color "$2" --description "$3" --force; } force_label 'needs rebase' b60205 'Conflicts with main, rebase needed' + force_label 'intake paused' d93f0b 'Closed while PR intake from new contributors is paused' force_label ci 5319e7 '.github' force_label agc 1d76db 'libSceAgc*' force_label shader 1d76db 'core/shader' diff --git a/.github/workflows/pr-intake.yml b/.github/workflows/pr-intake.yml new file mode 100644 index 000000000..0fc4c2c5b --- /dev/null +++ b/.github/workflows/pr-intake.yml @@ -0,0 +1,64 @@ +name: PR intake + +on: + pull_request_target: + branches: [main] + types: [opened] + +permissions: {} + +concurrency: + group: pr-intake-${{ github.event.pull_request.number }} + +jobs: + intake: + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + contents: read + issues: write + pull-requests: write + steps: + - uses: actions/github-script@v8 + with: + script: | + const { owner, repo } = context.repo; + const pull_number = context.payload.pull_request.number; + const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number }); + if (pr.state !== 'open' || pr.base.ref !== 'main') { + return; + } + const { data: commits } = await github.rest.repos.listCommits({ + owner, repo, sha: 'main', author: pr.user.login, per_page: 1 + }); + if (commits.length > 0) { + return; + } + const name = 'intake paused'; + try { + await github.rest.issues.getLabel({ owner, repo, name }); + } catch (error) { + if (error.status !== 404) { + throw error; + } + try { + await github.rest.issues.createLabel({ + owner, repo, name, color: 'd93f0b', + description: 'Closed while PR intake from new contributors is paused' + }); + } catch (createError) { + if (createError.status !== 422) { + throw createError; + } + await github.rest.issues.getLabel({ owner, repo, name }); + } + } + await github.rest.issues.addLabels({ owner, repo, issue_number: pull_number, labels: [name] }); + const body = 'Спасибо за ваш интерес к проекту! Извините, сейчас накопилось слишком много открытых PR. Пока мы разбираемся с ними, приём PR от новых участников - авторов, чьих коммитов ещё нет в `main`, - временно приостановлен. Поэтому этот PR автоматически закрыт. Это не оценка качества ваших изменений.'; + const comments = await github.paginate(github.rest.issues.listComments, { + owner, repo, issue_number: pull_number, per_page: 100 + }); + if (!comments.some((comment) => comment.user.login === 'github-actions[bot]' && comment.body === body)) { + await github.rest.issues.createComment({ owner, repo, issue_number: pull_number, body }); + } + await github.rest.pulls.update({ owner, repo, pull_number, state: 'closed' });