GitLab CI Generator / Validator
Build a .gitlab-ci.yml from stages, jobs and rules — or paste yours and validate it against the GitLab CI schema.
Commit the file at the repository root: git add .gitlab-ci.yml
Findings appear here as you paste.
Schema-only and local: include:, !reference and instance variables are not expanded here — GitLab's own CI Lint on your instance does that.
Press ? for shortcuts
Do it offline:$ git add .gitlab-ci.yml
How to use it
- Pick a tab: Build assembles a .gitlab-ci.yml from a form; Validate checks a pasted one.
- In Build, declare your stages, then give each job a name, a stage, script lines and a rules preset — every preset writes a commented rules: block.
- Read the YAML card as you type; reserved keywords, undeclared stages and empty scripts are refused with the exact reason.
- In Validate, paste the file: schema findings, undeclared stages and credential-shaped variables are listed with line numbers — select one to jump to it.
- Copy or download the file and commit it at the repository root on your default branch.
GitLab runs whatever the branch's .gitlab-ci.yml says, so a typo becomes a failed pipeline only after a push. Build the file here from stages, jobs and cited rules presets, or paste an existing one and check it against the vendored GitLab CI schema plus a stage-name sweep. Everything — parsing, validation, the generated YAML — happens in your browser; nothing you type is uploaded.
Examples
stages: build, test — build-job and test-job, run in every pipelinestages:
- build
- test
build-job:
stage: build
script:
- npm run build
rules:
# Run in every pipeline once earlier stages succeed (the rules default).
- when: on_success
test-job:
stage: test
script:
- npm test
rules:
# Run in every pipeline once earlier stages succeed (the rules default).
- when: on_success
The always preset writes the documented rules default — when: on_success — explicitly, with its meaning in a comment, so the generated file says what it does instead of relying on implicit behavior. Every stage a job names is checked against the stages: list before a single byte is emitted.
stages:
- build
- test
deploy-job:
stage: deploy
script:
- ./deploy.sh
line 5 GL_STAGE_UNDECLARED `deploy` is not one of the declared stages (build, test) — job `deploy-job`. /deploy-job/stageA JSON Schema cannot cross-reference one part of a document from another, so a job pointing at a stage that stages: never declared passes schema validation everywhere. The stage sweep catches it and anchors the finding to the stage: line itself.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
include: and !reference are not expanded
This validator checks one file against the schema. include: pulls other files at pipeline-creation time and !reference copies configuration across jobs — resolving either needs a GitLab instance, which is exactly what the official CI Lint API does with your project's context.
Ten top-level keywords can never be job names
stages, default, include, workflow, variables, image, services, cache, before_script and after_script are configuration, not jobs — the builder refuses them as names, citing the YAML syntax reference, before the file is generated.
A job with no stage runs in test
When a job omits stage:, GitLab assigns it to test — so the stage sweep checks stageless jobs too, and flags them when test itself is not in your declared list.
Manual rules jobs block by default
Under rules:, when: manual keeps allow_failure at false, so the pipeline waits for the click. Add allow_failure: true yourself when the manual job is optional — the preset deliberately emits only the documented rule.
Common errors
`stages` is a reserved GitLab CI/CD keyword and cannot be used as a job name.- A top-level key either configures the pipeline or defines a job — never both. The ten reserved keywords are refused as names so the generated file cannot silently redefine its own configuration.
Job `deploy-job` uses stage `deploy`, which is not in stages (build, test).- GitLab rejects a pipeline whose job names a stage the stages: list does not declare. The message prints your declared list so the fix is one glance away: add the stage or repoint the job.
Job `build-job` has an empty script — add at least one command.- A job with no commands does nothing and fails on GitLab. The builder refuses to emit it rather than generating a file that looks finished but cannot run.
Variable `DEPLOY_KEY` looks credential-shaped — store it as a masked CI/CD variable in GitLab instead of committing the value.- variables: values are committed plaintext. When one matches a credential shape — a key id, a JWT, a PEM header — the sweep points at it; GitLab's masked CI/CD variables keep the value out of the repository entirely.
This file is longer than the 1,048,576-character (1 MiB) limit for this tool. A .gitlab-ci.yml is normally a few hundred lines — for anything this size, run GitLab's own CI Lint on your instance.- Oversized input is refused whole instead of being truncated into some other document. The limit is printed exactly, and the honest alternative for megabyte configurations is named.
FAQ
How is this different from GitLab's CI Lint?
CI Lint is an API on your GitLab instance: it expands include: and !reference, knows your project's variables, and validates with server-side context. This page is schema-only and local — it checks structure against a vendored copy of GitLab's own editor schema, plus stage and secret sweeps, and never claims the two verdicts are equivalent. Use it for fast private iteration; use CI Lint for the authoritative answer.
What is the difference between rules and only/except?
rules is the current mechanism for deciding when a job runs, and it is what every preset here emits; only/except is the older pair, documented by GitLab as no longer actively developed. One job cannot mix the two systems — pick rules for new files and migrate old jobs one at a time.
Where does the .gitlab-ci.yml file live?
At the repository root, named exactly .gitlab-ci.yml, on the branch being built — each branch's pipeline reads that branch's copy. A project setting can move the path, but the root is the default every runner and tutorial assumes: git add .gitlab-ci.yml.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Rebuild the file or re-validate the paste immediately.
- ⌘/Ctrl + S
- Download the generated file as .gitlab-ci.yml.
- ⌘/Ctrl + C
- With no text selected, copy the YAML or the findings report.
- ⌘/Ctrl + Shift + C
- Copy the YAML or report even with text selected.
- /
- Focus the first field of the active tab.
- t
- Cycle the theme (ignored while an input has focus).
- ? or ⌘/Ctrl + /
- Show the shortcut overlay.
- Esc
- Dismiss the topmost dialog.