ci: add contributor workflow automation

- Add PR template with description, type of change, and contributing checklist
- Enforce target branch: label + comment + 24h auto-close for PRs targeting main
- Flag bad issue titles: label + comment + 24h auto-close instead of instant close
- Redirect feature requests to Discussions (instant close, unchanged)
- Add two scheduled workflows to close stale labeled issues and PRs after 24h
- Update CONTRIBUTING.md with tests and branch up-to-date requirements
This commit is contained in:
jubnl
2026-04-09 01:18:08 +02:00
parent 504195a324
commit c13b28ae8f
6 changed files with 317 additions and 45 deletions
@@ -0,0 +1,66 @@
name: Close PRs with unchanged wrong base branch
on:
schedule:
- cron: '0 */6 * * *' # Every 6 hours
permissions:
pull-requests: write
issues: write
jobs:
close-stale:
runs-on: ubuntu-latest
steps:
- name: Close stale wrong-base-branch PRs
uses: actions/github-script@v7
with:
script: |
const { data: pulls } = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
per_page: 100,
});
const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
for (const pull of pulls) {
const hasLabel = pull.labels.some(l => l.name === 'wrong-base-branch');
if (!hasLabel) continue;
const createdAt = new Date(pull.created_at);
if (createdAt > twentyFourHoursAgo) continue; // grace period not over yet
// Base was fixed — remove label and move on
if (pull.base.ref !== 'main') {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pull.number,
name: 'wrong-base-branch',
});
continue;
}
// Still targeting main after 24h — close it
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pull.number,
body: [
'## PR closed',
'',
'This PR has been automatically closed because the base branch was not updated to `dev` within 24 hours.',
'',
'Feel free to open a new PR targeting `dev`.',
].join('\n'),
});
await github.rest.pulls.update({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
state: 'closed',
});
}