Buildkite Browser Notifications Userscript

At Shopify, we use Buildkite for running continuous integration tests. That means I’m opening up and monitoring Buildkite builds dozens of times a day, checking on them, browsing them, etc. Sadly, Buildkite’s interface doesn’t provide browser notifications for build status (e.g. when it fails or succeeds).
So, I built my own implementation: Get a browser notification on buildkite build status change. Now I can let my browser tell me when to check back on those tabs.
// ==UserScript==
// @name Buildkite build completion notifications
// @namespace Violentmonkey Scripts
// @match https://buildkite.com/*/builds/*
// @grant none
// @version 2.0
// @author joshbeckman
// @description 6/4/2025, 2:09:56 PM
// ==/UserScript==
// Setup notification permissions
if (!("Notification" in window)) return;
if (Notification.permission !== "granted" && Notification.permission !== "denied") {
// Only ask until user explicitly grants / denies
Notification.requestPermission();
}
function notify(message, options) {
const notification = new Notification(message, options);
notification.addEventListener("click", () => {
window.focus();
notification.close();
});
}
// Initialize with current favicon href to prevent notification on page load
const initialFavicon = document.head.querySelector('link[rel=icon]');
let lastFaviconHref = initialFavicon ? initialFavicon.href : null;
const interval = setInterval(() => {
function clear() {clearInterval(interval)}
const favicon = document.head.querySelector('link[rel=icon]');
if (!favicon) {
return clear();
}
// Only proceed if favicon href has changed
if (favicon.href === lastFaviconHref) {
return;
}
lastFaviconHref = favicon.href;
if (favicon.href.match(/-failed/)) {
notify('❌ Build failed', {body: document.title, icon: favicon.href});
return clear();
} else if (favicon.href.match(/-passed/)) {
notify('✅ Build succeeded', {body: document.title, icon: favicon.href});
return clear();
} else if (favicon.href.match(/-canceled/)) {
notify('🛑 Build canceled', {body: document.title, icon: favicon.href});
return clear();
}
}, 2_000);
You can use this (like I do) with Violentmonkey or some other userscript extension in your browser or you can wrap this up as a bookmarklet just as easily.
Josh Beckman
Widgets
Comments & Replies
You can subscribe or follow or reply here: