Files
TREK/.github/workflows/close-stale-wrong-branch.yml
T
Maurice 4cfe6b59ba ci: move every workflow off Node 20 actions, pin the third-party ones, add Dependabot
security.yml, lint-prettier.yml and the release workflows still ran
actions built for Node 20 (checkout and setup-node v4, github-script v7,
the docker actions v3/v5, create-github-app-token v1), which GitHub now
forces onto Node 24 with a deprecation warning on every run. They move
to the Node 24 majors test.yml already uses (download-artifact to v7,
since v6 is still Node 20). Third-party actions, several of which hold
the Docker Hub and GitHub App secrets, are pinned by commit with the tag
in a comment. ubuntu-latest moves to a new Ubuntu release on 10-19, so
every job names ubuntu-24.04 and the switch happens in a PR. Every
setup-node reads .nvmrc; publish-plugin-sdk leaves 22, which it ran
under a comment claiming it matched the server.

security.yml gains an npm audit job over the lockfile, on PRs and pushes
into dev as well as main. It covers what the image installs and the
plugin SDK, takes seconds, and would have flagged the brace-expansion
regression the ORM squash brought in the day it landed. Scout keeps its
image scan on main. Neither becomes a required check: a CVE published
overnight would turn every open PR red, including the ones that cannot
fix it. The scout job now also skips PRs into dev, which the trigger
change would otherwise hand it.

.github/dependabot.yml adds weekly version updates into dev for the root
workspace, plugin-sdk, the actions and the Docker base images, minor and
patch grouped per ecosystem, majors one PR each. The Node major in the
Dockerfile is left to a hand-made change together with .nvmrc.
2026-10-08 13:04:43 +02:00

96 lines
3.3 KiB
YAML

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:
if: github.repository == 'liketrek/TREK'
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- name: Close stale wrong-base-branch PRs
uses: actions/github-script@v8
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 hasBypass = pull.labels.some(l => l.name === 'bypass-branch-check');
if (hasBypass) continue;
const hasLabel = pull.labels.some(l => l.name === 'wrong-base-branch');
if (!hasLabel) continue;
// Wiki-only PRs are exempt — clear label and skip
const files = [];
for (let page = 1; ; page++) {
const { data } = await github.rest.pulls.listFiles({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: pull.number,
per_page: 100,
page,
});
files.push(...data);
if (data.length < 100) break;
}
const allWiki = files.length > 0 && files.every(f => f.filename.startsWith('wiki/'));
if (allWiki) {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: pull.number,
name: 'wrong-base-branch',
});
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',
});
}