1package gitlabci
2
3import (
4 "net"
5 "list"
6 "strings"
7 "struct"
8 "time"
9 "regexp"
10)
11
12#Pipeline: {
13 @jsonschema(schema="http://json-schema.org/draft-07/schema#")
14 @jsonschema(id="https://gitlab.com/.gitlab-ci.yml")
15 $schema?: net.AbsURL
16 spec?: close({inputs?: #configInputs})
17 image?: #image
18 services?: #services
19 before_script?: #before_script
20 after_script?: #after_script
21 variables?: #globalVariables
22 cache?: #cache
23 "!reference"?: #."!reference"
24 default?: close({
25 after_script?: #after_script
26 artifacts?: #artifacts
27 before_script?: #before_script
28 hooks?: #hooks
29 cache?: #cache
30 image?: #image
31 interruptible?: #interruptible
32 id_tokens?: #id_tokens
33 identity?: #identity
34 retry?: #retry
35 services?: #services
36 tags?: #tags
37 timeout?: #timeout
38 "!reference"?: #."!reference"
39 })
40 stages?: list.UniqueItems() & list.MinItems(1) & [...matchN(>=1, [string, [...string]])]
41 include?: matchN(1, [#include_item, [...#include_item]])
42 pages?: #job
43 workflow?: {
44 name?: #workflowName
45 auto_cancel?: #workflowAutoCancel
46 rules?: [...matchN(>=1, [{...}, list.MinItems(1) & [...string]]) &
47 ([...] | close({
48 if?: #if
49 changes?: #changes
50 exists?: #exists
51 variables?: #rulesVariables
52 when?: "always" | "never"
53 auto_cancel?: #workflowAutoCancel
54 }))]
55 ...
56 }
57
58 {[=~"^[.]"]: matchN(>=1, [#job_template, _])}
59 {[!~"^[.]" &
60 !~"^(\\$schema|spec|image|services|before_script|after_script|variables|cache|!reference|default|stages|include|pages|workflow)$"]: #job}
61
62 #: "!reference": [...strings.MinRunes(1)]
63
64 #after_script: #optional_script
65
66 #allow_failure: matchN(1, [
67 bool,
68 close({exit_codes!: int}), close({exit_codes!: list.MinItems(1) & list.UniqueItems() & [...int]}),
69 ])
70
71 #artifacts: null | close({
72 paths?: list.MinItems(1) & [...string]
73 exclude?: list.MinItems(1) & [...string]
74 expose_as?: string
75 name?: string
76 untracked?: bool
77 when?: "on_success" | "on_failure" | "always"
78 access?: "none" | "developer" | "maintainer" | "all"
79 expire_in?: string
80 reports?: close({
81 // Path to JSON file with accessibility report.
82 accessibility?: string
83
84 // Path to JSON file with annotations report.
85 annotations?: string
86
87 // Path for file(s) that should be parsed as JUnit XML result
88 junit?: matchN(1, [string, list.MinItems(1) & [...string]])
89
90 // Path to a single file with browser performance metric report(s).
91 browser_performance?: string
92
93 // Used to collect coverage reports from the job.
94 coverage_report?: null | {
95 // Code coverage format used by the test framework.
96 coverage_format?: "cobertura" | "jacoco"
97
98 // Path to the coverage report file that should be parsed.
99 path?: strings.MinRunes(1)
100 ...
101 }
102 codequality?: #string_file_list
103 dotenv?: #string_file_list
104 lsif?: #string_file_list
105 sast?: #string_file_list
106 dependency_scanning?: #string_file_list
107 container_scanning?: #string_file_list
108 dast?: #string_file_list
109 license_management?: #string_file_list
110 license_scanning?: #string_file_list
111 requirements?: #string_file_list
112 secret_detection?: #string_file_list
113 metrics?: #string_file_list
114 terraform?: #string_file_list
115 cyclonedx?: #string_file_list
116 sarif?: #string_file_list
117 load_performance?: #string_file_list
118 repository_xray?: #string_file_list
119 })
120 })
121
122 #baseInput: {
123 type?: "array" | "boolean" | "number" | "string"
124 description?: strings.MaxRunes(1024)
125 options?: [...bool | number | string]
126 regex?: string
127 default?: _
128 ...
129 }
130
131 #before_script: #optional_script
132
133 #cache: matchN(1, [#cache_item, [...#cache_item]])
134
135 #cache_item: {
136 key?: matchN(1, [
137 =~"^[^/]*[^./][^/]*$",
138 {
139 files?: list.MinItems(1) & list.MaxItems(2) & [...string]
140 files_commits?: list.MinItems(1) & list.MaxItems(2) & [...string]
141 prefix?: string
142 ...
143 }
144 ])
145 paths?: [...string]
146 policy?: =~"pull-push|pull|push|\\$\\w{1,255}"
147 unprotect?: bool
148 untracked?: bool
149 when?: "on_success" | "on_failure" | "always"
150 fallback_keys?: list.MaxItems(5) & [...string]
151 ...
152 }
153
154 #changes: matchN(>=1, [
155 matchN(1, [{
156 paths!: _
157 ...
158 }, {
159 regexp!: _
160 ...
161 }]) & close({
162 // List of file paths.
163 paths?: [...string]
164
165 // Ref for comparing changes.
166 compare_to?: string
167
168 // Regular expression to match against changed file paths.
169 regexp?: strings.MaxRunes(255)
170 }),
171 [...string]
172 ])
173
174 #configInputs: {
175 {
176 [=~".*"]: matchN(1, [
177 #baseInput & {
178 rules?: [...{...}]
179 ...
180 } & (matchIf({
181 type!: "string"
182 ...
183 }, {
184 default?: null | string
185 ...
186 }, _) & {...} & (matchIf({
187 type!: "number"
188 ...
189 }, {
190 default?: null | number
191 ...
192 }, _) & {...}) & (matchIf({
193 type!: "boolean"
194 ...
195 }, {
196 default?: null | bool
197 ...
198 }, _) & {...}) & (matchIf({
199 type!: "array"
200 ...
201 }, {
202 default?: null | [...]
203 ...
204 }, _) & {...}) & (matchIf(matchN(0, [null | bool | number | string | [...] | {
205 type!: _
206 ...
207 }]) & {...}, {
208 default?: null | string
209 ...
210 }, _) & {...})),
211 null
212 ])
213 }
214 ...
215 }
216
217 #exists: matchN(>=1, [
218 [...string],
219 matchN(1, [{
220 paths!: _
221 ...
222 }, {
223 regexp!: _
224 ...
225 }]) & close({
226 // List of file paths.
227 paths?: [...string]
228
229 // Path of the project to search in.
230 project?: string
231
232 // Regular expression to match against file paths in the repository.
233 regexp?: strings.MaxRunes(255)
234 }),
235 matchN(1, [{
236 paths!: _
237 ...
238 }, {
239 regexp!: _
240 ...
241 }]) & close({
242 // List of file paths.
243 paths?: [...string]
244
245 // Path of the project to search in.
246 project!: string
247
248 // Ref of the project to search in.
249 ref?: string
250
251 // Regular expression to match against file paths in the repository.
252 regexp?: strings.MaxRunes(255)
253 })
254 ])
255
256 #filter: matchN(1, [
257 null,
258 #filter_refs,
259 close({
260 refs?: #filter_refs
261
262 // Filter job based on if Kubernetes integration is active.
263 kubernetes?: "active"
264 variables?: [...string]
265
266 // Filter job creation based on files that were modified in a git push.
267 changes?: [...string]
268 })
269 ])
270
271 // Filter job by different keywords that determine origin or state, or by
272 // supplying string/regex to check against branch/tag names.
273 #filter_refs: [
274 ...matchN(>=1, [
275 matchN(1, ["branches", "tags", "api", "external", "pipelines", "pushes", "schedules", "triggers", "web"]),
276 string
277 ])
278 ]
279
280 #globalVariables: {
281 {
282 [=~".*"]: matchN(1, [
283 bool | number | string,
284 close({
285 value?: string
286 options?: list.MinItems(1) & list.UniqueItems() & [...string]
287 description?: string
288 expand?: bool
289 })
290 ])
291 }
292 ...
293 }
294
295 #hooks: close({pre_get_sources_script?: #optional_script})
296
297 #id_tokens: {
298 {[=~".*"]: close({aud!: matchN(1, [string, list.MinItems(1) & list.UniqueItems() & [...string]])})}
299 ...
300 }
301
302 #identity: "google_cloud"
303
304 #if: string
305
306 #image: matchN(1, [strings.MinRunes(
307 1,
308 ), close({
309 // Full name of the image that should be used. It should contain the Registry part if needed.
310 name!: strings.MinRunes(1)
311
312 // Command or script that should be executed as the container's entrypoint. It
313 // will be translated to Docker's --entrypoint option while creating the
314 // container. The syntax is similar to Dockerfile's ENTRYPOINT directive, where
315 // each shell token is a separate string in the array.
316 entrypoint?: list.MinItems(1)
317 docker?: close({
318 // Image architecture to pull.
319 platform?: strings.MinRunes(1)
320
321 // Username or UID to use for the container.
322 user?: strings.MinRunes(1) & strings.MaxRunes(255)
323 })
324 kubernetes?: close({
325 // Username or UID to use for the container. It also supports the UID:GID format.
326 user?: int | strings.MinRunes(1) & strings.MaxRunes(255)
327 })
328 pull_policy?: matchN(1, [
329 "always" | "never" | "if-not-present",
330 list.MinItems(1) & list.UniqueItems() & [..."always" | "never" | "if-not-present"],
331 ])
332 })])
333
334 #includeRules: null | [...matchN(>=1, [
335 close({
336 if?: #if
337 changes?: #changes
338 exists?: #exists
339 when?: matchN(1, ["never" | "always", null])
340 }), strings.MinRunes(1),
341 list.MinItems(1) & [...string]
342 ])]
343
344 #include_item: matchN(1, [
345 matchN(>=1, [=~"^https?://", matchN(0, [null | bool | number | =~"^\\w+://" | [...] | {...}]) & string]) &
346 net.URL &
347 =~"\\w\\.ya?ml$",
348 close({
349 // Relative path from local repository root (`/`) to the `yaml`/`yml` file
350 // template. The file must be on the same branch, and does not work across git
351 // submodules.
352 local!: net.URL & =~"\\.ya?ml$"
353 rules?: #includeRules
354 inputs?: #inputs
355 }), close({
356 // Path to the project, e.g. `group/project`, or `group/sub-group/project`
357 // [Learn more](https://docs.gitlab.com/ci/yaml/#includeproject).
358 project!: =~"(?:\\S/\\S|\\$\\S+)"
359
360 // Branch/Tag/Commit-hash for the target project.
361 ref?: string
362 file!: matchN(1, [=~"\\.ya?ml$", [...=~"\\.ya?ml$"]])
363 rules?: #includeRules
364 inputs?: #inputs
365 }), close({
366 // Use a `.gitlab-ci.yml` template as a base, e.g. `Nodejs.gitlab-ci.yml`.
367 template!: net.URL & =~"\\.ya?ml$"
368 rules?: #includeRules
369 inputs?: #inputs
370 }), close({
371 // Local path to component directory or full path to external component directory.
372 component!: net.URL
373 rules?: #includeRules
374 inputs?: #inputs
375 }), close({
376 // URL to a `yaml`/`yml` template file using HTTP/HTTPS.
377 remote!: net.URL & =~"^https?://.+\\.ya?ml$"
378
379 // SHA256 integrity hash of the remote file content.
380 integrity?: =~"^sha256-[A-Za-z0-9+/]{43}=$"
381 rules?: #includeRules
382 inputs?: #inputs
383 })
384 ])
385
386 #inputs: close({
387
388 {[=~"^[a-zA-Z0-9_-]+$"]: matchN(1, [
389 strings.MaxRunes(1024),
390 number,
391 bool,
392 [...matchN(1, [string, number, bool, {...}, [...null | bool | number | string | [...] | {...}]])], {...},
393 null
394 ])}})
395
396 #interruptible: bool
397
398 #job: #job_template
399
400 #jobInputs: struct.MaxFields(50) & {
401 {
402 [=~".*"]: #baseInput & {
403 default!: _
404 ...
405 } & (matchIf({
406 type!: "string"
407 ...
408 }, {
409 default?: string
410 ...
411 }, _) & {...} & (matchIf({
412 type!: "number"
413 ...
414 }, {
415 default?: number
416 ...
417 }, _) & {...}) & (matchIf({
418 type!: "boolean"
419 ...
420 }, {
421 default?: bool
422 ...
423 }, _) & {...}) & (matchIf({
424 type!: "array"
425 ...
426 }, {
427 default?: [...]
428 ...
429 }, _) & {...}) & (matchIf(matchN(0, [null | bool | number | string | [...] | {
430 type!: _
431 ...
432 }]) & {...}, {
433 default?: string
434 ...
435 }, _) & {...}))
436 }
437 ...
438 }
439
440 #jobVariables: {
441 {
442 [=~".*"]: matchN(1, [
443 bool | number | string,
444 close({
445 value?: string
446 expand?: bool
447 })
448 ])
449 }
450 ...
451 }
452
453 #job_template: matchN(1, [{
454 when!: "delayed"
455 start_in!: _
456 ...
457 }, {
458 when?: matchN(0, ["delayed"])
459 ...
460 }]) & close({
461 image?: #image
462 services?: #services
463 before_script?: #before_script
464 after_script?: #after_script
465 hooks?: #hooks
466 rules?: #rules
467 variables?: #jobVariables
468 cache?: #cache
469 id_tokens?: #id_tokens
470 identity?: #identity
471 inputs?: #jobInputs
472 secrets?: #secrets
473 script?: #script
474 run?: #steps
475
476 // Define what stage the job will run in.
477 stage?: matchN(>=1, [strings.MinRunes(1), list.MinItems(1) & [...string]])
478 only?: #filter
479
480 // The name of one or more jobs to inherit configuration from.
481 extends?: matchN(1, [string, list.MinItems(1) & [...string]])
482
483 // The list of jobs in previous stages whose sole completion is needed to start the current job.
484 needs?: [...matchN(1, [
485 string,
486 close({
487 job!: string
488 artifacts?: bool
489 optional?: bool
490 parallel?: #parallel_matrix
491 }), close({
492 pipeline!: string
493 job!: string
494 artifacts?: bool
495 parallel?: #parallel_matrix
496 }), close({
497 job!: string
498 project!: string
499 ref!: string
500 artifacts?: bool
501 parallel?: #parallel_matrix
502 }),
503 #."!reference"
504 ])]
505 except?: #filter
506 tags?: #tags
507 allow_failure?: #allow_failure
508 timeout?: #timeout
509 when?: #when
510 start_in?: #start_in
511 manual_confirmation?: string
512
513 // Specify a list of job names from earlier stages from which artifacts should
514 // be loaded. By default, all previous artifacts are passed. Use an empty array
515 // to skip downloading artifacts.
516 dependencies?: [...string]
517 artifacts?: #artifacts
518
519 // Used to associate environment metadata with a deploy. Environment can have a
520 // name and URL attached to it, and will be displayed under /environments under
521 // the project.
522 environment?: matchN(1, [
523 string,
524 close({
525 // The name of the environment, e.g. 'qa', 'staging', 'production'.
526 name!: strings.MinRunes(1)
527
528 // When set, this will expose buttons in various places for the current
529 // environment in GitLab, that will take you to the defined URL.
530 url?: net.AbsURL & =~"^(https?://.+|\\$[A-Za-z]+)"
531
532 // The name of a job to execute when the environment is about to be stopped.
533 on_stop?: string
534
535 // Specifies what this job will do. 'start' (default) indicates the job will
536 // start the deployment. 'prepare'/'verify'/'access' indicates this will not
537 // affect the deployment. 'stop' indicates this will stop the deployment.
538 action?: "start" | "prepare" | "stop" | "verify" | "access"
539
540 // The amount of time it should take before GitLab will automatically stop the
541 // environment. Supports a wide variety of formats, e.g. '1 week', '3 mins 4
542 // sec', '2 hrs 20 min', '2h20min', '6 mos 1 day', '47 yrs 6 mos and 4d', '3
543 // weeks and 2 days'.
544 auto_stop_in?: string
545
546 // Used to configure the kubernetes deployment for this environment. This is
547 // currently not supported for kubernetes clusters that are managed by GitLab.
548 kubernetes?: {
549 // Specifies the GitLab Agent for Kubernetes. The format is `path/to/agent/project:agent-name`.
550 agent?: string
551
552 // Deprecated. Use `dashboard.namespace` instead. The kubernetes namespace where
553 // this environment's dashboard should be deployed to.
554 namespace?: strings.MinRunes(1)
555
556 // Deprecated. Use `dashboard.flux_resource_path` instead. The Flux resource
557 // path to associate with this environment. This must be the full resource
558 // path. For example,
559 // 'helm.toolkit.fluxcd.io/v2/namespaces/gitlab-agent/helmreleases/gitlab-agent'.
560 flux_resource_path?: string
561
562 // Used to configure the managed resources for this environment.
563 managed_resources?: {
564 // Indicates whether the managed resources are enabled for this environment.
565 enabled?: bool
566 ...
567 }
568
569 // Used to configure the dashboard for this environment.
570 dashboard?: {
571 // The kubernetes namespace where the dashboard for this environment should be deployed to.
572 namespace?: strings.MinRunes(1)
573
574 // The Flux resource path to associate with this environment. This must be the
575 // full resource path. For example,
576 // 'helm.toolkit.fluxcd.io/v2/namespaces/gitlab-agent/helmreleases/gitlab-agent'.
577 flux_resource_path?: string
578 ...
579 }
580 ...
581 }
582
583 // Explicitly specifies the tier of the deployment environment if non-standard
584 // environment name is used.
585 deployment_tier?: string
586 })
587 ])
588
589 // Indicates that the job creates a Release.
590 release?: close({
591 // The tag_name must be specified. It can refer to an existing Git tag or can be
592 // specified by the user.
593 tag_name!: strings.MinRunes(1)
594
595 // Message to use if creating a new annotated tag.
596 tag_message?: string
597
598 // Specifies the longer description of the Release.
599 description!: strings.MinRunes(1)
600
601 // The Release name. If omitted, it is populated with the value of release: tag_name.
602 name?: string
603
604 // If the release: tag_name doesn’t exist yet, the release is created from ref.
605 // ref can be a commit SHA, another tag name, or a branch name.
606 ref?: string
607
608 // The title of each milestone the release is associated with.
609 milestones?: [...string]
610
611 // The date and time when the release is ready. Defaults to the current date and
612 // time if not defined. Should be enclosed in quotes and expressed in ISO 8601
613 // format.
614 released_at?: time.Time &
615 =~"^(?:[1-9]\\d{3}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1\\d|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[1-9]\\d(?:0[48]|[2468][048]|[13579][26])|(?:[2468][048]|[13579][26])00)-02-29)T(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:Z|[+-][01]\\d:[0-5]\\d)$"
616 assets?: close({
617 // Include asset links in the release.
618 links!: list.MinItems(1) & [...close({
619 // The name of the link.
620 name!: strings.MinRunes(1)
621
622 // The URL to download a file.
623 url!: strings.MinRunes(1)
624
625 // The redirect link to the url.
626 filepath?: string
627
628 // The content kind of what users can download via url.
629 link_type?: "runbook" | "package" | "image" | "other"
630 })]
631 })
632 })
633
634 // Must be a regular expression, optionally but recommended to be quoted, and
635 // must be surrounded with '/'. Example: '/Code coverage: \d+\.\d+/'
636 coverage?: regexp.Valid & =~"^/.+/$"
637 retry?: #retry
638 parallel?: #parallel
639 interruptible?: #interruptible
640
641 // Limit job concurrency. Can be used to ensure that the Runner will not run
642 // certain jobs simultaneously.
643 resource_group?: string
644 trigger?: matchN(1, [
645 close({
646 // Path to the project, e.g. `group/project`, or `group/sub-group/project`.
647 project!: =~"(?:\\S/\\S|\\$\\S+)"
648
649 // The branch name that a downstream pipeline will use
650 "branch"?: string
651
652 // You can mirror or depend on the pipeline status from the triggered pipeline
653 // to the source bridge job by using strategy: `depend` or `mirror`
654 strategy?: "depend" | "mirror"
655 inputs?: #inputs
656
657 // Specify what to forward to the downstream pipeline.
658 forward?: close({
659 // Variables defined in the trigger job are passed to downstream pipelines.
660 yaml_variables?: bool
661
662 // Variables added for manual pipeline runs and scheduled pipelines are passed
663 // to downstream pipelines.
664 pipeline_variables?: bool
665 })
666 branch?: _
667 if branch != _|_ {
668 project!: _
669 }
670 {}
671 }), close({
672 include?: matchN(1, [
673 net.URL & =~"\\.ya?ml$",
674 list.MaxItems(3) & [...matchN(1, [close({
675 // Relative path from local repository root (`/`) to the local YAML file to
676 // define the pipeline configuration.
677 local!: net.URL & =~"\\.ya?ml$"
678 inputs?: #inputs
679 }), close({
680 // Name of the template YAML file to use in the pipeline configuration.
681 template!: net.URL & =~"\\.ya?ml$"
682 inputs?: #inputs
683 }), close({
684 // Relative path to the generated YAML file which is extracted from the
685 // artifacts and used as the configuration for triggering the child pipeline.
686 artifact!: net.URL & =~"\\.ya?ml$"
687
688 // Job name which generates the artifact
689 job!: string
690 inputs?: #inputs
691 }), close({
692 // Path to another private project under the same GitLab instance, like
693 // `group/project` or `group/sub-group/project`.
694 project!: =~"(?:\\S/\\S|\\$\\S+)"
695
696 // Branch/Tag/Commit hash for the target project.
697 ref?: strings.MinRunes(1)
698
699 // Relative path from repository root (`/`) to the pipeline configuration YAML file.
700 file!: net.URL & =~"\\.ya?ml$"
701 inputs?: #inputs
702 }), close({
703 // Local path to component directory or full path to external component directory.
704 component!: net.URL
705 inputs?: #inputs
706 }), close({
707 // URL to a `yaml`/`yml` template file using HTTP/HTTPS.
708 remote!: net.URL & =~"^https?://.+\\.ya?ml$"
709 inputs?: #inputs
710 })])]
711 ])
712
713 // You can mirror or depend on the pipeline status from the triggered pipeline
714 // to the source bridge job by using strategy: `depend` or `mirror`
715 strategy?: "depend" | "mirror"
716
717 // Specify what to forward to the downstream pipeline.
718 forward?: close({
719 // Variables defined in the trigger job are passed to downstream pipelines.
720 yaml_variables?: bool
721
722 // Variables added for manual pipeline runs and scheduled pipelines are passed
723 // to downstream pipelines.
724 pipeline_variables?: bool
725 })
726 }),
727 =~"(?:\\S/\\S|\\$\\S+)"
728 ])
729 inherit?: close({
730 default?: matchN(1, [
731 bool,
732 [
733 ..."after_script" |
734 "artifacts" |
735 "before_script" |
736 "cache" |
737 "image" |
738 "interruptible" |
739 "retry" |
740 "services" |
741 "tags" |
742 "timeout"
743 ],
744 ])
745 variables?: matchN(1, [bool, [...string]])
746 })
747
748 // Deprecated. Use `pages.publish` instead. A path to a directory that contains
749 // the files to be published with Pages.
750 publish?: string
751 pages?: matchN(1, [
752 close({
753 path_prefix?: string
754 expire_in?: string
755 publish?: string
756 }),
757 bool
758 ])
759 })
760
761 #optional_script: matchN(1, [string, [...matchN(>=1, [string, [...string]])]])
762
763 // Splits up a single job into multiple that run in parallel. Provides
764 // `CI_NODE_INDEX` and `CI_NODE_TOTAL` environment variables to the jobs.
765 #parallel: matchN(1, [
766 int & >=1 & <=200,
767 close({
768 // Defines different variables for jobs that are running in parallel.
769 matrix!: list.MaxItems(200) & [...{[string]: number | string | [...]}]
770 })
771 ])
772
773 // Use the `needs:parallel:matrix` keyword to specify parallelized jobs needed
774 // to be completed for the job to run. [Learn
775 // More](https://docs.gitlab.com/ci/yaml/#needsparallelmatrix)
776 #parallel_matrix: close({
777 // Defines different variables for jobs that are running in parallel.
778 matrix!: list.MaxItems(200) & [...{[string]: number | string | [...]}]
779 })
780
781 #retry: matchN(1, [
782 #retry_max,
783 close({
784 max?: #retry_max
785 when?: matchN(1, [#retry_errors, [...#retry_errors]])
786 exit_codes?: matchN(1, [list.MinItems(1) & list.UniqueItems() & [...int], int])
787 })
788 ])
789
790 #retry_errors: matchN(1, [
791 "always",
792 "unknown_failure",
793 "script_failure",
794 "api_failure",
795 "stuck_or_timeout_failure",
796 "stuck_pending_with_matching_runners",
797 "stuck_pending_no_matching_runners",
798 "no_updates_running",
799 "no_updates_canceling",
800 "runner_system_failure",
801 "runner_configuration_error",
802 "runner_external_dependency_failure",
803 "runner_interrupted",
804 "runner_unsupported",
805 "stale_schedule",
806 "job_execution_timeout",
807 "server_timeout_running",
808 "server_timeout_canceling",
809 "archived_failure",
810 "unmet_prerequisites",
811 "scheduler_failure",
812 "data_integrity_failure",
813 ])
814
815 // The number of times the job will be retried if it fails. Defaults to 0 and
816 // can max be retried 2 times (3 times total).
817 #retry_max: int & >=0 & <=2
818
819 #rules: null | [...matchN(>=1, [
820 close({
821 if?: #if
822 changes?: #changes
823 exists?: #exists
824 variables?: #rulesVariables
825 when?: #when
826 start_in?: #start_in
827 allow_failure?: #allow_failure
828 needs?: #rulesNeeds
829 interruptible?: #interruptible
830 }), strings.MinRunes(1),
831 list.MinItems(1) & [...string]
832 ])]
833
834 #rulesNeeds: [...matchN(1, [
835 string,
836 close({
837 // Name of a job that is defined in the pipeline.
838 job!: strings.MinRunes(1)
839
840 // Download artifacts of the job in needs.
841 artifacts?: bool
842
843 // Whether the job needs to be present in the pipeline to run ahead of the current job.
844 optional?: bool
845 })
846 ])]
847
848 #rulesVariables: {
849 {[=~".*"]: bool | number | string}
850 ...
851 }
852
853 #script: matchN(1, [strings.MinRunes(1), list.MinItems(1) & [...matchN(>=1, [string, [...string]])]])
854
855 #secrets: {
856 {
857 [=~".*"]: matchN(>=1, [{
858 vault!: _
859 ...
860 }, {
861 azure_key_vault!: _
862 ...
863 }, {
864 gcp_secret_manager!: _
865 ...
866 }, {
867 aws_secrets_manager!: _
868 ...
869 }, {
870 gitlab_secrets_manager!: _
871 ...
872 }]) & close({
873 vault?: matchN(1, [
874 string,
875 close({
876 engine!: {
877 name!: string
878 path!: string
879 ...
880 }
881 path!: string
882 field!: string
883 })
884 ])
885 "gcp_secret_manager"?: close({
886 name!: string
887 version?: matchN(1, [string, int])
888 })
889 azure_key_vault?: close({
890 name!: string
891 version?: string
892 })
893 aws_secrets_manager?: matchN(1, [
894 string,
895 close({
896 // The ARN or name of the secret to retrieve. To retrieve a secret from another
897 // account, you must use an ARN.
898 secret_id!: string
899
900 // The unique identifier of the version of the secret to retrieve. If you
901 // include both this parameter and VersionStage, the two parameters must refer
902 // to the same secret version. If you don't specify either a VersionStage or
903 // VersionId, Secrets Manager returns the AWSCURRENT version.
904 version_id?: string
905
906 // The staging label of the version of the secret to retrieve. If you include
907 // both this parameter and VersionStage, the two parameters must refer to the
908 // same secret version. If you don't specify either a VersionStage or
909 // VersionId, Secrets Manager returns the AWSCURRENT version.
910 version_stage?: string
911
912 // The AWS region where the secret is stored. Use this to override the region
913 // for a specific secret. Defaults to AWS_REGION variable.
914 region?: string
915
916 // The ARN of the IAM role to assume before retrieving the secret. Use this to
917 // override the ARN. Defaults to AWS_ROLE_ARN variable.
918 role_arn?: string
919
920 // The name of the session to use when assuming the role. Use this to override
921 // the session name. Defaults to AWS_ROLE_SESSION_NAME variable.
922 role_session_name?: string
923
924 // The name of the field to retrieve from the secret. If not specified, the
925 // entire secret is retrieved.
926 field?: string
927 })
928 ])
929 gitlab_secrets_manager?: close({
930 // Name of the secret. Only letters, digits, and underscores are allowed.
931 name!: =~"^[a-zA-Z0-9_]+$"
932
933 // Source of the secret. Defaults to the current project if not given. For
934 // fetching a secret from a group, provide group/<full_path_of_the_group>
935 source?: string
936 })
937 file?: bool
938
939 // Specifies the JWT variable that should be used to authenticate with the secret provider.
940 token?: string
941 gcp_secret_manager?: _
942 if gcp_secret_manager != _|_ {
943 token!: _
944 }
945 {}
946 })
947 }
948 ...
949 }
950
951 #services: [...matchN(1, [strings.MinRunes(
952 1,
953 ), close({
954 // Full name of the image that should be used. It should contain the Registry part if needed.
955 name!: strings.MinRunes(1)
956 entrypoint?: list.MinItems(1) & [...string]
957 docker?: close({
958 // Image architecture to pull.
959 platform?: strings.MinRunes(1)
960
961 // Username or UID to use for the container.
962 user?: strings.MinRunes(1) & strings.MaxRunes(255)
963 })
964 kubernetes?: close({
965 // Username or UID to use for the container. It also supports the UID:GID format.
966 user?: int | strings.MinRunes(1) & strings.MaxRunes(255)
967 })
968 pull_policy?: matchN(1, [
969 "always" | "never" | "if-not-present",
970 list.MinItems(1) & list.UniqueItems() & [..."always" | "never" | "if-not-present"],
971 ])
972 command?: #script
973 alias?: strings.MinRunes(1)
974 variables?: #jobVariables
975 })])]
976
977 #start_in: strings.MinRunes(1)
978
979 // Any of these function use cases are valid.
980 #step: matchN(1, [
981 matchN(1, [
982 matchN(0, [null | bool | number | string | [...] | {
983 func!: _
984 ...
985 }]) & {
986 step!: _
987 ...
988 },
989 matchN(0, [null | bool | number | string | [...] | {
990 step!: _
991 ...
992 }]) & {
993 func!: _
994 ...
995 }
996 ]) & close({
997 name!: #stepName
998 env?: #stepNamedStrings
999 inputs?: #stepNamedValues
1000 step?: #stepFuncReference
1001 func?: #stepFuncReference
1002 }),
1003 close({
1004 name!: #stepName
1005 env?: #stepNamedStrings
1006 script!: strings.MinRunes(1)
1007 })
1008 ])
1009
1010 #stepFuncReference: matchN(1, [string, #stepGitReference, #stepOciReference])
1011
1012 // GitReference is a reference to a function in a Git repository.
1013 #stepGitReference: close({
1014 git!: close({
1015 url!: string
1016 dir?: string
1017 rev!: string
1018 file?: string
1019 })
1020 })
1021
1022 #stepName: =~"^[a-zA-Z_][a-zA-Z0-9_]*$"
1023
1024 #stepNamedStrings: close({
1025
1026 {[=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]: string}})
1027
1028 #stepNamedValues: close({
1029
1030 {[=~"^[a-zA-Z_][a-zA-Z0-9_]*$"]: _}})
1031
1032 // OCIReference is a reference to a function hosted in an OCI repository.
1033 #stepOciReference: close({
1034 oci!: close({
1035 // The <host>[:<port>] of the container registry server.
1036 registry!: string
1037
1038 // A path within the registry containing related OCI images. Typically the
1039 // namespace, project, and image name.
1040 repository!: string
1041
1042 // A pointer to the image manifest hosted in the OCI repository.
1043 tag!: string
1044
1045 // A directory inside the OCI image where the function can be found.
1046 dir?: string
1047
1048 // The name of the file that defines the function, defaults to func.yml.
1049 file?: string
1050 })
1051 })
1052
1053 #steps: [...#step]
1054
1055 #string_file_list: matchN(1, [string, [...string]])
1056
1057 #tags: list.MinItems(1) & [...matchN(>=1, [strings.MinRunes(1), list.MinItems(1) & [...string]])]
1058
1059 #timeout: strings.MinRunes(1)
1060
1061 #when: "on_success" | "on_failure" | "always" | "never" | "manual" | "delayed"
1062
1063 // Define the rules for when pipeline should be automatically cancelled.
1064 #workflowAutoCancel: close({
1065 on_job_failure?: "none" | "all"
1066 on_new_commit?: "conservative" | "interruptible" | "none"
1067 })
1068
1069 #workflowName: strings.MinRunes(1) & strings.MaxRunes(255)
1070}