Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for GitLab CI/CD By James Joyner IV · · 10 min read

AI Prompts for GitLab CI rules: and workflow: That Actually Work

GitLab CI rules and workflow logic is where pipelines silently misbehave. Here are the AI prompts I use to get correct rules without the duplicate-pipeline bug.

  • #gitlab
  • #ci-cd
  • #ai
  • #rules
  • #prompts

If there’s one part of GitLab CI that generates more confused Slack messages than any other, it’s rules: and workflow:. “Why did this pipeline run twice?” “Why didn’t my MR pipeline trigger?” “Why is this job running on a tag when I only wanted branches?” The logic is deceptively simple per-rule but the interactions — branch pipelines vs. merge request pipelines, rule order, when defaults — are a genuine cognitive load. AI can write rules fast, but rules are also where it’s most confidently wrong, so the prompt matters enormously. Here are the prompts and patterns that actually produce correct rules.

The duplicate-pipeline trap

The single most common rules bug is the dreaded duplicate pipeline: you push to a branch that has an open merge request, and you get two pipelines — one branch pipeline, one MR pipeline. This happens when your rules allow both $CI_COMMIT_BRANCH and $CI_PIPELINE_SOURCE == "merge_request_event" to fire for the same commit.

A naive prompt produces exactly this bug. So my prompt is explicit about the outcome I want:

“Write a workflow:rules block that runs merge request pipelines for MRs, runs branch pipelines on the default branch, and never creates a duplicate pipeline when a branch has an open MR. Use $CI_OPEN_MERGE_REQUESTS to suppress the redundant branch pipeline.”

That last sentence is the unlock. The model knows the pattern when you name the mechanism:

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
    - if: '$CI_COMMIT_TAG'

The order matters: the MR rule matches first for MR events; the when: never rule kills the redundant branch pipeline when an MR is open; the remaining rules cover default-branch and tag pushes. Reorder these and the dedup breaks. The model will generate this correctly if you tell it the goal is dedup — and will silently produce the double-pipeline version if you don’t.

Always make AI explain rule order

rules evaluate top to bottom and stop at the first match. This is the property that trips everyone up, because a too-broad rule near the top shadows everything below it. My standing follow-up prompt after any rules generation is:

“For each rule, state which condition matches it and confirm evaluation stops at the first match. Then tell me what happens for these triggers: push to a feature branch, MR to main, tag push, scheduled pipeline.”

Forcing the model to trace evaluation order catches shadowing bugs. It also catches the inverse — a rule that never fires because an earlier rule always matches first. I do this trace for every non-trivial rules block, because reading rules cold and predicting behavior is exactly the kind of thing humans get wrong too.

Pro Tip: rules:changes: is evaluated against the pipeline’s diff, and that diff is computed differently for branch pipelines vs. MR pipelines. On a branch pipeline it compares to the previous commit; on an MR pipeline it compares to the target branch. A changes: rule that works great on MRs can behave bizarrely on the default branch. Always ask the AI to confirm a changes: rule against both pipeline types, and prefer running path-scoped jobs in MR pipelines where the diff is well-defined. The path-scoped pipelines guide goes deep on this.

Mind the implicit when default

A rules entry with no when defaults to when: on_success. But here’s the subtlety that bites people: if a job has a rules section and none of the rules match, the job is not added to the pipeline at all. That’s different from a job with no rules, which always runs. The model knows this but doesn’t always volunteer it, so a job that “should always run” silently disappears because its rules didn’t account for some trigger.

I prompt defensively: “If you add a rules block to a job that previously had none, include a final catch-all rule so the job’s run conditions are fully specified — I don’t want it silently dropped on an unexpected trigger.” That single instruction prevents a whole category of “where did my job go?” incidents.

workflow:rules vs. job rules — keep them straight

workflow:rules decides whether the whole pipeline gets created. Job rules decide whether an individual job is included in a pipeline that already exists. The model sometimes conflates them, putting pipeline-level logic in a job or vice versa. I keep the prompt scoped: “Generate only the workflow: block” or “generate only the rules: for the deploy job,” never both in one go. Smaller, scoped asks produce more correct rules than “do all the rules for this pipeline.”

A useful mental check I have the AI apply: “Does this condition decide whether the pipeline exists or whether this one job runs? Pipeline-existence logic goes in workflow:; per-job logic goes in the job.”

Variables in rules — quote everything

GitLab CI variable expressions in rules:if are strings, and the quoting rules are fiddly. $CI_COMMIT_BRANCH == "main" needs the literal quoted but not the variable; regex matches use =~ /pattern/. The model occasionally produces unquoted strings that lint fails on, or uses == where you wanted a regex =~. I always run the result through the pipeline editor lint, and I ask the model upfront: “Quote all literal string comparisons and use =~ with /.../ for any pattern matching.” This eliminates most of the syntax churn.

Test rules without spamming real pipelines

You don’t want to push twenty times just to test a rules change. Two cheaper paths: the pipeline editor has a “Validate” that simulates against a ref, and for the dedup behavior specifically, you can reason it through with the AI’s trace (above) plus a single test push to a branch with a real open MR. I treat the model’s predicted behavior as a hypothesis and confirm the one risky case — usually the duplicate-pipeline scenario — with a real run before merging to a protected branch.

Keep it reviewed, keep secrets out

Rules logic doesn’t touch secrets directly, but jobs gated by rules often do deploys. So the same discipline applies: the AI drafts the rules, I trace the evaluation order, I validate in the editor, and I confirm the risky trigger with a real run before merge. The model is a fast junior engineer that’s read every GitLab docs page but has never watched your pipeline misfire at 2am. That experience is what you bring. If you want a library of these rules prompts ready to paste, they’re collected in our prompts page and bundled in the CI prompt packs.

Conclusion

rules: and workflow: are where GitLab pipelines go quietly wrong, and AI will happily generate the buggy version if your prompt doesn’t name the trap. Name the dedup mechanism, force the model to trace evaluation order, add catch-all rules to avoid silently-dropped jobs, and validate changes: against both pipeline types. Do that and you get correct rules in a fraction of the time — drafted by the model, verified by you, merged with confidence. More in the GitLab CI/CD category.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.