name: PR Checklist Validation (History Rewrite) on: pull_request: types: [opened, edited, synchronize] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: validate: name: Validate history-rewrite checklist (conditional) runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6 - name: Validate PR checklist (only for history-rewrite changes) uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8 with: script: | const owner = context.repo.owner; const repo = context.repo.repo; const prNumber = context.issue.number; const pr = await github.rest.pulls.get({owner, repo, pull_number: prNumber}); const body = (pr.data && pr.data.body) || ''; // Determine if this PR modifies history-rewrite related files // Exclude the template file itself - it shouldn't trigger its own validation const filesResp = await github.rest.pulls.listFiles({ owner, repo, pull_number: prNumber }); const files = filesResp.data.map(f => f.filename.toLowerCase()); const relevant = files.some(fn => { // Skip the PR template itself if (fn === '.github/pull_request_template/history-rewrite.md') return false; // Check for actual history-rewrite implementation files return fn.startsWith('scripts/history-rewrite/') || fn === 'docs/plans/history_rewrite.md'; }); if (!relevant) { core.info('No history-rewrite related files changed; skipping checklist validation.'); return; } // Use a set of named checks with robust regex patterns for checkbox and phrase variants const checks = [ { name: 'preview_removals.sh mention', pattern: /preview_removals\.sh/i }, { name: 'data/backups mention', pattern: /data\/?backups/i }, // Accept checked checkbox variants and inline code/backtick usage for the '--force' phrase { name: 'explicit non-run of --force', pattern: /(?:\[\s*[xX]\s*\]\s*)?(?:i will not run|will not run|do not run|don'?t run|won'?t run)\b[^\n]*--force/i }, ]; const missing = checks.filter(c => !c.pattern.test(body)).map(c => c.name); if (missing.length > 0) { // Post a comment to the PR with instructions for filling the checklist const commentBody = `Hi! This PR touches history-rewrite artifacts and requires the checklist in .github/PULL_REQUEST_TEMPLATE/history-rewrite.md. The following items are missing in your PR body: ${missing.join(', ')}\n\nPlease update the PR description using the history-rewrite template and re-run checks.`; await github.rest.issues.createComment({ owner, repo, issue_number: prNumber, body: commentBody }); core.setFailed('Missing required checklist items: ' + missing.join(', ')); }