@lifeomic/bitrise
Advanced tools
Comparing version 0.1.2 to 0.2.0
{ | ||
"name": "@lifeomic/bitrise", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "Bitrise API client", | ||
@@ -5,0 +5,0 @@ "main": "src/client.js", |
@@ -72,6 +72,10 @@ bitrise | ||
### async build.follow() | ||
### async build.follow({ heartbeat, interval }) | ||
Poll on the logs for a build and print them to stdout. An error will be thrown | ||
if the build fails. | ||
if the build fails. `interval` is the polling interval in milliseconds | ||
(default value is `5000`). `heartbeat` is the maximum interval that no output | ||
can be received in milliseconds. When this value is supplied a heartbeat message | ||
will be printed if no output has been received. When it is not supplied nothing | ||
is printed unless output is received from the build. | ||
@@ -78,0 +82,0 @@ References: |
@@ -15,3 +15,4 @@ const abortBuild = async ({ appSlug, buildSlug, client }, options = {}) => { | ||
const followBuild = async ({ appSlug, buildSlug, client }) => { | ||
const followBuild = async ({ appSlug, buildSlug, client }, options = {}) => { | ||
let lastActive = Date.now(); | ||
let timestamp; | ||
@@ -21,3 +22,3 @@ | ||
if (timestamp) { | ||
await sleep(5000); | ||
await sleep(options.interval || 5000); | ||
} | ||
@@ -36,3 +37,11 @@ | ||
response.data.log_chunks.forEach(({ chunk }) => process.stdout.write(chunk)); | ||
const now = Date.now(); | ||
if (response.data.log_chunks.length) { | ||
response.data.log_chunks.forEach(({ chunk }) => process.stdout.write(chunk)); | ||
lastActive = now; | ||
} else if (options.heartbeat && (now - lastActive) >= options.heartbeat) { | ||
process.stdout.write('heartbeat: waiting for build output...\n'); | ||
lastActive = now; | ||
} | ||
timestamp = response.data.timestamp; | ||
@@ -39,0 +48,0 @@ } while (timestamp); |
@@ -71,2 +71,3 @@ const axios = require('axios'); | ||
sinon.assert.calledWithExactly(write, chunk); | ||
sinon.assert.calledWithExactly(clock, sinon.match.func, 5000); | ||
} | ||
@@ -162,1 +163,80 @@ } finally { | ||
}); | ||
test.serial('following a build can customize the polling interval', async (test) => { | ||
const { appSlug, build, buildSlug, client } = test.context; | ||
const interval = 1000; | ||
const logChunks = [ | ||
'line one', | ||
'line two', | ||
'line three' | ||
]; | ||
const buildStub = stubGetBuild({ appSlug, axios: client, buildSlug }); | ||
buildStub.build.status = 1; | ||
stubBuildLogStream({ appSlug, axios: client, buildSlug, logChunks }); | ||
// Cause timers to execute immediately | ||
const clock = sinon.stub(global, 'setTimeout').callsArg(0); | ||
const write = sinon.stub(process.stdout, 'write'); | ||
try { | ||
await build.follow({ interval }); | ||
sinon.assert.calledWithExactly(clock, sinon.match.func, interval); | ||
} finally { | ||
clock.restore(); | ||
write.restore(); | ||
} | ||
}); | ||
test.serial('a heartbeat can be emitted when a followed build has no new output', async (test) => { | ||
const { appSlug, build, buildSlug, client } = test.context; | ||
const heartbeat = 10000; | ||
const logChunks = [ | ||
'line one', // 0s | ||
null, // 5s | ||
null, // 10s | ||
'line two', // 15s | ||
'line three', // 20s | ||
null, // 25s | ||
null, // 30s | ||
null, // 35s | ||
'line four' // 40s | ||
]; | ||
const buildStub = stubGetBuild({ appSlug, axios: client, buildSlug }); | ||
buildStub.build.status = 1; | ||
stubBuildLogStream({ appSlug, axios: client, buildSlug, logChunks }); | ||
let currentNow = 0; | ||
const tick = () => { | ||
const oldNow = currentNow; | ||
currentNow += 5000; | ||
return oldNow; | ||
}; | ||
// Cause timers to execute immediately | ||
const clock = sinon.stub(global, 'setTimeout').callsArg(0); | ||
const now = sinon.stub(Date, 'now').callsFake(tick); | ||
const write = sinon.stub(process.stdout, 'write'); | ||
try { | ||
await build.follow({ heartbeat }); | ||
test.deepEqual( | ||
write.args, | ||
[ | ||
[ 'line one' ], | ||
[ 'heartbeat: waiting for build output...\n' ], | ||
[ 'line two' ], | ||
[ 'line three' ], | ||
[ 'heartbeat: waiting for build output...\n' ], | ||
[ 'line four' ] | ||
] | ||
); | ||
} finally { | ||
clock.restore(); | ||
now.restore(); | ||
write.restore(); | ||
} | ||
}); |
@@ -72,8 +72,10 @@ const get = require('lodash/get'); | ||
is_archived: chunks.length === 0, | ||
log_chunks: [ | ||
{ | ||
chunk, | ||
position: timestamp | ||
} | ||
], | ||
log_chunks: chunk | ||
? [ | ||
{ | ||
chunk, | ||
position: timestamp | ||
} | ||
] | ||
: [], | ||
timestamp: chunks.length ? timestamp : null | ||
@@ -80,0 +82,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
182212
599
96