UNPKG

build-light

Version:

A daemon, designed to run on single-board/development-board computers, that regularly polls your continuous integration server and reports build status through GPIO connected devices.

190 lines (156 loc) 4.71 kB
#!/usr/bin/env node /* * Configuration Variables * Configuration is controlled through environmental variables following the * twelve-factor methodology. (http://12factor.net/config) */ var CONFIG = { // Jenkins CI Server 'JENKINS_BASE_URL': process.env.JENKINS_BASE_URL || 'https://builds.apache.org', 'CHECK_INTERVAL': process.env.CHECK_INTERVAL || 15 * 60, // Every 15 minutes // GPIO Pins 'PIN_NUMBER_RED': process.env.PIN_NUMBER_RED || 17, 'PIN_NUMBER_YELLOW': process.env.PIN_NUMBER_YELLOW || 27, 'PIN_NUMBER_GREEN': process.env.PIN_NUMBER_GREEN || 22, }; /* * Modules */ var jenkins = require('jenkins-api').init(CONFIG.JENKINS_BASE_URL.trim()), gpio = require("./gpio"), program = require('commander'), path = require('path'), package = require( path.join(__dirname, 'package.json') ); /* * Command Line Interface */ program .version(package.version) .option('-v, --verbose', 'output light color') .parse(process.argv); /* * Main Function */ function main () { var interval = parseFloat(CONFIG.CHECK_INTERVAL) * 1000; jenkins.all_jobs(function (error, jobs) { // Set the color of the light var color = color_for_jobs(jobs); set_light_color(color); // Check again after interval setTimeout(main, interval); }); } main(); /* * Turn off and close pins on exit (including SIGINT) */ process.on('exit', function () { turn_light_off(); close_pins(); }); process.on('SIGINT', function () { process.exit(2); }); /* * Private Variables */ var redLight = gpio.pin(CONFIG.PIN_NUMBER_RED), yellowLight = gpio.pin(CONFIG.PIN_NUMBER_YELLOW), greenLight = gpio.pin(CONFIG.PIN_NUMBER_GREEN); /* * Private Functions */ function job_is_building (job) { return job.color.endsWith('_anime'); } function job_last_build_failed (job) { return ['red','yellow'].includes(job.color); } function color_for_jobs (jobs) { // Glass is half full, assume everything works until proven otherwise var color = 'green'; for (var i = jobs.length - 1; i >= 0; i--) { var job = jobs[i]; // if the job is currently building the light should be yellow // yellow trumps all other statuses so we stop processing if ( job_is_building(job) ) { color = 'yellow'; break; }; // if the job has failed the light should be red unless jobs are // currently building (so keep processing the jobs) if ( job_last_build_failed(job) ) { var color = 'red'; }; }; return color; } function set_light_color (color) { ('red'===color) ? redLight.turnOn() : redLight.turnOff(); ('yellow'===color) ? yellowLight.turnOn() : yellowLight.turnOff(); ('green'===color) ? greenLight.turnOn() : greenLight.turnOff(); if ( program.verbose === true ) { console.log(color); } } function turn_light_off () { redLight.turnOff(); yellowLight.turnOff(); greenLight.turnOff(); } function close_pins () { redLight.close(); yellowLight.close(); greenLight.close(); } /* * Polyfills */ // String.prototype.endsWith() // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith if (!String.prototype.endsWith) { Object.defineProperty(String.prototype, 'endsWith', { value: function(searchString, position) { var subjectString = this.toString(); if (position === undefined || position > subjectString.length) { position = subjectString.length; } position -= searchString.length; var lastIndex = subjectString.indexOf(searchString, position); return lastIndex !== -1 && lastIndex === position; } }); } // Array.prototype.includes() // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes if (![].includes) { Array.prototype.includes = function(searchElement /*, fromIndex*/ ) {'use strict'; if (this === undefined || this === null) { throw new TypeError('Cannot convert this value to object'); } var O = Object(this); var len = parseInt(O.length) || 0; if (len === 0) { return false; } var n = parseInt(arguments[1]) || 0; var k; if (n >= 0) { k = n; } else { k = len + n; if (k < 0) {k = 0;} } var currentElement; while (k < len) { currentElement = O[k]; if (searchElement === currentElement || (searchElement !== searchElement && currentElement !== currentElement)) { return true; } k++; } return false; }; }