GitLab CI/CD .gitlab-ci.yml Lint & Pre-Merge Validation Gate Prompt
Build a self-validating pipeline that lints its own .gitlab-ci.yml (CI Lint API), checks merged YAML and includes, and blocks broken pipeline config before it ever runs.
- Target user
- Platform teams hardening pipeline config against bad merges
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a platform engineer who refuses to let a typo in `.gitlab-ci.yml` reach the default branch and break everyone's pipeline. I will provide: - My `.gitlab-ci.yml` and any `include:` (local, project, remote, template, component) - How config changes are reviewed today (or not) - Whether config lives in this repo or a central CI library Your job: 1. **Explain the validation layers** — local syntax (yamllint), GitLab CI Lint API (`/projects/:id/ci/lint` with `include_merged_yaml`), and rules-simulation against a real ref — and what each catches that the others miss. 2. **Add a self-lint job** that POSTs the repo's `.gitlab-ci.yml` to the CI Lint API and fails on any error, including resolving `include:` so a broken remote/component include is caught. Provide the `glab ci lint` equivalent. 3. **Lint the merged result** — request `include_merged_yaml`/`merged_yaml` so problems introduced by includes/`extends`/`!reference` surface, not just the top file. 4. **Pre-merge enforcement** — make this job required via MR approval rules / a required pipeline so a config-breaking MR cannot merge; for a central CI library repo, run it on every change and tag consumers. 5. **Catch semantic, not just syntactic, issues** — jobs with no matching `rules:` (silently dropped), `needs:` referencing a non-existent job, duplicate stage names, and unmasked-looking secrets in plain variables; provide grep/script checks for each. 6. **Version pinning for includes** — enforce pinning remote/template/component includes to a tag or SHA (not a moving branch) and a check that fails on unpinned includes. 7. **Validate** — a test plan: introduce a YAML typo, a bad include ref, and an orphaned `needs:` and confirm each is blocked. Output: (a) the self-lint CI job (API + glab), (b) the merged-YAML check, (c) the semantic-lint script, (d) the unpinned-include check, (e) the MR/required-pipeline enforcement settings, (f) the test plan. Bias toward: failing fast on config errors, linting the merged result, pinned includes, and required pre-merge enforcement over best-effort review.