Skip to content

Commit

Permalink
feat: support external pipelines as nodes, logical OR
Browse files Browse the repository at this point in the history
  • Loading branch information
petey committed Oct 25, 2017
1 parent 3cd845d commit 164ce4c
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
24 changes: 16 additions & 8 deletions lib/getWorkflow.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
'use strict';

/**
* Remove the ~ prefix for logical OR on select node names.
* @method filterNodeName
* @param {String} name A Node Name, e.g. foo, ~foo, ~pr, ~commit, ~sd@1234:foo
* @return {String} A filtered node name, e.g. foo, foo, ~pr, ~commit, ~sd@1234:foo
*/
const filterNodeName = name => (/^~(pr|commit|sd@)/.test(name) ? name : name.replace('~', ''));

/**
* Get the list of nodes for the graph
* @method calculateNodes
* @param {Object} jobs Hash of job configs
* @return {Array} List of nodes (jobs)
*/
const calculateNodes = (jobs) => {
const nodes = [
{ name: '~pr' },
{ name: '~commit' }
];
const nodes = new Set(['~pr', '~commit']);

Object.keys(jobs).forEach((name) => {
nodes.push({ name });
nodes.add(name);
if (Array.isArray(jobs[name].requires)) {
jobs[name].requires.forEach(n => nodes.add(filterNodeName(n)));
}
});

return nodes;
return [...nodes].map(name => ({ name }));
};

/**
Expand Down Expand Up @@ -62,11 +70,11 @@ const calculateEdges = (jobs) => {
const isJoin = normalTriggers.length > 1;

specialTriggers.forEach((src) => {
edges.push({ src, dest });
edges.push({ src: filterNodeName(src), dest });
});

normalTriggers.forEach((src) => {
const obj = { src, dest };
const obj = { src: filterNodeName(src), dest };

if (isJoin) {
obj.join = true;
Expand Down
17 changes: 17 additions & 0 deletions test/data/expected-external.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"nodes": [
{ "name": "~pr" },
{ "name": "~commit" },
{ "name": "main" },
{ "name": "foo" },
{ "name": "bar" },
{ "name": "~sd@1234:foo" }
],
"edges": [
{ "src": "~pr", "dest": "main" },
{ "src": "~commit", "dest": "main" },
{ "src": "main", "dest": "foo" },
{ "src": "~sd@1234:foo", "dest": "bar" },
{ "src": "foo", "dest": "bar" }
]
}
7 changes: 7 additions & 0 deletions test/data/requires-workflow-exttrigger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"jobs": {
"main": { "requires": ["~pr", "~commit"] },
"foo": { "requires": ["main"] },
"bar": { "requires": ["foo", "~sd@1234:foo"] }
}
}
39 changes: 39 additions & 0 deletions test/lib/getWorkflow.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ const LEGACY_AND_REQUIRES_WORKFLOW = Object.assign({}, REQUIRES_WORKFLOW);

LEGACY_WITH_WORKFLOW.workflow = ['foo', 'bar'];

const EXTERNAL_TRIGGER = require('../data/requires-workflow-exttrigger');

const EXPECTED_OUTPUT = require('../data/expected-output');
const NO_EDGES = Object.assign({}, EXPECTED_OUTPUT);
const EXPECTED_EXTERNAL = require('../data/expected-external');

NO_EDGES.edges = [];

Expand All @@ -34,6 +37,9 @@ describe('getWorkflow', () => {
assert.deepEqual(getWorkflow(REQUIRES_WORKFLOW, {
useLegacy: true
}), EXPECTED_OUTPUT, 'requires-style workflow');
assert.deepEqual(getWorkflow(EXTERNAL_TRIGGER, {
useLegacy: true
}), EXPECTED_EXTERNAL, 'requires-style workflow with external trigger');
assert.deepEqual(getWorkflow(LEGACY_AND_REQUIRES_WORKFLOW, {
useLegacy: true
}), EXPECTED_OUTPUT, 'both legacy and non-legacy workflows');
Expand All @@ -51,6 +57,8 @@ describe('getWorkflow', () => {
EXPECTED_OUTPUT, 'requires-style workflow');
assert.deepEqual(getWorkflow(LEGACY_AND_REQUIRES_WORKFLOW),
EXPECTED_OUTPUT, 'both legacy and non-legacy workflows');
assert.deepEqual(getWorkflow(EXTERNAL_TRIGGER),
EXPECTED_EXTERNAL, 'requires-style workflow with external trigger');
});

it('should handle detatched jobs', () => {
Expand All @@ -67,6 +75,37 @@ describe('getWorkflow', () => {
});
});

it('should handle logical OR requires', () => {
const result = getWorkflow({
jobs: {
foo: { requires: ['~commit'] },
A: { requires: ['foo'] },
B: { requires: ['foo'] },
C: { requires: ['~A', '~B', '~sd@1234:foo'] }
}
});

assert.deepEqual(result, {
nodes: [
{ name: '~pr' },
{ name: '~commit' },
{ name: 'foo' },
{ name: 'A' },
{ name: 'B' },
{ name: 'C' },
{ name: '~sd@1234:foo' }
],
edges: [
{ src: '~commit', dest: 'foo' },
{ src: 'foo', dest: 'A' },
{ src: 'foo', dest: 'B' },
{ src: 'A', dest: 'C' },
{ src: 'B', dest: 'C' },
{ src: '~sd@1234:foo', dest: 'C' }
]
});
});

it('should handle joins', () => {
const result = getWorkflow({
jobs: {
Expand Down

0 comments on commit 164ce4c

Please sign in to comment.