diff --git a/lib/context.js b/lib/context.js index a815dc2..b434770 100644 --- a/lib/context.js +++ b/lib/context.js @@ -10,7 +10,7 @@ exports.getParentBranchName = async function getParentBranchName () { } exports.getTestingBranchName = function getTestingBranchName (parentBranchName) { - return `wiby-${parentBranchName}` + return parentBranchName.startsWith('wiby-') ? parentBranchName : `wiby-${parentBranchName}` } exports.getDependencyLink = async function getDependencyLink (owner, repo, commitish) { diff --git a/lib/result.js b/lib/result.js index 93ce1d4..6b82f25 100644 --- a/lib/result.js +++ b/lib/result.js @@ -9,10 +9,14 @@ const debug = logger('wiby:result') // enum containing possible pipeline checks statuses const pipelineStatusesEnum = module.exports.pipelineStatusesEnum = Object.freeze({ + // statuses returned by github FAILED: 'failure', QUEUED: 'queued', PENDING: 'pending', - SUCCEED: 'success' + SUCCEED: 'success', + + // custom statuses + MISSING: 'test branch missing' }) const PENDING_RESULT_EXIT_CODE = 64 @@ -36,6 +40,16 @@ module.exports = async function ({ dependents }) { const parentBranchName = await context.getParentBranchName() const branch = await context.getTestingBranchName(parentBranchName) + const exists = await github.getBranch(dependentPkgInfo.owner, dependentPkgInfo.name, branch) + if (!exists) { + output.results.push({ + dependent: `${dependentPkgInfo.owner}/${dependentPkgInfo.name}`, + status: pipelineStatusesEnum.MISSING, + runs: [] + }) + allDependentsChecks.push([undefined, pipelineStatusesEnum.MISSING]) + continue + } let resp = await github.getChecks(dependentPkgInfo.owner, dependentPkgInfo.name, branch) if (resp.data.check_runs.length === 0) { resp = await github.getCommitStatusesForRef(dependentPkgInfo.owner, dependentPkgInfo.name, branch) @@ -106,7 +120,8 @@ const getOverallStatusForAllRuns = module.exports.getOverallStatusForAllRuns = f // if includes null or pending or queued - overall status is pending if (statuses.includes(null) || statuses.includes(pipelineStatusesEnum.PENDING) || - statuses.includes(pipelineStatusesEnum.QUEUED) + statuses.includes(pipelineStatusesEnum.QUEUED) || + statuses.includes(pipelineStatusesEnum.MISSING) ) { return pipelineStatusesEnum.PENDING } diff --git a/test/cli/result.js b/test/cli/result.js index 82ad137..cea6b33 100644 --- a/test/cli/result.js +++ b/test/cli/result.js @@ -10,6 +10,8 @@ const gitFixture = require('../fixtures/git') const wibyCommand = path.join(__dirname, '..', '..', 'bin', 'wiby') const fixturesPath = path.resolve(path.join(__dirname, '..', 'fixtures')) +const SUCCESS_RESULT_EXIT_CODE = 0 +const FAIL_RESULT_EXIT_CODE = 1 const PENDING_RESULT_EXIT_CODE = 64 tap.test('result command', async (tap) => { @@ -37,20 +39,64 @@ tap.test('result command', async (tap) => { childProcess.execSync(`${wibyCommand} result --dependent="https://github.com/wiby-test/fakeRepo"`, { env: { ...process.env, - NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js` + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pass.js` } }) } catch (e) { const result = e.output[1].toString().trim() tap.equal(result, expected) - tap.equal(e.status, PENDING_RESULT_EXIT_CODE) + tap.equal(e.status, SUCCESS_RESULT_EXIT_CODE) } }) tap.test('result command should call result module with all deps from .wiby.json', async (tap) => { const expected = fs.readFileSync( - path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-dependant.md'), + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-pass.md'), + 'utf-8' + ) + .trim() + + try { + childProcess.execSync(`${wibyCommand} result`, { + env: { + ...process.env, + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pass.js` + } + }) + } catch (e) { + const result = e.output[1].toString().trim() + + tap.equal(result, expected) + tap.equal(e.status, SUCCESS_RESULT_EXIT_CODE) + } + }) + + tap.test('result command should call result module with all deps from .wiby.json (pending result)', async (tap) => { + const expected = fs.readFileSync( + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-multiple-pending.md'), + 'utf-8' + ) + .trim() + + try { + childProcess.execSync(`${wibyCommand} result`, { + env: { + ...process.env, + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive-pending.js` + } + }) + } catch (e) { + const result = e.output[1].toString().trim() + + tap.equal(result, expected) + tap.equal(e.status, PENDING_RESULT_EXIT_CODE) + } + }) + + tap.test('result command should call result module with all deps from .wiby.json (missing branch result)', async (tap) => { + const expected = fs.readFileSync( + path.join(__dirname, '..', 'fixtures', 'expected-outputs', 'result', 'result-output-missing-branch.md'), 'utf-8' ) .trim() @@ -59,7 +105,7 @@ tap.test('result command', async (tap) => { childProcess.execSync(`${wibyCommand} result`, { env: { ...process.env, - NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-positive.js` + NODE_OPTIONS: `-r ${fixturesPath}/http/result-command-missing-branch.js` } }) } catch (e) { @@ -136,7 +182,7 @@ tap.test('result command', async (tap) => { const result = e.output[1].toString().trim() tap.equal(result, expected) - tap.equal(e.status, 1) + tap.equal(e.status, FAIL_RESULT_EXIT_CODE) } }) }) diff --git a/test/cli/test.js b/test/cli/test.js index 96c2fbb..13b4e8d 100644 --- a/test/cli/test.js +++ b/test/cli/test.js @@ -10,11 +10,9 @@ const wibyCommand = path.join(__dirname, '..', '..', 'bin', 'wiby') const fixturesPath = path.resolve(path.join(__dirname, '..', 'fixtures')) tap.test('test command', async (tap) => { - tap.beforeEach(async () => { + tap.test('test command should fail when config and dependent provided', async (tap) => { gitFixture.init() - }) - tap.test('test command should fail when config and dependent provided', async (tap) => { try { childProcess.execSync(`${wibyCommand} test --config=.wiby.json --dependent="https://github.com/wiby-test/fakeRepo"`).toString() tap.fail() @@ -24,6 +22,8 @@ tap.test('test command', async (tap) => { }) tap.test('test command should call test module with dependent URI', async (tap) => { + gitFixture.init() + const result = childProcess.execSync(`${wibyCommand} test --dependent="https://github.com/wiby-test/fakeRepo"`, { env: { ...process.env, @@ -35,6 +35,23 @@ tap.test('test command', async (tap) => { }) tap.test('test command should call test module with all deps from .wiby.json', async (tap) => { + gitFixture.init() + + const result = childProcess.execSync(`${wibyCommand} test`, { + env: { + ...process.env, + NODE_OPTIONS: `-r ${fixturesPath}/http/test-command-positive.js` + } + }).toString() + + tap.match(result, 'Changes pushed to https://github.com/wiby-test/pass/blob/wiby-running-unit-tests/package.json') + tap.match(result, 'Changes pushed to https://github.com/wiby-test/fail/blob/wiby-running-unit-tests/package.json') + tap.match(result, 'Changes pushed to https://github.com/wiby-test/partial/blob/wiby-running-unit-tests/package.json') + }) + + tap.test('test command should not add `wiby-` prefix when branch already has it', async (tap) => { + gitFixture.init('wiby-running-unit-tests') + const result = childProcess.execSync(`${wibyCommand} test`, { env: { ...process.env, diff --git a/test/fixtures/expected-outputs/result/result-output-missing-branch.md b/test/fixtures/expected-outputs/result/result-output-missing-branch.md new file mode 100644 index 0000000..f7d4e96 --- /dev/null +++ b/test/fixtures/expected-outputs/result/result-output-missing-branch.md @@ -0,0 +1,21 @@ +# wiby result command + +Overall status - pending + +## wiby-test/partial - success + +Checks: + +- partial_run - success +- partial_run_2 - success + +## wiby-test/fail - test branch missing + +Checks: + +## wiby-test/pass - success + +Checks: + +- pass_run - success +- pass_run_2 - success diff --git a/test/fixtures/expected-outputs/result/result-output-multiple-pass.md b/test/fixtures/expected-outputs/result/result-output-multiple-pass.md new file mode 100644 index 0000000..432ad40 --- /dev/null +++ b/test/fixtures/expected-outputs/result/result-output-multiple-pass.md @@ -0,0 +1,24 @@ +# wiby result command + +Overall status - success + +## wiby-test/partial - success + +Checks: + +- partial_run - success +- partial_run_2 - success + +## wiby-test/fail - success + +Checks: + +- fail_run - success +- fail_run_2 - success + +## wiby-test/pass - success + +Checks: + +- pass_run - success +- pass_run_2 - success diff --git a/test/fixtures/expected-outputs/result/result-output-multiple-dependant.md b/test/fixtures/expected-outputs/result/result-output-multiple-pending.md similarity index 100% rename from test/fixtures/expected-outputs/result/result-output-multiple-dependant.md rename to test/fixtures/expected-outputs/result/result-output-multiple-pending.md diff --git a/test/fixtures/git.js b/test/fixtures/git.js index cbea4fb..aa68acc 100644 --- a/test/fixtures/git.js +++ b/test/fixtures/git.js @@ -5,15 +5,13 @@ const fs = require('fs') const path = require('path') const tmp = require('tmp') -exports.TEST_BRANCH_NAME = 'running-unit-tests' - -exports.init = function () { +exports.init = function (initialBranch = 'running-unit-tests') { const gitRepoPath = path.join(__dirname, '..', '..') const { name: tmpDir } = tmp.dirSync() process.chdir(tmpDir) - childProcess.execSync('git init --initial-branch=running-unit-tests') + childProcess.execSync(`git init --initial-branch=${initialBranch}`) childProcess.execSync('git config user.email "wiby@example.com"') childProcess.execSync('git config user.name "Wiby Bot"') diff --git a/test/fixtures/http/result-command-empty-branch-checks-flat.js b/test/fixtures/http/result-command-empty-branch-checks-flat.js index 8c2beab..ff74e91 100644 --- a/test/fixtures/http/result-command-empty-branch-checks-flat.js +++ b/test/fixtures/http/result-command-empty-branch-checks-flat.js @@ -23,6 +23,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-empty-branch-checks.js b/test/fixtures/http/result-command-empty-branch-checks.js index deab11e..ba56256 100644 --- a/test/fixtures/http/result-command-empty-branch-checks.js +++ b/test/fixtures/http/result-command-empty-branch-checks.js @@ -23,6 +23,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-missing-branch.js b/test/fixtures/http/result-command-missing-branch.js new file mode 100644 index 0000000..6a0bd50 --- /dev/null +++ b/test/fixtures/http/result-command-missing-branch.js @@ -0,0 +1,63 @@ +'use strict' + +/** + * Mocks of HTTP calls for "wiby result" command positive flow + */ +const nock = require('nock') + +nock.disableNetConnect() + +nock('https://api.github.com') + // get package json + .post('/graphql') + .times(3) + .reply(200, { + data: { + repository: { + object: { + text: JSON.stringify({ + dependencies: { + wiby: '*' + } + }) + } + } + } + }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(404, {}) + // get check results + .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fake_run', conclusion: 'success' }, + { status: 'done', name: 'fake_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/fail/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fail_run', conclusion: 'success' }, + { status: 'done', name: 'fail_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/pass/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'pass_run', conclusion: 'success' }, + { status: 'done', name: 'pass_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/partial/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'partial_run', conclusion: 'success' }, + { status: 'done', name: 'partial_run_2', conclusion: 'success' } + ] + }) diff --git a/test/fixtures/http/result-command-positive-checks-failed.js b/test/fixtures/http/result-command-positive-checks-failed.js index e252c80..a82d32c 100644 --- a/test/fixtures/http/result-command-positive-checks-failed.js +++ b/test/fixtures/http/result-command-positive-checks-failed.js @@ -25,6 +25,8 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/fixtures/http/result-command-positive-pass.js b/test/fixtures/http/result-command-positive-pass.js new file mode 100644 index 0000000..cfec151 --- /dev/null +++ b/test/fixtures/http/result-command-positive-pass.js @@ -0,0 +1,63 @@ +'use strict' + +/** + * Mocks of HTTP calls for "wiby result" command positive flow + */ +const nock = require('nock') + +nock.disableNetConnect() + +nock('https://api.github.com') + // get package json + .post('/graphql') + .times(3) + .reply(200, { + data: { + repository: { + object: { + text: JSON.stringify({ + dependencies: { + wiby: '*' + } + }) + } + } + } + }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(200, {}) + // get check results + .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fake_run', conclusion: 'success' }, + { status: 'done', name: 'fake_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/fail/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'fail_run', conclusion: 'success' }, + { status: 'done', name: 'fail_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/pass/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'pass_run', conclusion: 'success' }, + { status: 'done', name: 'pass_run_2', conclusion: 'success' } + ] + }) + .get('/repos/wiby-test/partial/commits/wiby-running-unit-tests/check-runs') + .reply(200, { + check_runs: [ + { status: 'done', name: 'partial_run', conclusion: 'success' }, + { status: 'done', name: 'partial_run_2', conclusion: 'success' } + ] + }) diff --git a/test/fixtures/http/result-command-positive.js b/test/fixtures/http/result-command-positive-pending.js similarity index 80% rename from test/fixtures/http/result-command-positive.js rename to test/fixtures/http/result-command-positive-pending.js index a14b8d9..ed48952 100644 --- a/test/fixtures/http/result-command-positive.js +++ b/test/fixtures/http/result-command-positive-pending.js @@ -24,6 +24,14 @@ nock('https://api.github.com') } } }) + .get('/repos/wiby-test/fakeRepo/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/partial/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/pass/branches/wiby-running-unit-tests') + .reply(200, {}) + .get('/repos/wiby-test/fail/branches/wiby-running-unit-tests') + .reply(200, {}) // get check results .get('/repos/wiby-test/fakeRepo/commits/wiby-running-unit-tests/check-runs') .reply(200, { diff --git a/test/result.js b/test/result.js index 121f416..b601eac 100644 --- a/test/result.js +++ b/test/result.js @@ -53,13 +53,13 @@ tap.test('wiby.result()', async (tap) => { tap.test('result() should return correct data object', async (tap) => { // mock real http requests with positive scenario - require('./fixtures/http/result-command-positive') + require('./fixtures/http/result-command-positive-pass') const output = await wiby.result({ dependents: [{ repository: 'https://github.com/wiby-test/fakeRepo' }] }) - tap.equal(output.status, 'pending') + tap.equal(output.status, 'success') tap.equal(output.results[0].dependent, 'wiby-test/fakeRepo') - tap.equal(output.results[0].status, 'pending') + tap.equal(output.results[0].status, 'success') tap.equal(output.results[0].runs.length, 2) })