@cryptotaxi247 / infra / commits / 32947059

status-page: add alerts for github issues (#93)

* status-page: add alerts for github issues * status-page: tweak css

Daiderd Jordan committed Jan 9, 2020 at 00:02 UTC 32947059eebc33282b7dcfead2431a08b59943b7
3 files changed +39 -4
delft/eris/status-page/index.html
+2
@@ -57,6 +57,8 @@
57 <h1>NixOS</h1>
58 </div>
59
60 + <div id="alerts"></div>
61 +
62 <div class="hero12">
63 <h2>Nix Channel Status</h2>
64 <p>See <a href="http://howoldis.herokuapp.com/">HowOldIs</a> and the <a href="https://nixos.wiki/wiki/Nix_channels">NixOS Wiki</a> for information on how channel updates progress.</p>
delft/eris/status-page/status.css
+9
@@ -12,6 +12,15 @@
12 max-width: 15em;
13 }
14
15 +#alerts {
16 + margin-top: 10px;
17 +}
18 +
19 +.issue-age {
20 + display: inline-block;
21 + min-width: 6em;
22 +}
23 +
24 .github {
25 max-width: 10em;
26 overflow: hidden;
delft/eris/status-page/status.js
+28 -4
@@ -8,6 +8,30 @@ function init() {
8 });
9 }
10
11 +async function fetchIssues(label) {
12 + const response = await fetch(`https://api.github.com/repos/NixOS/nixpkgs/issues?labels=${label}`);
13 + return await response.json();
14 +}
15 +
16 +fetchIssues("1.severity%3A%20channel%20blocker")
17 + .then(data => data.map(issue => {
18 + var el = document.createElement('div');
19 + el.classList = "alert alert-warning";
20 + el.innerHTML = '<span class="issue-age"></span> <a class="issue-link"></a>';
21 + const since = moment(issue['created_at']).fromNow();
22 + el.getElementsByClassName('issue-age')[0].innerText = since;
23 + el.getElementsByClassName('issue-link')[0].href = issue['html_url'];
24 + el.getElementsByClassName('issue-link')[0].innerText = issue['title'];
25 + if (issue['labels'].find(label => label['name'] == 'infrastructure')) {
26 + el.innerHTML += ' <span class="label label-important">Infrastructure</span>'
27 + }
28 + return el;
29 + }))
30 + .then(elems => {
31 + var alerts = document.getElementById('alerts');
32 + elems.forEach(el => alerts.appendChild(el));
33 + });
34 +
35 function aggregateByChannel(result) {
36 return result.reduce((acc, {
37 channel,
@@ -18,7 +42,7 @@ function aggregateByChannel(result) {
42 }), {});
43 }
44
21 -async function fetchData(queryType, queryArgs = {}) {
45 +async function fetchMetrics(queryType, queryArgs = {}) {
46 const params = new URLSearchParams();
47 for (const [key, value] of Object.entries(queryArgs)) {
48 params.set(key, String(value));
@@ -32,7 +56,7 @@ async function fetchData(queryType, queryArgs = {}) {
56 return data.result;
57 }
58
35 -const revisionData = fetchData('query', {
59 +const revisionData = fetchMetrics('query', {
60 query: 'channel_revision'
61 })
62 .then(records => (
@@ -50,7 +74,7 @@ const revisionData = fetchData('query', {
74 .then(aggregateByChannel);
75
76
53 -const updateTimeData = fetchData('query', {
77 +const updateTimeData = fetchMetrics('query', {
78 query: 'channel_update_time'
79 })
80 .then(records => (
@@ -75,7 +99,7 @@ if (idealStart > earliestStart) {
99 start = earliestStart;
100 }
101 var end = moment.utc().format();
78 -const jobsetData = fetchData('query_range', {
102 +const jobsetData = fetchMetrics('query_range', {
103 query: 'hydra_job_failed',
104 start: start.format(),
105 end,