Jenkins からの結果通知を WebSocket にしてみよういうことで、knockout.js の勉強を兼ねて HTML を書いてみました。
Jenkins から WebSocket を飛ばすのはこちらのプラグインを利用しています。
Websocket Plugin - Jenkins - Jenkins Wiki
使っている JavaScript ライブラリは、
- jQuery 1.8.2 jQuery
- knockout.js 2.1.0 Knockout : Home
- linq.js 3.0.3-Beta4 linq.js - LINQ for JavaScript - Home
です。*1
Visual Studio で開発しているので、NuGet でダウンロード、html や js にはインテリセンス用のコメントが入ってます。
Jenkins の Remote access API Remote access API - Jenkins - Jenkins Wiki を使って、Job の一覧を取得し、各 Job の設定ファイルから WebSocket プラグインを利用している Job のみを対象に抜き出しています。
設定ファイルを見てるため、Jenkins と同じサーバーに配置しないとだめなはずです。そのため Remote access API では JSONP を使用していません。
全 Job で良いなら JSONP を使えば別サーバーに配置することも出来るでしょう。
css 使ってないので、見栄えは微妙です。適当に装飾したらそれなりに見れるものになるかと思います。
.html
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta charset="utf-8" /> <script src="jquery-1.8.2.min.js"></script> <script src="knockout-2.1.0.js"></script> <script src="linq.min.js"></script> <script src="App.js"></script> <title>Jenkins Subscriber</title> <script type="text/javascript"> /// <reference path="packages/jQuery.1.8.2/Content/Scripts/jquery-1.8.2-vsdoc.js" /> /// <reference path="packages/knockoutjs.2.1.0/Content/Scripts/knockout-2.1.0.js" /> /// <reference path="packages/linq.js.3.0.3-beta4/Content/Scripts/linq-vsdoc.js" /> $(function () { var viewModel = new ViewModel(); ko.applyBindings(viewModel); var ws = new WebSocket('ws://localhost:8081/jenkins'); ws.onmessage = function (msg) { viewModel.setBuildResult(msg); }; }); </script> </head> <body style="font-size: xx-large"> <ul data-bind="foreach: details" style="list-style-type: none"> <!-- ko if: isShow --> <li> <div data-bind="style: { backgroundColor: color }" > <span data-bind="text: name"></span> </div> </li> <!-- /ko --> </ul> </body> </html>app.js
/// <reference path="packages/jQuery.1.8.2/Content/Scripts/jquery-1.8.2-vsdoc.js" /> /// <reference path="packages/knockoutjs.2.1.0/Content/Scripts/knockout-2.1.0.js" /> /// <reference path="packages/linq.js.3.0.3-beta4/Content/Scripts/linq-vsdoc.js" /> var JobItem = function (viewModel, job) { var parent = viewModel; var self = this; self.name = ko.observable(job.name); self.color = ko.observable(job.color); self.xml = ko.observable(""); self.isShow = ko.computed(function () { return self.xml().match(/org.codefirst.jenkins.wsnotifier.WsNotifier/); }, self); } var ViewModel = function () { var self = this; self.details = ko.observableArray(); self.setBuildResult = function (msg) { eval('var obj = ' + msg.data); var target = Enumerable.from(self.details()) .firstOrDefault(function (x) { return x.name() == obj.project; }); if (target == null) { return; } if (obj.result == "SUCCESS") { target.color("green"); } else { target.color("red"); } }; $.getJSON("http://localhost:8080/api/json?tree=jobs[name,color]").then(function (data) { self.details.removeAll(); Enumerable.from(data.jobs) .where(function (x) { return x.color != "disabled" }) .select(function (x) { var d = { name: x.name, color: x.color.replace("blue", "green") }; return new JobItem(self, d); }) .forEach(function (x) { self.details.push(x); $.get("http://localhost:8080/job/" + x.name() + "/config.xml", "", function (result) { x.xml(result); }, "text"); }); }, function (data) { alert('error'); }); }