From 0d9bd0091eb8d4cf4f80e007fd661e8334e3bf32 Mon Sep 17 00:00:00 2001 From: "Benjamin R. J. Schwedler" Date: Mon, 8 Jun 2026 14:04:40 -0500 Subject: [PATCH] Notify on failure when no run history exists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The action previously skipped silently when no previous workflow runs were found on main. This prevented merge queue failures from triggering notifications, since merge queue runs land on ephemeral refs and never appear in a main-branch run query. Now: no history + failed → fire failure notification; no history + passed → skip. State-transition logic is unchanged for builds with history. --- .github/actions/slack-build-notify/action.yml | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/.github/actions/slack-build-notify/action.yml b/.github/actions/slack-build-notify/action.yml index efccfdecc..55ffb0eff 100644 --- a/.github/actions/slack-build-notify/action.yml +++ b/.github/actions/slack-build-notify/action.yml @@ -54,32 +54,36 @@ runs: .filter(r => r.id !== context.runId && r.conclusion !== 'cancelled') .sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); - if (previousRuns.length === 0) { - core.info('No previous completed runs found, skipping notification'); - return; - } - - const previousRun = previousRuns[0]; const currentFailed = currentResult !== 'success'; - // Compare against the previous run's CI job conclusion (not the workflow - // conclusion) so that clean-job flaps don't trigger false notifications. - // Falls back to workflow conclusion if the CI job isn't found. - const { data: { jobs: prevJobs } } = await github.rest.actions.listJobsForWorkflowRun({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: previousRun.id, - per_page: 100, - }); - const prevCiJob = prevJobs.find(j => j.name === 'CI'); - const previousConclusion = prevCiJob - ? prevCiJob.conclusion - : previousRun.conclusion; - const previousFailed = previousConclusion !== 'success'; - - if (currentFailed === previousFailed) { - core.info(`No state transition (current: ${currentResult}, previous: ${previousConclusion}), skipping`); - return; + if (previousRuns.length === 0) { + if (!currentFailed) { + core.info('No previous completed runs found and build passed, skipping notification'); + return; + } + // No history — notify on failure directly (e.g. merge queue runs on ephemeral refs) + } else { + const previousRun = previousRuns[0]; + + // Compare against the previous run's CI job conclusion (not the workflow + // conclusion) so that clean-job flaps don't trigger false notifications. + // Falls back to workflow conclusion if the CI job isn't found. + const { data: { jobs: prevJobs } } = await github.rest.actions.listJobsForWorkflowRun({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: previousRun.id, + per_page: 100, + }); + const prevCiJob = prevJobs.find(j => j.name === 'CI'); + const previousConclusion = prevCiJob + ? prevCiJob.conclusion + : previousRun.conclusion; + const previousFailed = previousConclusion !== 'success'; + + if (currentFailed === previousFailed) { + core.info(`No state transition (current: ${currentResult}, previous: ${previousConclusion}), skipping`); + return; + } } const runUrl = currentRun.html_url;