Skip to content

Commit

Permalink
fix(3012): Trigger remote join job in restart when the last remote jo…
Browse files Browse the repository at this point in the history
…in job is successful (#3132)
  • Loading branch information
yakanechi authored Jun 6, 2024
1 parent 23ee643 commit b29780f
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 11 deletions.
15 changes: 14 additions & 1 deletion plugins/builds/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const {
createExternalEvent,
getBuildsForGroupEvent,
buildsToRestartFilter,
trimJobName
trimJobName,
getParallelBuilds
} = require('./triggers/helpers');

/**
Expand Down Expand Up @@ -140,6 +141,18 @@ async function triggerNextJobs(config, app) {
// This includes CREATED builds too
const groupEventBuilds =
externalEvent !== undefined ? await getBuildsForGroupEvent(externalEvent.groupEventId, buildFactory) : [];

// fetch builds created due to trigger
if (externalEvent) {
const parallelBuilds = await getParallelBuilds({
eventFactory,
parentEventId: externalEvent.id,
pipelineId: externalEvent.pipelineId
});

groupEventBuilds.push(...parallelBuilds);
}

const buildsToRestart = buildsToRestartFilter(joinedPipeline, groupEventBuilds, currentEvent, currentBuild);
const isRestart = buildsToRestart.length > 0;

Expand Down
11 changes: 1 addition & 10 deletions plugins/builds/triggers/remoteJoin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

const { getParallelBuilds, mergeParentBuilds, getParentBuildIds } = require('./helpers');
const { mergeParentBuilds, getParentBuildIds } = require('./helpers');
const { JoinBase } = require('./joinBase');

/**
Expand Down Expand Up @@ -31,15 +31,6 @@ class RemoteJoin extends JoinBase {
* @returns {Promise<Build|null>}
*/
async execute(externalEvent, nextJobName, nextJobId, parentBuilds, groupEventBuilds, joinListNames) {
// fetch builds created due to trigger
const parallelBuilds = await getParallelBuilds({
eventFactory: this.eventFactory,
parentEventId: externalEvent.id,
pipelineId: externalEvent.pipelineId
});

groupEventBuilds.push(...parallelBuilds);

// When restart case, should we create a new build ?
const nextBuild = groupEventBuilds.find(b => b.jobId === nextJobId && b.eventId === externalEvent.id);

Expand Down
137 changes: 137 additions & 0 deletions test/plugins/trigger.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1634,6 +1634,34 @@ describe('trigger tests', () => {
assert.equal(upstreamPipeline.getBuildsOf('target').length, 1);
});

it('[ sd@2:a, sd@2:b ] is triggered in restart event when only sd@2:b restarts', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@2:b-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@2:b-downstream.yaml');

const upstreamEvent = await eventFactoryMock.create({
pipelineId: upstreamPipeline.id,
startFrom: 'hub'
});

await upstreamEvent.run();

const downstreamEvent = downstreamPipeline.getLatestEvent();

await downstreamEvent.getBuildOf('a').complete('SUCCESS');
await downstreamEvent.getBuildOf('b').complete('SUCCESS');

const downstreamRestartEvent = await downstreamEvent.restartFrom('b');

assert.isNull(downstreamRestartEvent.getBuildOf('a'));
await downstreamRestartEvent.getBuildOf('b').complete('SUCCESS');

const upstreamRestartEvent = upstreamPipeline.getLatestEvent();

assert.equal(upstreamEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamRestartEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamPipeline.getBuildsOf('target').length, 2);
});

it('Multiple [ sd@2:a, sd@2:b ] is triggered', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@2:b-multiple-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@2:b-downstream.yaml');
Expand Down Expand Up @@ -1850,6 +1878,30 @@ describe('trigger tests', () => {
assert.equal(upstreamPipeline.getBuildsOf('target').length, 1);
});

it('[ sd@2:a, b ] is triggered in restart event when only b restarts', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_b-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_b-downstream.yaml');

const upstreamEvent = await eventFactoryMock.create({
pipelineId: upstreamPipeline.id,
startFrom: 'hub'
});

await upstreamEvent.run();

const downstreamEvent = downstreamPipeline.getLatestEvent();

await downstreamEvent.getBuildOf('a').complete('SUCCESS');

const upstreamRestartEvent = await upstreamEvent.restartFrom('b');

await upstreamRestartEvent.getBuildOf('b').complete('SUCCESS');

assert.equal(upstreamEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamRestartEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamPipeline.getBuildsOf('target').length, 2);
});

it('[ sd@2:a, sd@3:a ] is triggered', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@3:a-upstream.yaml');
const downstreamPipeline1 = await pipelineFactoryMock.createFromFile('sd@2:a_sd@3:a-downstream.yaml');
Expand Down Expand Up @@ -1953,6 +2005,35 @@ describe('trigger tests', () => {
assert.equal(upstreamPipeline.getBuildsOf('target').length, 1);
});

it('[ sd@2:a, sd@3:a ] is triggered in restart event when only sd@3:a restarts', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('sd@2:a_sd@3:a-upstream.yaml');
const downstreamPipeline1 = await pipelineFactoryMock.createFromFile('sd@2:a_sd@3:a-downstream.yaml');
const downstreamPipeline2 = await pipelineFactoryMock.createFromFile('sd@2:a_sd@3:a-downstream.yaml');

const upstreamEvent = await eventFactoryMock.create({
pipelineId: upstreamPipeline.id,
startFrom: 'hub'
});

await upstreamEvent.run();

const downstreamEvent1 = downstreamPipeline1.getLatestEvent();
const downstreamEvent2 = downstreamPipeline2.getLatestEvent();

await downstreamEvent1.getBuildOf('a').complete('SUCCESS');
await downstreamEvent2.getBuildOf('a').complete('SUCCESS');

const downstreamRestartEvent2 = await downstreamEvent2.restartFrom('a');

await downstreamRestartEvent2.getBuildOf('a').complete('SUCCESS');

const upstreamRestartEvent = upstreamPipeline.getLatestEvent();

assert.equal(upstreamEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamRestartEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamPipeline.getBuildsOf('target').length, 2);
});

it('[ ~sd@2:a, sd@2:b, sd@2:c ] is triggered when sd@2:a succeeds', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:b_sd@2:c-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:b_sd@2:c-downstream.yaml');
Expand Down Expand Up @@ -2061,6 +2142,35 @@ describe('trigger tests', () => {
assert.equal(upstreamPipeline.getBuildsOf('target').length, 1);
});

it('[ ~sd@2:a, sd@2:b, sd@2:c ] is triggered in restart event when only sd@2:c restarts', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:b_sd@2:c-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:b_sd@2:c-downstream.yaml');

const upstreamEvent = await eventFactoryMock.create({
pipelineId: upstreamPipeline.id,
startFrom: 'hub'
});

await upstreamEvent.run();

const downstreamEvent = downstreamPipeline.getLatestEvent();

await downstreamEvent.getBuildOf('a').complete('SUCCESS');
await downstreamEvent.getBuildOf('b').complete('SUCCESS');
await downstreamEvent.getBuildOf('c').complete('SUCCESS');

const downstreamRestartEvent = await downstreamEvent.restartFrom('c');

assert.isNull(downstreamRestartEvent.getBuildOf('b'));
await downstreamRestartEvent.getBuildOf('c').complete('SUCCESS');

const upstreamRestartEvent = upstreamPipeline.getLatestEvent();

assert.equal(upstreamEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamRestartEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamPipeline.getBuildsOf('target').length, 2);
});

it('[ ~sd@2:a, b, c ] is triggered', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_b_c-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_b_c-downstream.yaml');
Expand Down Expand Up @@ -2486,6 +2596,33 @@ describe('trigger tests', () => {
assert.equal(upstreamPipeline.getBuildsOf('target').length, 1);
});

it('[ ~sd@2:a, sd@2:a, sd@2:b ] is triggered in restart event when only sd@1:a restarts', async () => {
const upstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:a_sd@2:b-upstream.yaml');
const downstreamPipeline = await pipelineFactoryMock.createFromFile('~sd@2:a_sd@2:a_sd@2:b-downstream.yaml');

const upstreamEvent = await eventFactoryMock.create({
pipelineId: upstreamPipeline.id,
startFrom: 'hub'
});

await upstreamEvent.run();

const downstreamEvent = downstreamPipeline.getLatestEvent();

await downstreamEvent.getBuildOf('a').complete('SUCCESS');
await downstreamEvent.getBuildOf('b').complete('SUCCESS');

const downstreamRestartEvent = await downstreamEvent.restartFrom('a');

await downstreamRestartEvent.getBuildOf('a').complete('SUCCESS');

const upstreamRestartEvent = upstreamPipeline.getLatestEvent();

assert.equal(upstreamEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamRestartEvent.getBuildOf('target').status, 'RUNNING');
assert.equal(upstreamPipeline.getBuildsOf('target').length, 2);
});

it('[ sd@3:a, sd@3:b ] is triggered in second stream pipeline', async () => {
const firstPipeline = await pipelineFactoryMock.createFromFile('sd@3:a_sd@3:b-first.yaml');
const secondPipeline = await pipelineFactoryMock.createFromFile('sd@3:a_sd@3:b-second.yaml');
Expand Down

0 comments on commit b29780f

Please sign in to comment.