Created
May 5, 2020 08:26
-
-
Save romuald/2ff8c3673179eba1915a69982c44777b to your computer and use it in GitHub Desktop.
Jenkins favicon with status. Adds a colored status in the favicon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Jenkins favicon with status | |
// @version 1.0 | |
// @description Show a visual pill for Jenkins build status in the favicon (gray while building) | |
// @author Romuald Brunet <romuald@gandi.net> | |
// @match https://your-jenkins-instance/job/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
const COLOR_SUCCESS = "green", | |
COLOR_FAILURE = "red", | |
COLOR_PENDING = "gray"; | |
const path = window.location.pathname; | |
const re = new RegExp("(.*?/job/)(.*?)/([0-9]+)"); | |
const match = re.exec(path); | |
if ( ! match ) { return } | |
const apiurl = `${match[0]}/api/json?tree=result,building`; | |
const $links = document.querySelectorAll('link'); | |
const favicons = []; | |
function reloaded() { | |
let loaded = true; | |
favicons.forEach((favicon) => { | |
if ( ! favicon._image.complete ) { | |
loaded = false; | |
} | |
}) | |
if (loaded) { | |
fetch_status() | |
} | |
} | |
$links.forEach(function(link) { | |
if ( /(?<!\S)icon(?!\S)/.test(link.rel) ) { | |
const image = new Image(); | |
image.onload = reloaded | |
image.loading = "eager"; | |
image.src = link.href; | |
link._image = image; | |
link._original = link.href; | |
favicons.push(link); | |
} | |
}); | |
function change_favicon(color) { | |
const rectHeight = 1/4; // Height for the rectangle pill (image percent) | |
for ( let i=0, l=favicons.length; i<l; i++ ) { | |
const image = favicons[i]._image; | |
const canvas = document.createElement('canvas'); | |
canvas.width = image.width; | |
canvas.height = image.height; | |
const ctx = canvas.getContext('2d'); | |
ctx.drawImage(image, 0, 0); | |
ctx.fillStyle = color; | |
// Old circle visual | |
//const dwidth = 1/2; | |
//const size = image.width * dwidth; | |
//const x = image.width; | |
//const y = image.height; | |
//ctx.arc(x, y, size, 0, Math.PI * 2); | |
ctx.rect(0, image.height - image.height * rectHeight, | |
image.width, image.height * rectHeight); | |
ctx.fill(); | |
favicons[i].href = canvas.toDataURL(); | |
} | |
} | |
function fetch_status() { | |
fetch(apiurl).then((res) => { | |
return res.json(); | |
}).then((data) => { | |
let result = data.result; | |
// API sometimes returns a result when the build is still in progress | |
if ( data.building === true ) { | |
result = null; | |
} | |
switch (result) { | |
case null: // retry | |
change_favicon(COLOR_PENDING); | |
window.setTimeout(fetch_status, 4000); | |
break; | |
case "FAILURE": | |
case "UNSTABLE": | |
change_favicon(COLOR_FAILURE); | |
break; | |
case "SUCCESS": | |
change_favicon(COLOR_SUCCESS); | |
break; | |
default: | |
console.error(`Unknown Jenkins build result: ${result}`) | |
break; | |
} | |
}) | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment