1package buildkite
2
3import (
4 "strings"
5 "struct"
6 "regexp"
7)
8
9// JSON schema for Buildkite pipeline configuration files
10#Pipeline: {
11 @jsonschema(schema="http://json-schema.org/draft-07/schema#")
12 "env"?: #env
13 "agents"?: #agents
14 "notify"?: #buildNotify
15 "image"?: #image
16 "secrets"?: #secrets
17 "priority"?: #priority
18 "steps"!: #pipelineSteps
19 ...
20
21 #agents: matchN(1, [#agentsObject, #agentsList])
22
23 // Query rules to target specific agents in k=v format
24 #agentsList: [...string]
25
26 // Query rules to target specific agents
27 #agentsObject: {
28 ...
29 }
30
31 // Whether to proceed with this step and further steps if a step
32 // named in the depends_on attribute fails
33 #allowDependencyFailure: true | false | "true" | "false"
34
35 // A list of teams that are permitted to unblock this step, whose
36 // values are a list of one or more team slugs or IDs
37 #allowedTeams: matchN(>=1, [string, [...string]])
38
39 #automaticRetry: close({
40 // The exit status number that will cause this job to retry
41 "exit_status"?: matchN(>=1, ["*", int, [...int]])
42
43 // The number of times this job can be retried
44 "limit"?: int & >=0 & <=10
45
46 // The exit signal, if any, that may be retried
47 "signal"?: string
48
49 // The exit signal reason, if any, that may be retried
50 "signal_reason"?: "*" | "none" | "agent_incompatible" | "agent_refused" | "agent_stop" | "cancel" | "process_run_error" | "signature_rejected" | "stack_error"
51 })
52
53 #automaticRetryList: [...#automaticRetry]
54
55 #blockStep: close({
56 "allow_dependency_failure"?: #allowDependencyFailure
57
58 // The label of the block step
59 "block"?: _#defs."/definitions/blockStep/properties/block"
60
61 // The state that the build is set to when the build is blocked by
62 // this block step
63 "blocked_state"?: "passed" | "failed" | "running"
64 "branches"?: #branches
65 "depends_on"?: #dependsOn
66 "fields"?: #fields
67 "if"?: #if
68 "key"?: _#defs."/definitions/blockStep/properties/key"
69 "identifier"?: _#defs."/definitions/blockStep/properties/key"
70 "id"?: _#defs."/definitions/blockStep/properties/key"
71 "label"?: _#defs."/definitions/blockStep/properties/block"
72 "name"?: _#defs."/definitions/blockStep/properties/block"
73 "prompt"?: #prompt
74 "allowed_teams"?: #allowedTeams
75 "type"?: "block"
76 })
77
78 // Which branches will include this step in their builds
79 #branches: matchN(>=1, [string, [...string]])
80
81 // Array of notification options for this step
82 #buildNotify: [...matchN(1, [#notifySimple, #notifyEmail, #notifyBasecamp, #notifySlack, #notifyWebhook, #notifyPagerduty, #notifyGithubCommitStatus, #notifyGithubCheck])]
83
84 // The paths for the caches to be used in the step
85 #cache: matchN(>=1, [string, [...string], {
86 "paths"!: [...string]
87 "size"?: =~"^\\d+g$"
88 "name"?: string
89 ...
90 }])
91
92 // Whether to cancel the job as soon as the build is marked as
93 // failing
94 #cancelOnBuildFailing: true | false | "true" | "false"
95
96 #commandStep: close({
97 "agents"?: #agents
98 "allow_dependency_failure"?: #allowDependencyFailure
99
100 // The glob path/s of artifacts to upload once this step has
101 // finished running
102 "artifact_paths"?: matchN(>=1, [string, [...string]])
103 "branches"?: #branches
104 "cache"?: #cache
105 "cancel_on_build_failing"?: #cancelOnBuildFailing
106 "command"?: #commandStepCommand
107 "commands"?: #commandStepCommand
108
109 // The maximum number of jobs created from this step that are
110 // allowed to run at the same time. If you use this attribute,
111 // you must also define concurrency_group.
112 "concurrency"?: int
113
114 // A unique name for the concurrency group that you are creating
115 // with the concurrency attribute
116 "concurrency_group"?: string
117
118 // Control command order, allowed values are 'ordered' (default)
119 // and 'eager'. If you use this attribute, you must also define
120 // concurrency_group and concurrency.
121 "concurrency_method"?: "ordered" | "eager"
122 "depends_on"?: #dependsOn
123 "env"?: #env
124 "if"?: #if
125 "if_changed"?: #ifChanged
126 "key"?: _#defs."/definitions/commandStep/properties/key"
127 "identifier"?: _#defs."/definitions/commandStep/properties/key"
128 "id"?: _#defs."/definitions/commandStep/properties/key"
129 "image"?: #image
130 "label"?: _#defs."/definitions/commandStep/properties/label"
131
132 // The signature of the command step, generally injected by agents
133 // at pipeline upload
134 "signature"?: {
135 // The algorithm used to generate the signature
136 "algorithm"?: string
137
138 // The signature value, a JWS compact signature with a detached
139 // body
140 "value"?: string
141
142 // The fields that were signed to form the signature value
143 "signed_fields"?: [...string]
144 ...
145 }
146 "matrix"?: #matrix
147 "name"?: _#defs."/definitions/commandStep/properties/label"
148 "notify"?: #commandStepNotify
149
150 // The number of parallel jobs that will be created based on this
151 // step
152 "parallelism"?: int
153 "plugins"?: #plugins
154 "soft_fail"?: #softFail
155
156 // The conditions for retrying this step.
157 "retry"?: close({
158 "automatic"?: #commandStepAutomaticRetry
159 "manual"?: #commandStepManualRetry
160 })
161 "skip"?: #skip
162
163 // The number of minutes to time out a job
164 "timeout_in_minutes"?: int & >=1
165 "type"?: "script" | "command" | "commands"
166 "priority"?: #priority
167 "secrets"?: #secrets
168 })
169
170 // Whether to allow a job to retry automatically. If set to true,
171 // the retry conditions are set to the default value.
172 #commandStepAutomaticRetry: matchN(>=1, [true | false | "true" | "false", #automaticRetry, #automaticRetryList])
173
174 // The commands to run on the agent
175 #commandStepCommand: matchN(>=1, [[...string], string])
176
177 // Whether to allow a job to be retried manually
178 #commandStepManualRetry: matchN(>=1, [true | false | "true" | "false", #commandStepManualRetryObject])
179
180 #commandStepManualRetryObject: close({
181 // Whether or not this job can be retried manually
182 "allowed"?: true | false | "true" | "false"
183
184 // Whether or not this job can be retried after it has passed
185 "permit_on_passed"?: true | false | "true" | "false"
186
187 // A string that will be displayed in a tooltip on the Retry
188 // button in Buildkite. This will only be displayed if the
189 // allowed attribute is set to false.
190 "reason"?: string
191 })
192
193 // Array of notification options for this step
194 #commandStepNotify: [...matchN(1, [#notifySimple, #notifyBasecamp, #notifySlack, #notifyGithubCommitStatus, #notifyGithubCheck])]
195
196 // The step keys for a step to depend on
197 #dependsOn: matchN(>=1, [null, string, #dependsOnList])
198
199 #dependsOnList: [...matchN(>=1, [string, close({
200 "step"?: string
201 "allow_failure"?: true | false | "true" | "false"
202 })])]
203
204 // Environment variables for this step
205 #env: {
206 ...
207 }
208
209 // A list of input fields required to be filled out before
210 // unblocking the step
211 #fields: [...matchN(1, [#textField, #selectField])]
212
213 #groupStep: close({
214 "depends_on"?: #dependsOn
215
216 // The name to give to this group of steps
217 "group"!: _#defs."/definitions/groupStep/properties/group"
218 "if"?: #if
219 "if_changed"?: #ifChanged
220 "key"?: _#defs."/definitions/groupStep/properties/key"
221 "identifier"?: _#defs."/definitions/groupStep/properties/key"
222 "id"?: _#defs."/definitions/groupStep/properties/key"
223 "label"?: _#defs."/definitions/groupStep/properties/group"
224 "name"?: _#defs."/definitions/groupStep/properties/group"
225 "allow_dependency_failure"?: #allowDependencyFailure
226 "notify"?: #buildNotify
227 "skip"?: #skip
228 "steps"!: #groupSteps
229 })
230
231 // A list of steps
232 #groupSteps: [...matchN(>=1, [#blockStep, #nestedBlockStep, #stringBlockStep, #inputStep, #nestedInputStep, #stringInputStep, #commandStep, #nestedCommandStep, #waitStep, #nestedWaitStep, #stringWaitStep, #triggerStep, #nestedTriggerStep])] & [_, ...]
233
234 // A boolean expression that omits the step when false
235 #if: string
236
237 // Agent-applied attribute: A glob pattern that omits the step
238 // from a build if it does not match any files changed in the
239 // build. Can be a single pattern, list of patterns, or an object
240 // with include/exclude attributes.
241 #ifChanged: matchN(1, [string, [...string], close({
242 // Pattern or list of patterns to include
243 "include"!: matchN(1, [string, [...string]])
244
245 // Pattern or list of patterns to exclude
246 "exclude"?: matchN(1, [string, [...string]])
247 })])
248
249 // (Kubernetes stack only) The container image to use for this
250 // pipeline or step
251 #image: string
252
253 #inputStep: close({
254 "allow_dependency_failure"?: #allowDependencyFailure
255
256 // The label of the input step
257 "input"?: _#defs."/definitions/inputStep/properties/input"
258 "branches"?: #branches
259 "depends_on"?: #dependsOn
260 "fields"?: #fields
261
262 // The state that the build is set to when the build is blocked by
263 // this input step
264 "blocked_state"?: "passed" | "failed" | "running"
265 "if"?: #if
266 "key"?: _#defs."/definitions/inputStep/properties/key"
267 "identifier"?: _#defs."/definitions/inputStep/properties/key"
268 "id"?: _#defs."/definitions/inputStep/properties/key"
269 "label"?: _#defs."/definitions/inputStep/properties/input"
270 "name"?: _#defs."/definitions/inputStep/properties/input"
271 "prompt"?: #prompt
272 "allowed_teams"?: #allowedTeams
273 "type"?: "input"
274 })
275
276 // A unique identifier for a step, must not resemble a UUID
277 #key: matchN(0, [null | bool | number | =~"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" | [...] | {
278 ...
279 }]) & (strings.MaxRunes(100) & =~"^[a-zA-Z0-9_\\-:${}.,]+$")
280
281 // The label that will be displayed in the pipeline visualisation
282 // in Buildkite. Supports emoji.
283 #label: string
284
285 #matrix: matchN(1, [#matrixElementList, #matrixObject])
286
287 // An adjustment to a Build Matrix
288 #matrixAdjustments: {
289 "with"!: matchN(1, [#matrixElementList, #matrixAdjustmentsWithObject])
290 "skip"?: #skip
291 "soft_fail"?: #softFail
292 ...
293 }
294
295 // Specification of a new or existing Build Matrix combination
296 #matrixAdjustmentsWithObject: {
297 [string]: _
298 } & {
299 [string]: string
300 }
301
302 #matrixElement: matchN(1, [string, int, bool])
303
304 // List of elements for single-dimension Build Matrix
305 #matrixElementList: [...#matrixElement]
306
307 // Configuration for multi-dimension Build Matrix
308 #matrixObject: {
309 "setup"!: #matrixSetup
310
311 // List of Build Matrix adjustments
312 "adjustments"?: [...#matrixAdjustments]
313 ...
314 }
315
316 #matrixSetup: matchN(1, [#matrixElementList, {
317 [=~"^[a-zA-Z0-9_]+$"]: _
318 } & {
319 [string]: [...#matrixElement]
320 }])
321
322 #nestedBlockStep: close({
323 "block"?: #blockStep
324 })
325
326 #nestedCommandStep: close({
327 "command"?: #commandStep
328 "commands"?: #commandStep
329 "script"?: #commandStep
330 })
331
332 #nestedInputStep: close({
333 "input"?: #inputStep
334 })
335
336 #nestedTriggerStep: close({
337 "trigger"?: #triggerStep
338 })
339
340 #nestedWaitStep: close({
341 "wait"?: #waitStep
342 "waiter"?: #waitStep
343 })
344
345 #notifyBasecamp: close({
346 "basecamp_campfire"?: string
347 "if"?: #if
348 })
349
350 #notifyEmail: close({
351 "email"?: string
352 "if"?: #if
353 })
354
355 #notifyGithubCheck: close({
356 "github_check"?: {
357 ...
358 }
359 })
360
361 #notifyGithubCommitStatus: close({
362 "github_commit_status"?: close({
363 // GitHub commit status name
364 "context"?: string
365 })
366 "if"?: #if
367 })
368
369 #notifyPagerduty: close({
370 "pagerduty_change_event"?: string
371 "if"?: #if
372 })
373
374 #notifySimple: "github_check" | "github_commit_status"
375
376 #notifySlack: close({
377 "slack"?: matchN(1, [string, #notifySlackObject])
378 "if"?: #if
379 })
380
381 #notifySlackObject: {
382 "channels"?: [...string]
383 "message"?: string
384 ...
385 }
386
387 #notifyWebhook: close({
388 "webhook"?: string
389 "if"?: #if
390 })
391
392 // A list of steps
393 #pipelineSteps: [...matchN(>=1, [#blockStep, #nestedBlockStep, #stringBlockStep, #inputStep, #nestedInputStep, #stringInputStep, #commandStep, #nestedCommandStep, #waitStep, #nestedWaitStep, #stringWaitStep, #triggerStep, #nestedTriggerStep, #groupStep])]
394
395 #plugins: matchN(>=1, [#pluginsList, #pluginsObject])
396
397 // Array of plugins for this step
398 #pluginsList: [...matchN(1, [string, struct.MaxFields(1)])]
399
400 // A map of plugins for this step. Deprecated: please use the
401 // array syntax.
402 #pluginsObject: {
403 ...
404 }
405
406 // Priority of all jobs in the pipeline, higher priorities are
407 // assigned to agents. When set pipeline-wide, it applies to all
408 // steps that do not have their own priority key set.
409 #priority: int
410
411 // The instructional message displayed in the dialog box when the
412 // unblock step is activated
413 #prompt: string
414
415 // A list of secret names or a mapping of environment variable
416 // names to secret names to be made available to the build or
417 // step
418 #secrets: matchN(>=1, [[...string], {
419 [string]: string
420 }])
421
422 #selectField: close({
423 // The text input name
424 "select"?: string
425
426 // The meta-data key that stores the field's input
427 "key"!: =~"^[a-zA-Z0-9-_]+$"
428
429 // The value of the option(s) that will be pre-selected in the
430 // dropdown
431 "default"?: matchN(1, [string, [...string]])
432
433 // The explanatory text that is shown after the label
434 "hint"?: string
435
436 // Whether more than one option may be selected
437 "multiple"?: true | false | "true" | "false"
438 "options"!: [_, ...] & [...#selectFieldOption]
439
440 // Whether the field is required for form submission
441 "required"?: true | false | "true" | "false"
442 })
443
444 #selectFieldOption: close({
445 // The text displayed on the select list item
446 "label"!: string
447
448 // The value to be stored as meta-data
449 "value"!: string
450
451 // The text displayed directly under the select field’s label
452 "hint"?: string
453
454 // Whether the field is required for form submission
455 "required"?: true | false | "true" | "false"
456 })
457
458 // Whether this step should be skipped. Passing a string provides
459 // a reason for skipping this command
460 #skip: matchN(>=1, [bool, strings.MaxRunes(70)])
461
462 // The conditions for marking the step as a soft-fail.
463 #softFail: matchN(>=1, [true | false | "true" | "false", #softFailList])
464
465 #softFailList: [...#softFailObject]
466
467 #softFailObject: {
468 // The exit status number that will cause this job to soft-fail
469 "exit_status"?: matchN(>=1, ["*", int])
470 ...
471 }
472
473 // Pauses the execution of a build and waits on a user to unblock
474 // it
475 #stringBlockStep: "block"
476
477 // Pauses the execution of a build and waits on a user to unblock
478 // it
479 #stringInputStep: "input"
480
481 // Waits for previous steps to pass before continuing
482 #stringWaitStep: "wait" | "waiter"
483
484 #textField: close({
485 // The text input name
486 "text"?: string
487
488 // The meta-data key that stores the field's input
489 "key"!: =~"^[a-zA-Z0-9-_]+$"
490
491 // The explanatory text that is shown after the label
492 "hint"?: string
493
494 // The format must be a regular expression implicitly anchored to
495 // the beginning and end of the input and is functionally
496 // equivalent to the HTML5 pattern attribute.
497 "format"?: regexp.Valid
498
499 // Whether the field is required for form submission
500 "required"?: true | false | "true" | "false"
501
502 // The value that is pre-filled in the text field
503 "default"?: string
504 })
505
506 #triggerStep: close({
507 "allow_dependency_failure"?: #allowDependencyFailure
508
509 // Whether to continue the build without waiting for the triggered
510 // step to complete
511 "async"?: true | false | "true" | "false"
512 "branches"?: #branches
513
514 // Properties of the build that will be created when the step is
515 // triggered
516 "build"?: close({
517 // The branch for the build
518 "branch"?: string
519
520 // The commit hash for the build
521 "commit"?: string
522 "env"?: #env
523
524 // The message for the build (supports emoji)
525 "message"?: string
526
527 // Meta-data for the build
528 "meta_data"?: {
529 ...
530 }
531 })
532 "depends_on"?: #dependsOn
533 "if"?: #if
534 "if_changed"?: #ifChanged
535 "key"?: _#defs."/definitions/triggerStep/properties/key"
536 "identifier"?: _#defs."/definitions/triggerStep/properties/key"
537 "id"?: _#defs."/definitions/triggerStep/properties/key"
538 "label"?: _#defs."/definitions/triggerStep/properties/label"
539 "name"?: _#defs."/definitions/triggerStep/properties/label"
540 "type"?: "trigger"
541
542 // The slug of the pipeline to create a build
543 "trigger"!: string
544 "skip"?: #skip
545 "soft_fail"?: #softFail
546 })
547
548 #waitStep: close({
549 "allow_dependency_failure"?: #allowDependencyFailure
550 "branches"?: #branches
551
552 // Continue to the next steps, even if the previous group of steps
553 // fail
554 "continue_on_failure"?: true | false | "true" | "false"
555 "depends_on"?: #dependsOn
556 "if"?: #if
557 "key"?: _#defs."/definitions/waitStep/properties/key"
558 "label"?: _#defs."/definitions/waitStep/properties/wait"
559 "name"?: _#defs."/definitions/waitStep/properties/wait"
560 "identifier"?: _#defs."/definitions/waitStep/properties/key"
561 "id"?: _#defs."/definitions/waitStep/properties/key"
562 "type"?: "wait" | "waiter"
563
564 // Waits for previous steps to pass before continuing
565 "wait"?: _#defs."/definitions/waitStep/properties/wait"
566 })
567
568 // The label of the block step
569 _#defs: "/definitions/blockStep/properties/block": string
570
571 _#defs: "/definitions/blockStep/properties/key": #key
572
573 _#defs: "/definitions/commandStep/properties/key": #key
574
575 _#defs: "/definitions/commandStep/properties/label": #label
576
577 // The name to give to this group of steps
578 _#defs: "/definitions/groupStep/properties/group": null | string
579
580 _#defs: "/definitions/groupStep/properties/key": #key
581
582 // The label of the input step
583 _#defs: "/definitions/inputStep/properties/input": string
584
585 _#defs: "/definitions/inputStep/properties/key": #key
586
587 _#defs: "/definitions/triggerStep/properties/key": #key
588
589 _#defs: "/definitions/triggerStep/properties/label": #label
590
591 _#defs: "/definitions/waitStep/properties/key": #key
592
593 // Waits for previous steps to pass before continuing
594 _#defs: "/definitions/waitStep/properties/wait": null | string
595}