Skip to content

PR CI Sweeper

PR CI Sweeper #162

Workflow file for this run

name: PR CI Sweeper
# Repairs dropped pull_request CI via close/reopen and non-destructively revives
# cancelled GitHub Actions checks attached to auto-merge PR heads. The app token
# authorizes reruns; GITHUB_TOKEN close/reopen events would not trigger CI.
on:
schedule:
- cron: "7 * * * *"
workflow_dispatch:
inputs:
dry_run:
description: Log intended repairs without closing/reopening or rerunning workflows.
required: false
default: false
type: boolean
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
concurrency:
group: pr-ci-sweeper
cancel-in-progress: false
permissions: {}
jobs:
sweep:
permissions:
contents: read
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
ref: ${{ github.sha }}
persist-credentials: false
# No permission-* subset here: requesting a permission the installation
# does not grant fails token minting outright, and these installations
# lack actions:write/checks:read (every sweep failed 2026-07-24 until the
# subset was reverted). No inputs = the app's full granted set, which the
# sweep's re-fire lane is known to work with.
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # zizmor: ignore[github-app] v3
id: app-token
continue-on-error: true
with:
app-id: "2729701"
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
- uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # zizmor: ignore[github-app] v3
id: app-token-fallback
if: steps.app-token.outcome == 'failure'
with:
app-id: "2971289"
private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }}
- name: Sweep dropped PR CI runs
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
with:
github-token: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }}
script: |
const { pathToFileURL } = require("node:url");
const moduleUrl = pathToFileURL(
`${process.env.GITHUB_WORKSPACE}/scripts/github/pr-ci-sweeper.mjs`,
);
const { runPrCiSweeper } = await import(moduleUrl.href);
await runPrCiSweeper({
github,
context,
core,
dryRun: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false }},
appSlug: ${{ toJSON(steps.app-token.outputs.app-slug || steps.app-token-fallback.outputs.app-slug || '') }},
});