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}