diff --git a/.github/workflows/fleet-status-self-test.yml b/.github/workflows/fleet-status-self-test.yml index 1fc2cb9..b8b9d31 100644 --- a/.github/workflows/fleet-status-self-test.yml +++ b/.github/workflows/fleet-status-self-test.yml @@ -9,6 +9,9 @@ on: types: [opened, synchronize, reopened, ready_for_review] paths: - .github/workflows/** + # A Redline pin bump touches only these two, and moves no fleet-status rule. + - '!.github/workflows/redline.yml' + - '!.github/workflows/redline-fix.yml' - scripts/fleet-status.mjs - scripts/fleet-status.test.mjs diff --git a/.github/workflows/fleet-status.yml b/.github/workflows/fleet-status.yml index 13ecc49..41e1848 100644 --- a/.github/workflows/fleet-status.yml +++ b/.github/workflows/fleet-status.yml @@ -41,8 +41,12 @@ jobs: # the PR merge ref's workflow with a read-only token, so they never run this job. # A fork's workflow_run lists no pull requests; the script finds them by head repo and branch. # issue_comment fires for issues too; only PR comments matter. The script re-checks it. + # A comment starts a run only when it can change a status: a verification comment, an edit + # away from one, or its deletion. if: >- - (github.event_name == 'issue_comment' && github.event.issue.pull_request != null) || + (github.event_name == 'issue_comment' && github.event.issue.pull_request != null && + (startsWith(github.event.comment.body, '## Verification at') || + startsWith(github.event.changes.body.from, '## Verification at'))) || (github.event_name == 'workflow_run' && ((contains(fromJSON('["pull_request","pull_request_target"]'), github.event.workflow_run.event) && github.event.workflow_run.head_repository.full_name == github.repository && diff --git a/scripts/fleet-status.test.mjs b/scripts/fleet-status.test.mjs index a4aa748..7c44523 100644 --- a/scripts/fleet-status.test.mjs +++ b/scripts/fleet-status.test.mjs @@ -439,6 +439,7 @@ console.log('\n fleet-status.yml: which events run the job for a fork'); const fns = { contains: (h, n) => (Array.isArray(h) ? h.some((x) => eq(x, n)) : String(h ?? '').toLowerCase().includes(String(n ?? '').toLowerCase())), fromJSON: (x) => JSON.parse(x), + startsWith: (h, n) => String(h ?? '').toLowerCase().startsWith(String(n ?? '').toLowerCase()), }; const primary = () => { const k = toks[p++]; @@ -491,9 +492,15 @@ console.log('\n fleet-status.yml: which events run the job for a fork'); check('a fork\'s pull_request event does not run the job', !onPr('pull_request', FORKED)); check('a fork\'s pull_request_review event does not run the job', !onPr('pull_request_review', FORKED)); check('a same-repo pull_request and review run it', onPr('pull_request', REPO) && onPr('pull_request_review', REPO)); - check('a comment on a PR runs it, fork or not; a comment on an issue does not', - runs({ event_name: 'issue_comment', event: { issue: { pull_request: { url: 'x' } } } }) - && !runs({ event_name: 'issue_comment', event: { issue: {} } })); + const onComment = (body, extra = {}) => runs({ event_name: 'issue_comment', event: { issue: { pull_request: { url: 'x' } }, comment: { body }, ...extra } }); + check('a verification comment on a PR runs it, fork or not; one on an issue does not', + onComment('## Verification at abc1234\n\nPassed.') + && !runs({ event_name: 'issue_comment', event: { issue: {}, comment: { body: '## Verification at abc1234' } } })); + check('any other comment does not run it (a preview bot, a person)', + !onComment('Deploying with Cloudflare Workers ... preview URL') && !onComment('lgtm') && !onComment('')); + check('a comment edited away from a verification, or a deleted one, still runs it', + onComment('never mind', { changes: { body: { from: '## Verification at abc1234' } } }) + && onComment('## Verification at abc1234', { action: 'deleted' })); check('a fork\'s CI finishing runs it, though the event lists no PR', onRun('pull_request', FORKED, [])); check('a fork\'s pull_request_target run finishing runs it', onRun('pull_request_target', FORKED, [])); check('the review relay finishing on a fork runs it', onRun('pull_request_review', FORKED, []));