Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 1 | /** |
| 2 | * Copyright (c) 2017 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you |
| 5 | * may not use this file except in compliance with the License. You may |
| 6 | * obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| 13 | * implied. See the License for the specific language governing |
| 14 | * permissions and limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | 'use strict'; |
| 18 | |
| 19 | const REPO_URL = 'https://android.googlesource.com/platform/external/perfetto/'; |
| 20 | const GERRIT_REVIEW_URL = 'https://android-review.googlesource.com/c/platform/external/perfetto'; |
Primiano Tucci | fecbb17 | 2017-12-19 15:05:37 +0100 | [diff] [blame] | 21 | const CHANGES_URL = '/changes/?q=project:platform/external/perfetto+-age:7days+-is:abandoned&o=DETAILED_ACCOUNTS'; |
Primiano Tucci | 46e4719 | 2017-10-04 09:32:12 -0700 | [diff] [blame] | 22 | const REPO = 'catapult-project/perfetto'; |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 23 | |
| 24 | let botIndex = {}; |
| 25 | |
| 26 | // Builds a map of bot name -> column index, e.g.: |
| 27 | // {'linux-clang-x86_64-relese' -> 1, 'android-clang-arm-debug' -> 2}. |
| 28 | function GetColumnIndexes() { |
| 29 | const cols = document.getElementById('cls_header').children; |
| 30 | for (let i = 0; i < cols.length; i++) { |
| 31 | const id = cols[i].id; |
| 32 | if (id) |
| 33 | botIndex[id] = i + 4 /* 4 = subject...updated columns */; |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | function GetTravisStatusForJob(jobId, div) { |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 38 | fetch('https://api.travis-ci.org/jobs/' + jobId) |
| 39 | .then(response => { |
| 40 | if (response.status != 200) |
| 41 | throw 'Unable to make request to Travis'; |
| 42 | return response.json(); |
| 43 | }) |
| 44 | .then(resp => { |
| 45 | let jobName = resp.config.env.split(' ')[0]; |
| 46 | if (jobName.startsWith('CFG=')) |
| 47 | jobName = jobName.substring(4); |
| 48 | if (!(jobName in botIndex)) |
| 49 | return; |
| 50 | let link = document.createElement('a'); |
| 51 | link.href = 'https://travis-ci.org/' + REPO + '/jobs/' + jobId; |
| 52 | link.title = resp.state + ' [' + jobName + ']'; |
| 53 | let jobState = resp.state; |
| 54 | if (resp.state == 'finished' && resp.result !== 0) |
| 55 | jobState = 'errored'; |
| 56 | link.classList.add(jobState); |
| 57 | if (jobState == 'finished') |
| 58 | link.innerHTML = '<i class="material-icons">check_circle</i>'; |
| 59 | else if (jobState == 'created') |
| 60 | link.innerHTML = '<i class="material-icons">autorenew</i>'; |
| 61 | else if (jobState == 'errored' || jobState == 'cancelled') |
| 62 | link.innerHTML = '<i class="material-icons">bug_report</i>'; |
| 63 | else |
| 64 | link.innerHTML = '<i class="material-icons">hourglass_full</i>'; |
| 65 | let td = div.children[botIndex[jobName]]; |
| 66 | td.innerHTML = ''; |
| 67 | td.appendChild(link); |
| 68 | }); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 69 | } |
| 70 | |
| 71 | function GetTravisStatusForBranch(branch, div) { |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 72 | fetch('https://api.travis-ci.org/repos/' + REPO + '/branches/' + branch) |
| 73 | .then(response => { |
| 74 | if (response.status != 200) |
| 75 | throw 'Unable to make request to Travis'; |
| 76 | return response.json() |
| 77 | }) |
| 78 | .then(resp => { |
| 79 | for (const jobId of resp.branch.job_ids) |
| 80 | GetTravisStatusForJob(jobId, div); |
| 81 | }); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 82 | } |
| 83 | |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 84 | function CreateRowForBranch(branch, href, subject, status, author, updated) { |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 85 | let table = document.getElementById('cls'); |
| 86 | let tr = document.createElement('tr'); |
| 87 | tr.classList.add(status); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 88 | |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 89 | let link = document.createElement('a'); |
| 90 | link.href = href; |
| 91 | link.innerText = subject; |
| 92 | let td = document.createElement('td'); |
| 93 | td.appendChild(link); |
| 94 | tr.appendChild(td); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 95 | |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 96 | td = document.createElement('td'); |
| 97 | td.innerText = status; |
| 98 | tr.appendChild(td); |
| 99 | |
| 100 | td = document.createElement('td'); |
| 101 | td.innerText = author; |
| 102 | tr.appendChild(td); |
| 103 | |
| 104 | td = document.createElement('td'); |
| 105 | td.innerText = updated; |
| 106 | tr.appendChild(td); |
| 107 | |
| 108 | for (let _ in botIndex) { |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 109 | td = document.createElement('td'); |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 110 | td.classList.add('job'); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 111 | tr.appendChild(td); |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 112 | } |
| 113 | table.appendChild(tr); |
| 114 | GetTravisStatusForBranch(branch, tr); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 115 | } |
| 116 | |
| 117 | function LoadGerritCLs() { |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 118 | fetch(CHANGES_URL) |
| 119 | .then(response => { |
| 120 | if (response.status != 200) |
| 121 | throw 'Unable to make request to Travis'; |
Lalit Maganti | cf324a5 | 2018-01-30 14:58:48 +0000 | [diff] [blame] | 122 | return response.text(); |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 123 | }) |
| 124 | .then(text => { |
| 125 | let json; |
| 126 | if (text.startsWith(')]}\'')) |
| 127 | json = text.substring(4); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 128 | else |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 129 | json = text; |
| 130 | let resp = JSON.parse(json); |
| 131 | for (const cl of resp) { |
| 132 | const branch = 'changes/' + cl._number; |
| 133 | const href = GERRIT_REVIEW_URL + '/+/' + cl._number;; |
| 134 | const lastUpdate = new Date(cl.updated + ' UTC'); |
| 135 | const lastUpdateMins = Math.ceil((Date.now() - lastUpdate) / 60000); |
| 136 | let lastUpdateText = ''; |
| 137 | if (lastUpdateMins < 60) |
| 138 | lastUpdateText = lastUpdateMins + ' mins ago'; |
| 139 | else if (lastUpdateMins < 60 * 24) |
| 140 | lastUpdateText = Math.ceil(lastUpdateMins / 60) + ' hours ago'; |
| 141 | else |
| 142 | lastUpdateText = lastUpdate.toLocaleDateString(); |
| 143 | CreateRowForBranch(branch, href, cl.subject, cl.status, |
| 144 | cl.owner.email.replace('@google.com', '@'), lastUpdateText); |
| 145 | } |
| 146 | }); |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 147 | } |
| 148 | |
Lalit Maganti | 2044f39 | 2018-01-30 11:32:27 +0000 | [diff] [blame] | 149 | // Register the service worker to cache job requests. |
| 150 | if ('serviceWorker' in navigator) { |
| 151 | navigator.serviceWorker.register('/service_worker.js', { scope: '/' }); |
| 152 | } |
| 153 | |
| 154 | // Fetch the CLs and the corresponding status for the Travis jobs. |
Primiano Tucci | e0ccef9 | 2017-10-03 10:43:20 -0700 | [diff] [blame] | 155 | GetColumnIndexes(); |
| 156 | CreateRowForBranch('master', REPO_URL, '*** master branch ***', 'MASTER', '', ''); |
| 157 | LoadGerritCLs(); |