Skip to content

Commit 57c0890

Browse files
authored
Merge pull request #149 from buildkite/ming/pb-939
PB-939: Update pipeline YAML schema to match if_changed doc
2 parents 47d87ef + 0009077 commit 57c0890

File tree

3 files changed

+115
-16
lines changed

3 files changed

+115
-16
lines changed

schema.json

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,9 +493,58 @@
493493
}
494494
},
495495
"if_changed": {
496-
"type": "string",
497-
"description": "Agent-applied attribute: A glob pattern that omits the step from a build if it does not match any files changed in the build.",
498-
"examples": ["**.go", "go.mod", "go.sum", "fixtures/**"]
496+
"description": "Agent-applied attribute: A glob pattern that omits the step from a build if it does not match any files changed in the build. Can be a single pattern, list of patterns, or an object with include/exclude attributes.",
497+
"oneOf": [
498+
{
499+
"type": "string",
500+
"description": "A single glob pattern",
501+
"examples": ["**.go", "go.{mod,sum}", "{app/**,spec/**}"]
502+
},
503+
{
504+
"type": "array",
505+
"description": "A list of glob patterns",
506+
"items": {
507+
"type": "string"
508+
},
509+
"examples": [["**.go", "go.{mod,sum}"], ["app/**", "spec/**"]]
510+
},
511+
{
512+
"type": "object",
513+
"description": "An object with include and optional exclude patterns",
514+
"properties": {
515+
"include": {
516+
"description": "Pattern or list of patterns to include",
517+
"oneOf": [
518+
{
519+
"type": "string"
520+
},
521+
{
522+
"type": "array",
523+
"items": {
524+
"type": "string"
525+
}
526+
}
527+
]
528+
},
529+
"exclude": {
530+
"description": "Pattern or list of patterns to exclude",
531+
"oneOf": [
532+
{
533+
"type": "string"
534+
},
535+
{
536+
"type": "array",
537+
"items": {
538+
"type": "string"
539+
}
540+
}
541+
]
542+
}
543+
},
544+
"required": ["include"],
545+
"additionalProperties": false
546+
}
547+
]
499548
},
500549
"matrixElement": {
501550
"oneOf": [

test/schema.test.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,45 @@ const validate = (name) => {
1919
}
2020
};
2121

22-
describe("schema.json", function () {
23-
it("should validate block steps", function () {
22+
describe("schema.json", function() {
23+
it("should validate block steps", function() {
2424
validate("block.yml");
2525
});
26-
it("should validate input steps", function () {
26+
it("should validate input steps", function() {
2727
validate("input.yml");
2828
});
29-
it("should validate command steps", function () {
29+
it("should validate command steps", function() {
3030
validate("command.yml");
3131
});
32-
it("should validate env blocks", function () {
32+
it("should validate env blocks", function() {
3333
validate("env.yml");
3434
});
35-
it("should validate blocks with extra properties", function () {
35+
it("should validate blocks with extra properties", function() {
3636
validate("extra-properties.yml");
3737
});
38-
it("should validate step groups", function () {
38+
it("should validate step groups", function() {
3939
validate("group.yml");
4040
});
41-
it("should validate trigger steps", function () {
41+
it("should validate trigger steps", function() {
4242
validate("trigger.yml");
4343
});
44-
it("should validate wait steps", function () {
44+
it("should validate wait steps", function() {
4545
validate("wait.yml");
4646
});
47-
it("should validate notify", function () {
47+
it("should validate notify", function() {
4848
validate("notify.yml");
4949
});
50-
it("should validate matrix", function () {
50+
it("should validate matrix", function() {
5151
validate("matrix.yml");
5252
});
53-
it("should validate secrets", function () {
53+
it("should validate secrets", function() {
5454
validate("secrets.yml");
5555
});
56+
it("should if-changed", function() {
57+
validate("if-changed.yml");
58+
});
5659

57-
it("should verify groupStep.steps uses the same-ish items as root steps", function () {
60+
it("should verify groupStep.steps uses the same-ish items as root steps", function() {
5861
const mainList = schema.definitions.pipelineSteps.items.anyOf;
5962
const groupList = schema.definitions.groupSteps.items.anyOf;
6063
expect(mainList.slice(0, -1)).to.eql(groupList);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
steps:
2+
# Always runs
3+
- command: "always runs"
4+
5+
# Single string pattern
6+
- command: "only runs when files in foo changed"
7+
if_changed: "foo/**"
8+
9+
# Include/exclude object pattern
10+
- command: "only runs when files in foo changed, except for baz"
11+
if_changed:
12+
include: "foo/**"
13+
exclude: "foo/baz"
14+
15+
# Single string pattern for bar
16+
- command: "only runs when files in bar changed"
17+
if_changed: "bar/**"
18+
19+
# Array of patterns
20+
- command: "only runs when files in foo or bar changed"
21+
if_changed:
22+
- "foo/**"
23+
- "bar/**"
24+
25+
# Match all files
26+
- command: "only runs when any files changed"
27+
if_changed: "**"
28+
29+
# Complex include/exclude with arrays
30+
- command: "runs for api and internal, but not api/docs or internal .py files"
31+
if_changed:
32+
include:
33+
- "api/**"
34+
- "internal/**"
35+
exclude:
36+
- "api/docs/**"
37+
- "internal/**.py"
38+
39+
# Braces pattern
40+
- command: "runs for Go-related files"
41+
if_changed: "{**.go,go.{mod,sum}}"
42+
43+
# Include/exclude with single exclude pattern
44+
- command: "runs for spec/ but not spec/integration/"
45+
if_changed:
46+
include: "spec/**"
47+
exclude: "spec/integration/**"

0 commit comments

Comments
 (0)