Skip to content

Commit 38a0345

Browse files
authored
fix(3271): Enables sourcePaths to be used in stage [2] (#178)
1 parent 09cf38b commit 38a0345

6 files changed

Lines changed: 330 additions & 1 deletion

lib/phase/flatten.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,17 @@ function flattenStageSetupAndTeardownJobs(doc) {
700700
stageTeardown = DEFAULT_JOB;
701701
}
702702

703+
// Use 'sourcePaths' from setup job if defined; otherwise, use the stage's value or default to [].
704+
const sourcePaths =
705+
stageSetup.sourcePaths !== undefined ? stageSetup.sourcePaths : stages[stageName].sourcePaths || [];
706+
703707
newJobs[setupStageName] = {
704708
...stageSetup,
705-
...{ requires: stages[stageName].requires || [], stage: { name: stageName } }
709+
...{
710+
requires: stages[stageName].requires || [],
711+
stage: { name: stageName },
712+
sourcePaths
713+
}
706714
};
707715
newJobs[teardownStageName] = {
708716
...stageTeardown,

lib/phase/functional.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,13 @@ function validateStages(stages, jobs) {
315315
});
316316
});
317317

318+
// If jobs in stages have sourcePaths set, throw error
319+
stageJobNames.forEach(jobName => {
320+
if (jobs[jobName] && jobs[jobName].sourcePaths && jobs[jobName].sourcePaths.length > 0) {
321+
errors.push(`Job ${jobName} in stage cannot have sourcePaths defined.`);
322+
}
323+
});
324+
318325
return errors;
319326
}
320327

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
stages:
2+
foobar:
3+
requires: [ ~commit ]
4+
jobs: [ foo, bar ]
5+
6+
shared:
7+
image: node:18
8+
steps:
9+
- echo: echo foo
10+
11+
jobs:
12+
foo:
13+
requires: []
14+
sourcePaths: [ "src/" ] # Error if the stage job defines sourcePaths
15+
bar:
16+
requires: [ foo ]
Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
{
2+
"annotations": {},
3+
"parameters": {},
4+
"subscribe": {},
5+
"jobs": {
6+
"foo": [
7+
{
8+
"annotations": {},
9+
"commands": [
10+
{
11+
"command": "echo foo",
12+
"name": "echo"
13+
}
14+
],
15+
"environment": {},
16+
"image": "node:18",
17+
"secrets": [],
18+
"settings": {},
19+
"requires": [
20+
"~stage@foobar:setup"
21+
],
22+
"stage": {
23+
"name": "foobar"
24+
}
25+
}
26+
],
27+
"bar": [
28+
{
29+
"annotations": {},
30+
"commands": [
31+
{
32+
"command": "echo foo",
33+
"name": "echo"
34+
}
35+
],
36+
"environment": {},
37+
"image": "node:18",
38+
"secrets": [],
39+
"settings": {},
40+
"requires": [
41+
"foo"
42+
],
43+
"stage": {
44+
"name": "foobar"
45+
}
46+
}
47+
],
48+
"baz": [
49+
{
50+
"annotations": {},
51+
"commands": [
52+
{
53+
"command": "echo foo",
54+
"name": "echo"
55+
}
56+
],
57+
"environment": {},
58+
"image": "node:18",
59+
"secrets": [],
60+
"settings": {},
61+
"requires": [
62+
"~stage@bazqux:setup"
63+
],
64+
"stage": {
65+
"name": "bazqux"
66+
}
67+
}
68+
],
69+
"qux": [
70+
{
71+
"annotations": {},
72+
"commands": [
73+
{
74+
"command": "echo foo",
75+
"name": "echo"
76+
}
77+
],
78+
"environment": {},
79+
"image": "node:18",
80+
"secrets": [],
81+
"settings": {},
82+
"requires": [
83+
"baz"
84+
],
85+
"stage": {
86+
"name": "bazqux"
87+
}
88+
}
89+
],
90+
"stage@foobar:setup": [
91+
{
92+
"annotations": {
93+
"screwdriver.cd/virtualJob": true
94+
},
95+
"commands": [
96+
{
97+
"command": "echo noop",
98+
"name": "noop"
99+
}
100+
],
101+
"environment": {},
102+
"image": "node:18",
103+
"secrets": [],
104+
"settings": {},
105+
"requires": [
106+
"~commit"
107+
],
108+
"stage": {
109+
"name": "foobar"
110+
},
111+
"sourcePaths": [
112+
"src/"
113+
]
114+
}
115+
],
116+
"stage@foobar:teardown": [
117+
{
118+
"annotations": {
119+
"screwdriver.cd/virtualJob": true
120+
},
121+
"commands": [
122+
{
123+
"command": "echo noop",
124+
"name": "noop"
125+
}
126+
],
127+
"environment": {},
128+
"image": "node:18",
129+
"secrets": [],
130+
"settings": {},
131+
"requires": [
132+
"bar"
133+
],
134+
"stage": {
135+
"name": "foobar"
136+
}
137+
}
138+
],
139+
"stage@bazqux:setup": [
140+
{
141+
"annotations": {},
142+
"commands": [
143+
{
144+
"command": "echo bazqux",
145+
"name": "echo"
146+
}
147+
],
148+
"environment": {},
149+
"image": "node:18",
150+
"secrets": [],
151+
"settings": {},
152+
"requires": [
153+
"~commit"
154+
],
155+
"stage": {
156+
"name": "bazqux"
157+
},
158+
"sourcePaths": [
159+
"config/"
160+
]
161+
}
162+
],
163+
"stage@bazqux:teardown": [
164+
{
165+
"annotations": {
166+
"screwdriver.cd/virtualJob": true
167+
},
168+
"commands": [
169+
{
170+
"command": "echo noop",
171+
"name": "noop"
172+
}
173+
],
174+
"environment": {},
175+
"image": "node:18",
176+
"secrets": [],
177+
"settings": {},
178+
"requires": [
179+
"qux"
180+
],
181+
"stage": {
182+
"name": "bazqux"
183+
}
184+
}
185+
]
186+
},
187+
"workflowGraph": {
188+
"nodes": [
189+
{ "name": "~pr" },
190+
{ "name": "~commit" },
191+
{ "name": "foo", "stageName": "foobar" },
192+
{
193+
"name": "stage@foobar:setup",
194+
"virtual": true,
195+
"stageName": "foobar"
196+
},
197+
{ "name": "bar", "stageName": "foobar" },
198+
{ "name": "baz", "stageName": "bazqux" },
199+
{ "name": "stage@bazqux:setup", "stageName": "bazqux" },
200+
{ "name": "qux", "stageName": "bazqux" },
201+
{
202+
"name": "stage@foobar:teardown",
203+
"virtual": true,
204+
"stageName": "foobar"
205+
},
206+
{
207+
"name": "stage@bazqux:teardown",
208+
"virtual": true,
209+
"stageName": "bazqux"
210+
}
211+
],
212+
"edges": [
213+
{ "src": "stage@foobar:setup", "dest": "foo" },
214+
{ "src": "foo", "dest": "bar", "join": true },
215+
{ "src": "stage@bazqux:setup", "dest": "baz" },
216+
{ "src": "baz", "dest": "qux", "join": true },
217+
{ "src": "~commit", "dest": "stage@foobar:setup" },
218+
{ "src": "bar", "dest": "stage@foobar:teardown", "join": true },
219+
{ "src": "~commit", "dest": "stage@bazqux:setup" },
220+
{ "src": "qux", "dest": "stage@bazqux:teardown", "join": true }
221+
]
222+
},
223+
"stages": {
224+
"bazqux": {
225+
"jobs": [
226+
"baz",
227+
"qux"
228+
],
229+
"requires": [
230+
"~commit"
231+
],
232+
"sourcePaths": [
233+
"bin/"
234+
]
235+
},
236+
"foobar": {
237+
"jobs": [
238+
"foo",
239+
"bar"
240+
],
241+
"requires": [
242+
"~commit"
243+
],
244+
"sourcePaths": [
245+
"src/"
246+
]
247+
}
248+
}
249+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
stages:
2+
foobar:
3+
requires: [ ~commit ]
4+
jobs: [ foo, bar ]
5+
sourcePaths: [ "src/" ]
6+
bazqux:
7+
requires: [ ~commit ]
8+
jobs: [ baz, qux ]
9+
sourcePaths: [ "bin/" ]
10+
setup:
11+
image: node:18
12+
steps:
13+
- echo: echo bazqux
14+
sourcePaths: [ "config/" ] # If sourcePaths is set in both stage and setup job, use the value of setup job.
15+
16+
shared:
17+
image: node:18
18+
steps:
19+
- echo: echo foo
20+
21+
jobs:
22+
foo:
23+
requires: []
24+
bar:
25+
requires: [ foo ]
26+
baz:
27+
requires: []
28+
qux:
29+
requires: [ baz ]

test/index.test.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,16 @@ describe('config parser', () => {
225225
);
226226
}));
227227

