mirror of
https://github.com/stalwartlabs/stalwart.git
synced 2026-08-19 08:01:08 +00:00
21ff8b15b4
Bumps [actions/github-script](https://github.com/actions/github-script) from 7 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](https://github.com/actions/github-script/compare/v7...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com>
132 lines
5.3 KiB
YAML
132 lines
5.3 KiB
YAML
name: Auto-close PRs from non-allowed authors
|
|
|
|
on:
|
|
pull_request_target:
|
|
types: [opened, reopened]
|
|
|
|
permissions:
|
|
pull-requests: write
|
|
issues: write
|
|
|
|
jobs:
|
|
auto-close:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
with:
|
|
sparse-checkout: .github/allowed-pr-authors.txt
|
|
sparse-checkout-cone-mode: false
|
|
|
|
- name: Close PRs from non-allowed authors
|
|
uses: actions/github-script@v9
|
|
with:
|
|
script: |
|
|
const fs = require('fs');
|
|
|
|
let allowedAuthors = [];
|
|
try {
|
|
allowedAuthors = fs.readFileSync('.github/allowed-pr-authors.txt', 'utf8')
|
|
.split('\n')
|
|
.map(line => line.trim())
|
|
.filter(line => line && !line.startsWith('#'))
|
|
.map(line => line.toLowerCase());
|
|
} catch (err) {
|
|
core.warning(`Could not read allowed-pr-authors.txt: ${err.message}`);
|
|
}
|
|
|
|
const pr = context.payload.pull_request;
|
|
const author = (pr.user && pr.user.login) || '';
|
|
const login = author.toLowerCase();
|
|
|
|
if (author.endsWith('[bot]')) {
|
|
core.info(`PR #${pr.number} opened by bot '${author}'. Skipping.`);
|
|
return;
|
|
}
|
|
|
|
if (allowedAuthors.includes(login)) {
|
|
core.info(`PR #${pr.number} opened by allowed author '${author}'. Skipping.`);
|
|
return;
|
|
}
|
|
|
|
const actor = (context.payload.sender && context.payload.sender.login) || '';
|
|
|
|
const isCollaborator = async (username) => {
|
|
if (!username) {
|
|
return false;
|
|
}
|
|
try {
|
|
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
username,
|
|
});
|
|
return perm.permission === 'admin' || perm.permission === 'write';
|
|
} catch (err) {
|
|
core.info(`Could not resolve collaborator permission for '${username}': ${err.message}`);
|
|
return false;
|
|
}
|
|
};
|
|
|
|
if (await isCollaborator(author)) {
|
|
core.info(`PR #${pr.number} author '${author}' is a collaborator. Skipping.`);
|
|
return;
|
|
}
|
|
|
|
if (actor.toLowerCase() !== login && await isCollaborator(actor)) {
|
|
core.info(`PR #${pr.number} action triggered by collaborator '${actor}'. Skipping.`);
|
|
return;
|
|
}
|
|
|
|
const contributingUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/blob/HEAD/CONTRIBUTING.md`;
|
|
|
|
const haystack = `${pr.title || ''}\n${pr.body || ''}`;
|
|
const aiPatterns = [
|
|
/[—―]/,
|
|
];
|
|
const looksAiGenerated = aiPatterns.some(re => re.test(haystack));
|
|
|
|
const aiMessage = [
|
|
`Hi @${author}, thanks for your interest in contributing.`,
|
|
``,
|
|
`This pull request is being **automatically closed and locked**. The description contains strong indicators of AI-generated content, and this project does not accept AI-generated code or unsolicited machine-authored contributions.`,
|
|
``,
|
|
`Please read [CONTRIBUTING.md](${contributingUrl}) to learn what kinds of contributions are currently accepted. If this is a genuine hand-written change that fits those guidelines, please open a discussion at **[support.stalw.art](https://support.stalw.art)** before submitting.`,
|
|
].join('\n');
|
|
|
|
const standardMessage = [
|
|
`Hi @${author}, thanks for taking the time to open this pull request.`,
|
|
``,
|
|
`This PR is being **automatically closed** because it was submitted by an author who is not on the list of approved contributors. This policy helps us keep review capacity focused and filter out unsolicited or low-quality contributions.`,
|
|
``,
|
|
`Please read [CONTRIBUTING.md](${contributingUrl}) to learn what kinds of contributions are currently accepted. If your change fits those guidelines, please first discuss it at our support portal: **[support.stalw.art](https://support.stalw.art)**. You can sign in with your existing GitHub account.`,
|
|
``,
|
|
`Thank you for understanding.`,
|
|
].join('\n');
|
|
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: pr.number,
|
|
body: looksAiGenerated ? aiMessage : standardMessage,
|
|
});
|
|
|
|
await github.rest.pulls.update({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
pull_number: pr.number,
|
|
state: 'closed',
|
|
});
|
|
|
|
if (looksAiGenerated) {
|
|
try {
|
|
await github.rest.issues.lock({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: pr.number,
|
|
lock_reason: 'spam',
|
|
});
|
|
} catch (err) {
|
|
core.warning(`Could not lock PR #${pr.number}: ${err.message}`);
|
|
}
|
|
}
|