Skip to content

Commit

Permalink
feat(3181): Skip execution of a virtual job when an event is started …
Browse files Browse the repository at this point in the history
…from that job (#635)


BREAKING CHANGE: Virtual job at the beginning of the event is no longer queued for execution. API changes are needed to process such build to mark its status as 'SUCCESS' and trigger its downstream jobs.
  • Loading branch information
sagar1312 authored Dec 12, 2024
1 parent 582a8fa commit cea3593
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 || 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": "31.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 cea3593

Please sign in to comment.