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