Skip to content

Commit

Permalink
fix(3181): Skip execution of a virtual job when an event is started f…
Browse files Browse the repository at this point in the history
…rom that job
  • Loading branch information
sagar1312 committed Dec 12, 2024
1 parent 582a8fa commit f634588
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 48 deletions.
91 changes: 45 additions & 46 deletions lib/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,56 +526,55 @@ class BuildModel extends BaseModel {
return this.job.then(job =>
Promise.all([job.pipeline, job.prNum])
.then(([pipeline, prNum]) =>
getBlockedByIds(pipeline, job).then(blockedBy => {
const config = {
build: this,
buildId: this.id,
eventId: this.eventId,
jobId: job.id,
jobState: job.state,
jobArchived: job.archived,
jobName: job.name,
annotations: hoek.reach(job.permutations[0], 'annotations', { default: {} }),
blockedBy,
pipelineId: pipeline.id,
pipeline: {
id: pipeline.id,
name: pipeline.name,
scmContext: pipeline.scmContext,
configPipelineId: pipeline.configPipelineId
},
causeMessage: causeMessage || '',
freezeWindows: hoek.reach(job.permutations[0], 'freezeWindows', { default: [] }),
apiUri: this[apiUri],
container: this.container,
tokenGen: this[tokenGen],
token: getToken(this, job, pipeline),
isPR: job.isPR(),
prParentJobId: job.prParentJobId
};

if (template && !hoek.deepEqual(template, {})) {
config.template = template;
}
getBlockedByIds(pipeline, job)
.then(blockedBy => {
const config = {
build: this,
buildId: this.id,
eventId: this.eventId,
jobId: job.id,
jobState: job.state,
jobArchived: job.archived,
jobName: job.name,
annotations: hoek.reach(job.permutations[0], 'annotations', { default: {} }),
blockedBy,
pipelineId: pipeline.id,
pipeline: {
id: pipeline.id,
name: pipeline.name,
scmContext: pipeline.scmContext,
configPipelineId: pipeline.configPipelineId
},
causeMessage: causeMessage || '',
freezeWindows: hoek.reach(job.permutations[0], 'freezeWindows', { default: [] }),
apiUri: this[apiUri],
container: this.container,
tokenGen: this[tokenGen],
token: getToken(this, job, pipeline),
isPR: job.isPR(),
prParentJobId: job.prParentJobId
};

if (template && !hoek.deepEqual(template, {})) {
config.template = template;
}

if (prNum) {
config.prNum = prNum;
}
if (prNum) {
config.prNum = prNum;
}

if (this.buildClusterName) {
config.buildClusterName = this.buildClusterName;
}
if (this.buildClusterName) {
config.buildClusterName = this.buildClusterName;
}

if (hoek.reach(job.permutations[0], 'provider')) {
config.provider = job.permutations[0].provider;
}
if (hoek.reach(job.permutations[0], 'provider')) {
config.provider = job.permutations[0].provider;
}

return Promise.all([
this[executor].start(config),
this.updateCommitStatus(pipeline) // update github
]);
})
)
return this[executor].start(config);
})
.then(() => this.updateCommitStatus(pipeline))
) // update github
.then(() => this)
);
}
Expand Down
7 changes: 7 additions & 0 deletions lib/eventFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,13 @@ function createBuilds(config) {

buildConfig.configPipelineSha = pipelineConfig.configPipelineSha;

const { annotations, freezeWindows } = j.permutations[0];
const isVirtualJob = annotations ? annotations['screwdriver.cd/virtualJob'] === true : false;
const hasFreezeWindows = freezeWindows ? freezeWindows.length > 0 : false;

// Bypass execution of the build if the job is virtual
buildConfig.start = !isVirtualJob || (isVirtualJob && hasFreezeWindows);

return startBuild({
decoratedCommit,
subscribedConfigSha,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "screwdriver-models",
"version": "29.0.0",
"version": "30.0.0",
"description": "Screwdriver models",
"main": "index.js",
"scripts": {
Expand Down
89 changes: 88 additions & 1 deletion test/lib/eventFactory.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ describe('Event Factory', () => {
{ name: '~pr' },
{ name: '~commit' },
{ name: 'main' },
{ name: 'firstVirtual' },
{ name: 'secondVirtual' },
{ name: 'disabledJob' },
{ name: 'stage@integration:setup', stageName: 'integration' },
{ name: 'int-deploy', stageName: 'integration' },
Expand All @@ -198,6 +200,8 @@ describe('Event Factory', () => {
{ src: '~sd@123:main', dest: 'main' },
{ src: '~pr', dest: 'main' },
{ src: '~commit', dest: 'main' },
{ src: '~commit', dest: 'firstVirtual' },
{ src: '~commit', dest: 'secondVirtual' },
{ src: 'main', dest: 'disabledJob' },
{ src: 'main', dest: 'stage@integration:setup' },
{ src: 'stage@integration:setup', dest: 'int-deploy' },
Expand Down Expand Up @@ -236,6 +240,8 @@ describe('Event Factory', () => {
{ name: '~pr' },
{ name: '~commit' },
{ name: 'main' },
{ name: 'firstVirtual' },
{ name: 'secondVirtual' },
{ name: 'disabledJob' },
{ name: 'stage@integration:setup', stageName: 'integration' },
{ name: 'int-deploy', stageName: 'integration' },
Expand All @@ -255,6 +261,8 @@ describe('Event Factory', () => {
{ src: '~sd@123:main', dest: 'main' },
{ src: '~pr', dest: 'main' },
{ src: '~commit', dest: 'main' },
{ src: '~commit', dest: 'firstVirtual' },
{ src: '~commit', dest: 'secondVirtual' },
{ src: 'main', dest: 'disabledJob' },
{ src: 'main', dest: 'stage@integration:setup' },
{ src: 'stage@integration:setup', dest: 'int-deploy' },
Expand Down Expand Up @@ -471,6 +479,38 @@ describe('Event Factory', () => {
],
state: 'ENABLED',
isPR: sinon.stub().returns(false)
},

{
id: 16,
pipelineId: 8765,
name: 'firstVirtual',
permutations: [
{
requires: ['~commit', '~pr'],
annotations: {
'screwdriver.cd/virtualJob': true
}
}
],
state: 'ENABLED',
isPR: sinon.stub().returns(false)
},
{
id: 17,
pipelineId: 8765,
name: 'secondVirtual',
permutations: [
{
requires: ['~commit', '~pr'],
freezeWindows: ['* 10-21 ? * *'],
annotations: {
'screwdriver.cd/virtualJob': true
}
}
],
state: 'ENABLED',
isPR: sinon.stub().returns(false)
}
];

Expand Down Expand Up @@ -901,12 +941,59 @@ describe('Event Factory', () => {
return eventFactory.create(config).then(model => {
assert.instanceOf(model, Event);
assert.notCalled(jobFactoryMock.create);
assert.callCount(buildFactoryMock.create, 6);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 1
jobId: 1,
start: true
})
);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 5,
start: true
})
);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 6,
start: true
})
);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 7,
start: true
})
);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 16,
start: false // should skip execution of virtual job without freeze windows
})
);
assert.calledWith(
buildFactoryMock.create,
sinon.match({
parentBuildId: 12345,
eventId: model.id,
jobId: 17,
start: true
})
);
assert.calledOnce(pipelineMock.sync);
Expand Down

0 comments on commit f634588

Please sign in to comment.