228+
it('returns a yaml with sourcePaths set in stages', () =>
229+
parser({
230+
yaml: loadData('pipeline-with-stages-and-sourcePaths.yaml'),
231+
templateFactory: templateFactoryMock,
232+
triggerFactory,
233+
pipelineId
234+
}).then(data => {
235+
assert.deepEqual(data, JSON.parse(loadData('pipeline-with-stages-and-sourcePaths.json')));
236+
}));
237+
228238
it('returns an error if bad stages', () =>
229239
parser({ yaml: loadData('bad-stages.yaml'), triggerFactory, pipelineId }).then(data => {
230240
assert.match(
@@ -265,6 +275,16 @@ describe('config parser', () => {
265275
/Error: main job has invalid requires: baz. Triggers must be jobs from canary stage./
266276
);
267277
}));
278+
279+
it('returns an error if sourcePaths is set for a job defined in stage.', () =>
280+
parser({
281+
yaml: loadData('pipeline-with-stages-and-invalid-sourcePaths.yaml'),
282+
templateFactory: templateFactoryMock,
283+
triggerFactory,
284+
pipelineId
285+
}).then(data => {
286+
assert.match(data.errors[0], /Error: Job foo in stage cannot have sourcePaths defined./);
287+
}));
268288
});
269289

270290
describe('subscribe', () => {

0 commit comments

Comments
 (0)