GitLab CI/CD Dynamic Child Pipeline Generation Prompt
Generate `.gitlab-ci.yml` at runtime — emit child-pipeline YAML from a script based on changed paths, a matrix file, or service inventory, then trigger it with artifact-based config.
- Target user
- Platform engineers building data-driven pipelines for monorepos and large service catalogs
- Difficulty
- Advanced
- Tools
- Claude, ChatGPT
The prompt
You are a senior CI/CD engineer who builds dynamic child pipelines that generate themselves from the repo state, so adding a new service requires zero `.gitlab-ci.yml` edits.
I will provide:
- My repo layout (services/packages, languages, where build configs live)
- The decision logic I want (per-service jobs only for changed paths? full matrix on main? tags?)
- My GitLab tier and runner setup
- Any existing static `.gitlab-ci.yml`
Your job:
1. **Choose the trigger pattern** — a `generate` job that writes `generated-config.yml` as an artifact, then a `trigger` job with `trigger: include: [{ artifact: generated-config.yml, job: generate }]` and `strategy: depend`. Explain `strategy: depend` (parent waits + inherits status) vs fire-and-forget.
2. **Write the generator** — a small, readable script (Python or bash+yq) that: detects changed paths via `git diff` against `CI_MERGE_REQUEST_DIFF_BASE_SHA` (MRs) or the previous SHA (branches), maps each to a job template, and emits valid YAML. Provide the actual generator code.
3. **Keep generated YAML DRY** — emit `extends:` references to a hidden `.job_template` and pass per-service values via `variables:`, instead of duplicating full job bodies.
4. **Handle the empty case** — when nothing relevant changed, emit a single no-op `pipeline: cannot be empty` guard job (GitLab rejects empty child configs); show the pattern.
5. **Propagate context** — which variables auto-pass to children, which need explicit `variables:` forwarding, and how `CI_PIPELINE_SOURCE` differs inside a child.
6. **Make it debuggable** — echo the generated YAML to the job log, upload it as a browsable artifact, and run `gitlab-ci-lint` (or the `/ci/lint` API) on it before triggering so a malformed generation fails fast with a clear message.
7. **Failure semantics** — with `strategy: depend`, how a failing child surfaces in the parent; `allow_failure` behavior; and how to retry only the child.
Output: (a) parent `.gitlab-ci.yml` with generate + trigger jobs, (b) the generator script, (c) a generated-config example for a 2-service change, (d) the lint/validation step, (e) common failure modes and fixes.
Bias toward: validated-before-trigger, readable generated YAML, and zero edits to add a new service.