Serialization
The GitLab lexicon serializes resources into .gitlab-ci.yml YAML. Keys are
converted to snake_case and jobs use kebab-case names. Stages are collected
from the job definitions, after any a Pipeline lists.
Building
Section titled “Building”Run chant build to produce a .gitlab-ci.yml from your declarations:
chant build# Writes dist/.gitlab-ci.ymlThe generated file includes:
- a header comment,
include:andvariables:, if aPipelineresource is exported stages:list: aPipeline’sstagesin its order, then every other stage a job’sstagenames, in first usedefault:section — if aDefaultresource is exportedworkflow:section — if aWorkflowresource is exported- Job definitions with
snake_casekeys andkebab-casejob names
Key conversions
Section titled “Key conversions”| Chant (TypeScript) | YAML output | Rule |
|---|---|---|
export const buildApp = new Job({...}) | build-app: | Export name → kebab-case job key |
expire_in: "1 week" | expire_in: 1 week | Property names use spec-native snake_case |
new Image({ name: "node:20" }) | image: node:20 | Single-property objects are collapsed |
Top-level keys and comments
Section titled “Top-level keys and comments”A Pipeline resource holds the top-level keys that are not a job, default or workflow: include, stages and variables. Its stages can name a stage no declared job uses, such as one an included file’s jobs run in, and set the order; a stage a job names that the list leaves out is still added after it, so the file stays valid. variables holds pipeline-wide variables, which Default cannot, since GitLab’s default: has none.
Pipeline and Job also take a comment, written as # lines: the pipeline’s at the top of the file, a job’s above its key.
export const pipeline = new Pipeline({ comment: "Protect the writer's variables and scope them to their environment.", include: [{ local: ".gitlab/watch.yml" }], stages: ["review", "apply", "ops"], variables: { GIT_DEPTH: "0" },});
export const lint = new Job({ comment: "Blocks the merge.", stage: "review", image: "node:22", script: ["npm run lint"] });# Protect the writer's variables and scope them to their environment.
include: - local: .gitlab/watch.yml
stages: - review - apply - ops
variables: GIT_DEPTH: '0'
# Blocks the merge.lint: stage: review image: node:22 script: - npm run lintValidating locally
Section titled “Validating locally”The output is standard GitLab CI YAML. Validate with the GitLab CI Lint API or locally:
# Using the GitLab APIcurl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \ --data-urlencode "content=$(cat dist/.gitlab-ci.yml)" \ "https://gitlab.com/api/v4/ci/lint"
# Using the glab CLIglab ci lint dist/.gitlab-ci.ymlCompatibility
Section titled “Compatibility”The output is compatible with:
- GitLab CI/CD (any recent GitLab version)
- GitLab CI Lint API
glabCLI tool- Any tool that processes
.gitlab-ci.ymlfiles