CI configuration reference
Forge reads pipeline configuration from .gitlab-ci.yml at the root of the repository. The syntax is compatible with GitLab CI/CD, but only the subset below is supported. Configuration that uses anything else is rejected by lint with the line and column, not ignored.
The configuration is pinned to the commit that the pipeline runs on.
Pipeline structure
Section titled “Pipeline structure”| Keyword | Support |
|---|---|
stages |
Stage order. The implicit .pre and .post stages run first and last. |
default |
Defaults for image, before_script, tags and timeout. |
workflow:rules |
Decide whether a pipeline is created. |
include |
local files at the pipeline’s commit; files of other repositories in the same Orbit project (project, file, ref as a branch, tag or commit, pinned when the pipeline is created); CI/CD components with inputs. Nested up to 10 levels and 50 files. |
spec:inputs |
Typed, defaulted inputs for included files and for web runs. Unknown inputs are refused. |
extends |
Several parents, deep merge, up to 11 levels. |
!reference |
Up to 10 levels. |
| YAML anchors, aliases and merge keys | Bounded to 20,000 expanded nodes. Hidden jobs (names starting with .) work as templates. |
variables |
Plain global, job, workflow-rule and job-rule variables with $VAR references. Names such as CI_*, FORGE_*, DOCKER_* and PATH are refused. Project and schedule secrets take precedence. |
Components
Section titled “Components”Components are included with an address of this shape, and live in the same Orbit project:
include: - component: $CI_SERVER_FQDN/<repository>/<component>@<version> inputs: stage: testThe component file is templates/<name>.yml or templates/<name>/template.yml. <version> can be a tag, a branch, a commit or ~latest (the highest release tag; pre-release tags are ignored).
| Keyword | Support |
|---|---|
image |
Job or global. Also image: {name, pull_policy}, subject to the runner’s allowlist of pull policies. |
script, before_script |
Supported. |
tags |
Match runner tags. |
needs |
Job names, or {job, artifacts, optional}. optional: true drops a need on a job that rules leave out. artifacts: false stops artifacts and dotenv variables reaching the job. |
dependencies |
Selects exactly which earlier jobs’ artifacts a job receives ([] for none). |
when |
on_success, on_failure, always, manual and delayed with start_in (up to one week). |
allow_failure |
Boolean, or {exit_codes: [...]} to allow only those exit codes. |
retry |
0 to 2, or {max, when, exit_codes}. Deployment and resource-group jobs never retry automatically. |
timeout |
Up to 24 hours. Durations accept forms such as 90, 15m, 1h 30m, 1 hour 30 minutes and 2 days. |
parallel |
parallel: N and parallel: matrix, up to 50 instances. A job that needs a parallel job waits for all its instances. |
rules |
if (operators ==, !=, =~, !~ with RE2 regexes such as /.../i, null, &&, ||, parentheses), changes, exists, variables, plus when and allow_failure on a rule. |
resource_group |
A static key. Jobs of a group are serialised. |
environment |
See below. |
release |
tag_name, tag_message, name, description, ref, released_at and assets.links. |
id_tokens |
RS256 JWTs for reaching cloud providers without long-lived keys. |
trigger |
Child and multi-project pipelines, see below. |
Environments
Section titled “Environments”environment supports a name and url (http or https, up to 512 characters, no credentials; it may use $CI_ENVIRONMENT_SLUG, $CI_ENVIRONMENT_NAME and the commit variables), deployment_tier, on_stop, auto_stop_in (from one minute to one year, or never) and action (start, prepare, verify, access, stop). A dynamic name such as review/$CI_COMMIT_REF_SLUG must start with a static segment, so a branch name can never create a top-level environment such as production. Runners that offer environmentV1 set CI_ENVIRONMENT_NAME, CI_ENVIRONMENT_SLUG, CI_ENVIRONMENT_ACTION, CI_ENVIRONMENT_URL and CI_ENVIRONMENT_TIER in the job. Details: Environments and deployments.
Artifacts and cache
Section titled “Artifacts and cache”| Keyword | Support |
|---|---|
artifacts:paths, when, expire_in, name, exclude, expose_as |
Supported. name may use variables. |
artifacts:reports |
junit (globs), dotenv (up to five files, at most 20 variables and 5 KiB, reserved names refused) and coverage (a regex read from the job log). |
cache |
Up to four caches per job; key (with variables or key:files, up to two files) and prefix, paths, policy (pull, push, pull-push), when, fallback_keys, unprotect; also default:cache. Keys get a -protected or -non_protected suffix, so jobs on unprotected refs never read or replace a protected ref’s cache. |
Limits: an archive holds up to 1000 entries and 64 MiB expanded (32 MiB compressed). Project quotas default to 512 MiB and 1000 unpurged archives and are configurable. Caches are evicted above a per-repository quota (1 GiB by default) and removed when unused for 14 days by default. Symlink and device entries are rejected. Optional S3-compatible object storage can hold artifacts and caches.
Downstream pipelines
Section titled “Downstream pipelines”trigger jobs never reach a runner.
- Child pipelines:
trigger:includestarts a child from up to three included files at the parent commit, or from a file produced by an earlier job’s artifact (a dynamic child pipeline). - Multi-project pipelines:
trigger:project(a repository slug, orPROJECTKEY/slugfor another Orbit project) with an optionalbranch. strategy: dependmirrors the downstream result into the trigger job, andforward:yaml_variables(on by default) passes the trigger job’s variables.- Downstream pipelines run as the user who triggered the parent, who needs write access to the target project. Nesting stops at two levels, and a pipeline creates at most 20 downstream pipelines.
CI_PIPELINE_SOURCEisparent_pipelineorpipeline.
Triggers and schedules
Section titled “Triggers and schedules”| Trigger | Notes |
|---|---|
| Branch push, tag push, merge request | Each is opt-in per project. [skip ci] or [ci skip] in the commit message and git push -o ci.skip skip them. |
| Schedules | Branch and protected-tag targets, five-field cron with JAN-DEC and SUN-SAT names and @hourly to @yearly shortcuts, IANA time zones, typed inputs, encrypted schedule variables. |
| API and webhook triggers | Owner-scoped trigger tokens and HMAC-signed webhooks, with exact allowed refs, expiry and once-only display of the secret. |
| Web run | Manual run, with typed spec:inputs. |
Not supported
Section titled “Not supported”Forge rejects these, so a copied GitLab file fails lint rather than behaving differently:
after_scriptservices(service containers) andimage:entrypoint- remote includes and GitLab template includes
- includes or components from other Orbit projects (multi-project triggers may cross projects)
needs:pipeline,needs:projectandrules:needsinterruptibleand automatic cancellation of redundant pipelinescache:untrackedsecrets:(useid_tokensto reach external secret providers)trigger:include:inputsandforward:pipeline_variablesci.variableandci.inputpush options (rejected)
Other differences: log output is not streamed live (the job log refreshes while the pipeline page polls), and only JUnit, dotenv and coverage reports are collected, besides the security reports.