From 2f1df5500352cfc0956ea2cb81712b7fe29dfd69 Mon Sep 17 00:00:00 2001 From: Li Zhang Date: Thu, 9 Jul 2026 15:38:13 +0800 Subject: [PATCH] PROJQUAY-12196: fix(buildman): fire build_start notification on phase transition (#6443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * PROJQUAY-12196: fix(buildman): fire build_start notification on phase transition The BuildStartEvent was defined and configurable via the UI but never triggered. Add send_notification("build_start") when the build phase transitions to BUILDING. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude * PROJQUAY-12196: test(notifications): add build_start webhook E2E test 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --------- Co-authored-by: Claude --- buildman/manager/ephemeral.py | 3 ++ .../e2e/repository/notifications.spec.ts | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/buildman/manager/ephemeral.py b/buildman/manager/ephemeral.py index 0e1f62d50..3c6bddbdc 100644 --- a/buildman/manager/ephemeral.py +++ b/buildman/manager/ephemeral.py @@ -491,6 +491,9 @@ class EphemeralBuilderManager(BuildStateInterface): build_job.build_uuid, phase, self._build_logs.PHASE, phase_metadata ) + if phase == BUILD_PHASE.BUILDING: + build_job.send_notification("build_start") + # Check if on_job_complete needs to be called if updated and phase in EphemeralBuilderManager.COMPLETED_PHASES: executor_name = job_data_json.get("executor_name") diff --git a/web/playwright/e2e/repository/notifications.spec.ts b/web/playwright/e2e/repository/notifications.spec.ts index 14143a514..a669108eb 100644 --- a/web/playwright/e2e/repository/notifications.spec.ts +++ b/web/playwright/e2e/repository/notifications.spec.ts @@ -890,4 +890,46 @@ test.describe('Repository Notifications', {tag: ['@repository']}, () => { } }, ); + + test( + 'build_start notification delivered via webhook', + {tag: ['@feature:BUILD_SUPPORT', '@PROJQUAY-12196']}, + async ({api}) => { + test.setTimeout(300_000); + const org = await api.organization('buildstartwh'); + const repo = await api.repository(org.name, 'buildstartrepo'); + + const receiver = new WebhookReceiver(); + await receiver.start(); + + try { + await api.notification( + org.name, + repo.name, + 'build_start', + 'webhook', + {url: receiver.getUrl()}, + 'Build Start Webhook', + ); + + const build = await api.build( + org.name, + repo.name, + 'FROM scratch\nLABEL build="build-start-test"\n', + ); + + const webhook = await receiver.waitForWebhook( + (req) => + req.body.build_id === build.buildId && + req.body.repository === `${org.name}/${repo.name}`, + 240000, + ); + expect(webhook, 'build_start webhook not received').not.toBeNull(); + expect(webhook!.body.repository).toBe(`${org.name}/${repo.name}`); + expect(webhook!.body.build_id).toBe(build.buildId); + } finally { + await receiver.stop(); + } + }, + ); });