Add heroku ci:watch command using polling

This commit is contained in:
Andrew Appleton 2016-11-08 14:17:34 +00:00
Родитель c5e2a67750
Коммит d49eabc161
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 74BD60891CAC329A
4 изменённых файлов: 90 добавлений и 1 удалений

19
commands/ci/watch.js Normal file
Просмотреть файл

@ -0,0 +1,19 @@
const cli = require('heroku-cli-util')
const co = require('co')
const api = require('../../lib/heroku-api')
const WatchTestRuns = require('../../lib/watch-test-runs')
function* run (context, heroku) {
const coupling = yield api.pipelineCoupling(heroku, context.app)
return yield WatchTestRuns.watch(coupling.pipeline, { heroku })
}
module.exports = {
topic: 'ci',
command: 'watch',
needsApp: true,
needsAuth: true,
description: 'watch in flight tests runs',
help: 'a long running command which will watch all running test runs',
run: cli.command(co.wrap(run))
}

Просмотреть файл

@ -21,6 +21,17 @@ function isTerminal (testRun) {
return TERMINAL_STATES.includes(testRun.status)
}
function isNotTerminal (testRun) {
return !isTerminal(testRun)
}
// True if the given test run was updated in the last {recency} minutes
function isRecent (testRun, recency = 60) {
const oneHourAgo = Date.now() - (recency * 60 * 1000)
const updatedAt = new Date(testRun.updated_at).valueOf()
return updatedAt > oneHourAgo
}
function * waitForStates (states, testRun, { heroku }) {
while (!states.includes(testRun.status)) {
testRun = yield api.testRun(heroku, testRun.pipeline.id, testRun.number)
@ -88,6 +99,9 @@ function * displayAndExit (pipeline, number, { heroku }) {
module.exports = {
isTerminal,
isNotTerminal,
isRecent,
display,
displayAndExit
displayAndExit,
STATES: { PENDING, CREATING, BUILDING, RUNNING, ERRORED, FAILED, SUCCEEDED }
}

55
lib/watch-test-runs.js Normal file
Просмотреть файл

@ -0,0 +1,55 @@
const cli = require('heroku-cli-util')
const wait = require('co-wait')
const log = require('single-line-log').stdout
const api = require('./heroku-api')
const TestRun = require('./test-run')
const { PENDING, CREATING, BUILDING, RUNNING, ERRORED, FAILED, SUCCEEDED } = TestRun.STATES
const STATUS_ICONS = {
[PENDING]: '⋯',
[CREATING]: '⋯',
[BUILDING]: '⋯',
[RUNNING]: '⋯',
[ERRORED]: '!',
[FAILED]: '𐄂',
[SUCCEEDED]: '✓'
}
const STATUS_COLORS = {
[PENDING]: 'yellow',
[CREATING]: 'yellow',
[BUILDING]: 'yellow',
[RUNNING]: 'yellow',
[ERRORED]: 'red',
[FAILED]: 'red',
[SUCCEEDED]: 'green'
}
function isRunningOrRecent (testRun) {
return TestRun.isNotTerminal(testRun) || TestRun.isRecent(testRun)
}
function* getRunningTests (heroku, pipelineID) {
return (yield api.testRuns(heroku, pipelineID)).filter(isRunningOrRecent)
}
function statusIcon ({ status }) {
return cli.color[STATUS_COLORS[status]](STATUS_ICONS[status])
}
function printLine (testRun) {
return `${statusIcon(testRun)} #${testRun.number} ${testRun.commit_branch}:${testRun.commit_sha.slice(0, 6)} ${testRun.status}`
}
function* watch (pipeline, { heroku }) {
cli.styledHeader(`Watching test runs for the ${pipeline.name} pipeline`)
while (true) {
const testRuns = yield getRunningTests(heroku, pipeline.id)
log(testRuns.map(printLine).join('\n'))
yield wait(1000)
}
}
module.exports = {
watch
}

Просмотреть файл

@ -38,6 +38,7 @@
"github-url-to-object": "^2.2.6",
"got": "^6.6.3",
"heroku-cli-util": "^6.0.15",
"single-line-log": "^1.1.2",
"temp": "^0.8.3"
}
}