diff --git a/lib/getWorkflow.js b/lib/getWorkflow.js index def8ec9..9a58336 100644 --- a/lib/getWorkflow.js +++ b/lib/getWorkflow.js @@ -139,28 +139,31 @@ const calculateEdges = async (jobs, triggerFactory, externalDownstreamOrs, exter // for backward compatibility. TODO: remove this block later if (!triggerFactory) { Object.keys(jobs).forEach(j => { - const job = jobs[j]; + let { requires } = jobs[j]; const dest = j; - if (Array.isArray(job.requires)) { - const specialTriggers = new Set(job.requires.filter(name => name.charAt(0) === '~')); - const normalTriggers = new Set(job.requires.filter(name => name.charAt(0) !== '~')); - const isJoin = normalTriggers.size > 1; + // For plain text format 'requires: foo' + if (!Array.isArray(requires)) { + requires = requires ? [requires] : []; + } - specialTriggers.forEach(src => { - edges.push({ src: filterNodeName(src), dest }); - }); + const specialTriggers = new Set(requires.filter(name => name.charAt(0) === '~')); + const normalTriggers = new Set(requires.filter(name => name.charAt(0) !== '~')); + const isJoin = normalTriggers.size >= 1; - normalTriggers.forEach(src => { - const obj = { src, dest }; + specialTriggers.forEach(src => { + edges.push({ src: filterNodeName(src), dest }); + }); - if (isJoin) { - obj.join = true; - } + normalTriggers.forEach(src => { + const obj = { src, dest }; - edges.push(obj); - }); - } + if (isJoin) { + obj.join = true; + } + + edges.push(obj); + }); }); return edges; @@ -169,27 +172,30 @@ const calculateEdges = async (jobs, triggerFactory, externalDownstreamOrs, exter // new implementation. allow external join await Promise.all( Object.keys(jobs).map(async jobName => { - const job = jobs[jobName]; - - if (Array.isArray(job.requires)) { - // Calculate which upstream jobs trigger the current job - const upstreamOr = new Set(job.requires.filter(name => name.charAt(0) === '~')); - const upstreamAnd = new Set(job.requires.filter(name => name.charAt(0) !== '~')); - const isJoin = upstreamAnd.size > 1; - - upstreamOr.forEach(src => { - edges.push({ src: filterNodeName(src), dest: jobName }); - }); - upstreamAnd.forEach(src => { - const obj = { src, dest: jobName }; - - if (isJoin) { - obj.join = true; - } - edges.push(obj); - }); + let { requires } = jobs[jobName]; + + // For plain text format 'requires: foo' + if (!Array.isArray(requires)) { + requires = requires ? [requires] : []; } + // Calculate which upstream jobs trigger the current job + const upstreamOr = new Set(requires.filter(name => name.charAt(0) === '~')); + const upstreamAnd = new Set(requires.filter(name => name.charAt(0) !== '~')); + const isJoin = upstreamAnd.size >= 1; + + upstreamOr.forEach(src => { + edges.push({ src: filterNodeName(src), dest: jobName }); + }); + upstreamAnd.forEach(src => { + const obj = { src, dest: jobName }; + + if (isJoin) { + obj.join = true; + } + edges.push(obj); + }); + const externalDownstreamOr = jobName in externalDownstreamOrs ? externalDownstreamOrs[jobName] : []; const externalDownstreamAnd = jobName in externalDownstreamAnds ? externalDownstreamAnds[jobName] : []; diff --git a/test/data/expected-external-complex.json b/test/data/expected-external-complex.json index 2e8d417..4be6396 100644 --- a/test/data/expected-external-complex.json +++ b/test/data/expected-external-complex.json @@ -18,7 +18,7 @@ { "src": "A", "dest": "sd@777:external-level1" }, { "src": "A", "dest": "sd@111:external-level1" }, { "src": "A", "dest": "sd@333:external-level1" }, - { "src": "A", "dest": "B" }, + { "src": "A", "dest": "B", "join": true }, { "src": "~sd@888:external-level2", "dest": "C" }, { "src": "B", "dest": "C", "join": true }, { "src": "sd@222:external-level2", "dest": "C", "join": true }, diff --git a/test/data/expected-external-join.json b/test/data/expected-external-join.json index 434a182..ebffd26 100644 --- a/test/data/expected-external-join.json +++ b/test/data/expected-external-join.json @@ -11,7 +11,7 @@ "edges": [ { "src": "~pr", "dest": "main" }, { "src": "~commit", "dest": "main" }, - { "src": "main", "dest": "foo" }, + { "src": "main", "dest": "foo", "join": true }, { "src": "foo", "dest": "sd@111:baz" }, { "src": "foo", "dest": "sd@1234:foo" }, { "src": "sd@111:baz", "dest": "bar", "join": true }, diff --git a/test/data/expected-external.json b/test/data/expected-external.json index 4f7cd97..4059105 100644 --- a/test/data/expected-external.json +++ b/test/data/expected-external.json @@ -11,7 +11,7 @@ "edges": [ { "src": "~pr", "dest": "main" }, { "src": "~commit", "dest": "main" }, - { "src": "main", "dest": "foo" }, + { "src": "main", "dest": "foo", "join": true }, { "src": "~sd@1234:foo", "dest": "bar" }, { "src": "foo", "dest": "bar", "join": true }, { "src": "sd@111:baz", "dest": "bar", "join": true } diff --git a/test/data/expected-output.json b/test/data/expected-output.json index d89b54b..805cc0a 100644 --- a/test/data/expected-output.json +++ b/test/data/expected-output.json @@ -13,7 +13,7 @@ "edges": [ { "src": "~pr", "dest": "main" }, { "src": "~commit", "dest": "main" }, - { "src": "main", "dest": "foo" }, + { "src": "main", "dest": "foo", "join": true }, { "src": "foo", "dest": "bar" }, { "src": "promote", "dest": "bar" }, { "src": "~release", "dest": "baz" }, diff --git a/test/lib/getSrcForJoin.test.js b/test/lib/getSrcForJoin.test.js index 2d9f2cb..64b42d3 100644 --- a/test/lib/getSrcForJoin.test.js +++ b/test/lib/getSrcForJoin.test.js @@ -43,7 +43,7 @@ describe('getSrcForJoin', () => { it('should figure out what src for the job for a complex workflow', () => { // src nodes for join job assert.deepEqual(getSrcForJoin(EXTERNAL_COMPLEX_WORKFLOW, { jobName: 'A' }), []); - assert.deepEqual(getSrcForJoin(EXTERNAL_COMPLEX_WORKFLOW, { jobName: 'B' }), []); + assert.deepEqual(getSrcForJoin(EXTERNAL_COMPLEX_WORKFLOW, { jobName: 'B' }), [{ name: 'A' }]); assert.deepEqual(getSrcForJoin(EXTERNAL_COMPLEX_WORKFLOW, { jobName: 'C' }), [ { name: 'B' }, { name: 'sd@222:external-level2' }, diff --git a/test/lib/getWorkflow.test.js b/test/lib/getWorkflow.test.js index d55cdbb..ec5bec5 100644 --- a/test/lib/getWorkflow.test.js +++ b/test/lib/getWorkflow.test.js @@ -71,7 +71,7 @@ describe('getWorkflow', () => { assert.deepEqual(result, { nodes: [{ name: '~pr' }, { name: '~commit' }, { name: 'foo' }, { name: 'bar' }], - edges: [{ src: 'foo', dest: 'bar' }] + edges: [{ src: 'foo', dest: 'bar', join: true }] }); }); @@ -100,8 +100,8 @@ describe('getWorkflow', () => { ], edges: [ { src: '~commit', dest: 'foo' }, - { src: 'foo', dest: 'A' }, - { src: 'foo', dest: 'B' }, + { src: 'foo', dest: 'A', join: true }, + { src: 'foo', dest: 'B', join: true }, { src: 'A', dest: 'C' }, { src: 'B', dest: 'C' }, { src: '~sd@1234:foo', dest: 'C' } @@ -137,8 +137,8 @@ describe('getWorkflow', () => { ], edges: [ { src: '~commit', dest: 'foo' }, - { src: 'foo', dest: 'A' }, - { src: 'foo', dest: 'B' }, + { src: 'foo', dest: 'A', join: true }, + { src: 'foo', dest: 'B', join: true }, { src: 'A', dest: 'C' }, { src: 'B', dest: 'C' }, { src: 'D', dest: 'C', join: true }, @@ -160,7 +160,7 @@ describe('getWorkflow', () => { assert.deepEqual(result, { nodes: [{ name: '~pr' }, { name: '~commit' }, { name: 'foo' }, { name: 'A' }], - edges: [{ src: 'A', dest: 'foo' }] + edges: [{ src: 'A', dest: 'foo', join: true }] }); }); @@ -187,8 +187,8 @@ describe('getWorkflow', () => { { name: 'bax' } ], edges: [ - { src: 'foo', dest: 'bar' }, - { src: 'foo', dest: 'baz' }, + { src: 'foo', dest: 'bar', join: true }, + { src: 'foo', dest: 'baz', join: true }, { src: 'bar', dest: 'bax', join: true }, { src: 'baz', dest: 'bax', join: true } ] @@ -324,25 +324,25 @@ describe('getWorkflow', () => { ], edges: [ { src: '~commit', dest: 'stage@alpha:setup' }, - { src: 'stage@alpha:setup', dest: 'alpha-deploy' }, - { src: 'alpha-deploy', dest: 'alpha-test' }, - { src: 'alpha-test', dest: 'alpha-certify' }, - { src: 'alpha-certify', dest: 'stage@alpha:teardown' }, + { src: 'stage@alpha:setup', dest: 'alpha-deploy', join: true }, + { src: 'alpha-deploy', dest: 'alpha-test', join: true }, + { src: 'alpha-test', dest: 'alpha-certify', join: true }, + { src: 'alpha-certify', dest: 'stage@alpha:teardown', join: true }, { src: 'stage@alpha:teardown', dest: 'stage@beta:setup' }, { src: 'stage@beta:setup', dest: 'beta-deploy' }, { src: 'beta-deploy', dest: 'beta-test' }, { src: 'beta-test', dest: 'beta-certify' }, { src: 'beta-certify', dest: 'stage@beta:teardown' }, - { src: 'triggering-a-stage', dest: 'stage@gamma:setup' }, - { src: 'stage@gamma:setup', dest: 'gamma-deploy' }, - { src: 'gamma-deploy', dest: 'gamma-test-integration' }, - { src: 'gamma-deploy', dest: 'gamma-test-functional' }, + { src: 'triggering-a-stage', dest: 'stage@gamma:setup', join: true }, + { src: 'stage@gamma:setup', dest: 'gamma-deploy', join: true }, + { src: 'gamma-deploy', dest: 'gamma-test-integration', join: true }, + { src: 'gamma-deploy', dest: 'gamma-test-functional', join: true }, { src: 'gamma-test-integration', dest: 'gamma-certify', join: true }, { src: 'gamma-test-functional', dest: 'gamma-certify', join: true }, - { src: 'gamma-certify', dest: 'stage@gamma:teardown' }, + { src: 'gamma-certify', dest: 'stage@gamma:teardown', join: true }, { src: '~commit', dest: 'triggering-a-stage' }, - { src: 'gamma-test-integration', dest: 'triggered-by-a-stage-job' }, - { src: 'stage@gamma:teardown', dest: 'triggered-after-a-stage' } + { src: 'gamma-test-integration', dest: 'triggered-by-a-stage-job', join: true }, + { src: 'stage@gamma:teardown', dest: 'triggered-after-a-stage', join: true } ] }); });