@lifeomic/bitrise
Advanced tools
Comparing version 0.7.0 to 0.10.0
{ | ||
"name": "@lifeomic/bitrise", | ||
"version": "0.7.0", | ||
"version": "0.10.0", | ||
"description": "Bitrise API client", | ||
@@ -31,3 +31,3 @@ "main": "src/client.js", | ||
"@lifeomic/eslint-plugin-node": "^2.0.1", | ||
"ava": "^0.25.0", | ||
"ava": "^2.4.0", | ||
"coveralls": "^3.0.2", | ||
@@ -34,0 +34,0 @@ "eslint": "^6.0.0", |
@@ -66,3 +66,3 @@ const build = require('./build'); | ||
const response = await client.post(`/apps/${slug}/builds`, buildOptions); | ||
return build({ appSlug: slug, client, buildSlug: response.data.build_slug }); | ||
return build({ appSlug: slug, client, buildSlug: response.data.build_slug, buildInfo: response.data }); | ||
}; | ||
@@ -77,3 +77,8 @@ | ||
const builds = response.data.data.map((buildInfo) => { | ||
return build({ appSlug: slug, client, buildSlug: buildInfo.slug }); | ||
return build({ | ||
appSlug: slug, | ||
buildSlug: buildInfo.slug, | ||
client, | ||
buildInfo | ||
}); | ||
}); | ||
@@ -80,0 +85,0 @@ |
@@ -32,3 +32,3 @@ const isNil = require('lodash/isNil'); | ||
let timestamp; | ||
let attributes; | ||
do { | ||
@@ -65,7 +65,15 @@ if (timestamp) { | ||
// Sometimes build might have empty log_chunks, have is_archived set to false, have non-empty timestamp, but be aborted | ||
// (because of bitrise timeout for example). Don't follow such builds forever: | ||
attributes = await describeBuild({ appSlug, buildSlug, client }); | ||
if (attributes.status === 3 && !response.data.is_archived && response.data.log_chunks.length === 0) { | ||
process.stdout.write('Build has been aborted, not polling logs any more\n'); | ||
throw new Error(`Build ${appSlug}/${buildSlug} aborted`); | ||
} | ||
timestamp = response.data.timestamp; | ||
} while (timestamp); | ||
const attributes = await describeBuild({ appSlug, buildSlug, client }); | ||
if (!attributes) { | ||
attributes = await describeBuild({ appSlug, buildSlug, client }); | ||
} | ||
if (attributes.status > 1) { | ||
@@ -99,4 +107,4 @@ throw new Error(`Build ${appSlug}/${buildSlug} failed`); | ||
module.exports = ({ appSlug, buildSlug, client }) => { | ||
const build = { appSlug, buildSlug }; | ||
module.exports = ({ appSlug, buildSlug, client, buildInfo }) => { | ||
const build = { appSlug, buildSlug, ...buildInfo }; | ||
const state = { appSlug, buildSlug, client }; | ||
@@ -103,0 +111,0 @@ |
@@ -6,4 +6,5 @@ const app = require('../src/app'); | ||
const uuid = require('uuid/v4'); | ||
const omit = require('lodash/omit'); | ||
const { stubTriggerBuild, stubListBuilds } = require('./stubs'); | ||
const { stubTriggerBuild, stubListBuilds, mockBuildData } = require('./stubs'); | ||
@@ -288,9 +289,16 @@ test.beforeEach((test) => { | ||
const stub = stubListBuilds({ appSlug: slug, axios: client }); | ||
const mockBuildData1 = mockBuildData(stub.builds[0].build_slug); | ||
const mockBuildData2 = mockBuildData(stub.builds[1].build_slug); | ||
mockBuildData1.buildSlug = stub.builds[0].build_slug; | ||
mockBuildData2.buildSlug = stub.builds[1].build_slug; | ||
mockBuildData1.appSlug = slug; | ||
mockBuildData2.appSlug = slug; | ||
const buildList = await app.listBuilds(); | ||
const buildResponseDataOnly1 = omit(buildList.builds[0], ['abort', 'describe', 'follow', 'listArtifacts', 'isFinished']); | ||
const buildResponseDataOnly2 = omit(buildList.builds[1], ['abort', 'describe', 'follow', 'listArtifacts', 'isFinished']); | ||
test.is(buildList.builds.length, 2); | ||
test.is(buildList.builds[0].appSlug, slug); | ||
test.is(buildList.builds[0].buildSlug, stub.builds[0].build_slug); | ||
test.is(buildList.builds[1].appSlug, slug); | ||
test.is(buildList.builds[1].buildSlug, stub.builds[1].build_slug); | ||
test.deepEqual(buildResponseDataOnly1, mockBuildData1); | ||
test.deepEqual(buildResponseDataOnly2, mockBuildData2); | ||
}); | ||
@@ -297,0 +305,0 @@ |
@@ -8,3 +8,3 @@ const axios = require('axios'); | ||
const { DateTime } = require('luxon'); | ||
const { stubAbortBuild, stubArchivedBuildLog, stubBuildLogStream, stubGetBuild, stubListArtifacts } = require('./stubs'); | ||
const { stubAbortBuild, stubArchivedBuildLog, stubBuildLogStream, stubGetBuild, stubListArtifacts, stubEmptyNonArchivedBuildLog } = require('./stubs'); | ||
@@ -98,3 +98,3 @@ test.beforeEach((test) => { | ||
try { | ||
await test.throws(build.follow()); | ||
await test.throwsAsync(() => build.follow()); | ||
@@ -110,2 +110,19 @@ for (const chunk of logChunks) { | ||
test.serial('following an aborted build with is_archived=false prints the log output and then errors', async (test) => { | ||
const { appSlug, build, buildSlug, client } = test.context; | ||
const buildStub = stubGetBuild({ appSlug, axios: client, buildSlug }); | ||
buildStub.build.status = 3; | ||
stubEmptyNonArchivedBuildLog({ appSlug, axios: client, buildSlug }); | ||
// Cause timers to execute immediately | ||
const clock = sinon.stub(global, 'setTimeout').callsArg(0); | ||
const write = sinon.stub(process.stdout, 'write'); | ||
try { | ||
await test.throwsAsync(() => build.follow(), { message: `Build ${buildStub.build.slug}/${buildStub.build.build_slug} aborted` }); | ||
} finally { | ||
clock.restore(); | ||
write.restore(); | ||
} | ||
}); | ||
test.serial('following a successful build that has already finished prints the log output', async (test) => { | ||
@@ -140,3 +157,3 @@ const { appSlug, build, buildSlug, client } = test.context; | ||
try { | ||
await test.throws(build.follow()); | ||
await test.throwsAsync(() => build.follow()); | ||
sinon.assert.calledWithExactly(write, logText); | ||
@@ -143,0 +160,0 @@ } finally { |
@@ -103,3 +103,3 @@ const axios = require('axios'); | ||
const httpClient = create.firstCall.returnValue; | ||
const { response } = await test.throws(httpClient.get('http://localhost/error')); | ||
const { response } = await test.throwsAsync(() => httpClient.get('http://localhost/error')); | ||
test.is(response.status, 500); | ||
@@ -106,0 +106,0 @@ } finally { |
@@ -67,2 +67,16 @@ const get = require('lodash/get'); | ||
exports.stubEmptyNonArchivedBuildLog = ({ appSlug, axios, buildSlug }) => { | ||
const logUrl = 'http://localhost/logs/example.txt'; | ||
const stub = getStub(axios, 'get'); | ||
stub.withArgs(`/apps/${appSlug}/builds/${buildSlug}/log`).resolves({ | ||
data: { | ||
expiring_raw_log_url: logUrl, | ||
is_archived: false, | ||
log_chunks: [] | ||
}, | ||
status: 200 | ||
}); | ||
}; | ||
exports.stubBuildLogStream = ({ appSlug, axios, buildSlug, logChunks }) => { | ||
@@ -144,2 +158,30 @@ const logStub = getStub(axios, 'get'); | ||
function mockBuildData (buildSlug) { | ||
return { | ||
abort_reason: undefined, | ||
branch: 'master', | ||
build_number: 0, | ||
commit_hash: '86d07c9a9c6f4fc4bf551fcdaa224e57d0c55265', | ||
commit_message: 'Commit message', | ||
commit_view_url: 'https://bitbucket.org/lifeomic/life-extend/commits/4c9a6a12568f33df3ed373cd7b389e1262404ac1', | ||
environment_prepare_finished_at: '2020-11-01T00:00:00', | ||
finished_at: '2020-11-01T00:00:00', | ||
is_on_hold: true, | ||
machine_type_id: '1', | ||
original_build_params: 'params', | ||
pull_request_id: 0, | ||
pull_request_target_branch: 'master', | ||
pull_request_view_url: 'https://github.com/lifeomic/bitrise/pull/33', | ||
slug: buildSlug, | ||
stack_identifier: 'stack-identifier', | ||
started_on_worker_at: '2020-11-01T00:00:00', | ||
status: 0, | ||
status_text: 'in-progress', | ||
tag: 'tag', | ||
triggered_at: '2020-11-01T00:00:00', | ||
triggered_by: 'system', | ||
triggered_workflow: 'lifeFastingIOS' | ||
}; | ||
} | ||
exports.stubListBuilds = ({ appSlug, axios, next }) => { | ||
@@ -160,4 +202,4 @@ const build1 = generateBuild(); | ||
data: [ | ||
{ slug: build1.build_slug }, | ||
{ slug: build2.build_slug } | ||
mockBuildData(build1.build_slug), | ||
mockBuildData(build2.build_slug) | ||
], | ||
@@ -205,1 +247,3 @@ paging: { | ||
}; | ||
exports.mockBuildData = mockBuildData; |
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
1196
50310