Chapter 08Lesson 05~195 minutes

Checkpoint Lab — workflow:rules, Job rules, if Expressions, changes, exists, Pipeline Sources, and Conditional Execution

The checkpoint asks you to design one compact rule set for branch, merge-request, and scheduled pipelines, prove which pipelines and jobs exist in each context, deliberately introduce a duplicate-pipeline bug, preserve the evidence, and repair the rule boundary without weakening unrelated execution paths.

Checkpoint labBranch/MR/ScheduleEvidence packetRepairVerification

Learning objectives

  • Design branch, merge-request, and scheduled behavior before writing YAML and record expected pipeline/job state.
  • Trigger or faithfully simulate each context and verify source/ref/SHA, workflow decision, and job presence independently.
  • Introduce and diagnose a deliberate duplicate-pipeline bug while preserving both pipeline IDs and job graphs.
  • Repair the bug with an explicit workflow boundary and verify that intended manual/API-like or triggered contexts are not accidentally blocked.
  • Produce a compact evidence packet and bridge conditional execution into Chapter 09 DAG/stage/needs design.

1. Checkpoint scenario and success criteria

Your disposable repository has three intended pipeline classes:

  • Feature branch without an open MR: lightweight branch verification.
  • Merge request: MR verification with service-specific diff filtering.
  • Nightly schedule: dependency audit regardless of ordinary source-code diff.

You must first implement a non-duplicating policy, then intentionally break the workflow to create branch+MR duplicates for one SHA, preserve the evidence, repair the defect, and verify that schedule behavior still works. No production deployments, real secrets, runner registration, cloud resources, packages, or policy/admin settings are involved.

2. Assumptions and preflight

  • GitLab primary docs checked 2026-09-11; core rules used here are Free-compatible.
  • Disposable branch: glci/ch08-checkpoint.
  • Synthetic paths: services/api/app.txt, services/web/app.txt, deps.lock.
  • A project schedule is optional if your role/project permits it. Otherwise simulate schedule rule evaluation with CI Lint/prediction worksheet and mark runtime as not observed.
  • Runner is optional for rule-state completion; if available, use a normal non-privileged runner and record Runner version/executor from safe job metadata.
  • Do not supply real pipeline variables or API/trigger tokens.

3. Write predictions before the YAML

Context Pipeline creation Expected jobs State prediction
Feature push, no MR Create push pipeline context, branch_smoke No MR job; no scheduled audit
MR update touching API Create MR pipeline only context, mr_verify, api_tests Suppress redundant push pipeline
MR update touching only web Create MR pipeline only context, mr_verify api_tests absent
Schedule Create schedule pipeline context, dependency_audit No branch/MR-specific jobs

4. Implement the verified baseline

Validate this configuration before committing it. If your default branch or project model differs, change only the relevant trusted baseline assumptions and record them.

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

stages:
  - inspect
  - verify

context:
  stage: inspect
  script:
    - printf 'source=%s\n' "$CI_PIPELINE_SOURCE"
    - printf 'ref=%s\n' "$CI_COMMIT_REF_NAME"
    - printf 'sha=%s\n' "$CI_COMMIT_SHA"
    - printf 'pipeline=%s\n' "$CI_PIPELINE_ID"
    - printf 'job=%s\n' "$CI_JOB_ID"

branch_smoke:
  stage: verify
  script: echo "synthetic branch smoke"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH'

mr_verify:
  stage: verify
  script: echo "synthetic MR verify"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'

api_tests:
  stage: verify
  script: echo "synthetic API tests"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      changes:
        paths:
          - services/api/**/*

dependency_audit:
  stage: verify
  script: echo "synthetic scheduled dependency audit"
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

5. Prove the baseline contexts

  1. Branch: push the lab branch before opening an MR. Record the push pipeline ID, SHA, and jobs.
  2. MR: open an MR, then change services/api/app.txt. Record exactly one pipeline for the new SHA with source merge_request_event; verify api_tests exists.
  3. MR diff negative: make a web-only commit. Verify api_tests is absent while mr_verify remains.
  4. Schedule: if permitted, create a temporary schedule for this disposable branch, run it once, record source schedule and dependency_audit, then remove the schedule. If not permitted, record the simulation limitation explicitly.

6. Inject the deliberate duplicate-pipeline bug

On the disposable branch only, replace the workflow with the broken version below. Do not alter job rules yet:

workflow:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
    - when: always

With the MR still open, push a harmless commit. Expect two pipeline attempts for the same SHA: one push and one merge_request_event. Preserve both pipeline IDs, source values, job graphs, and timestamps. This is the first-failure evidence; do not delete it.

7. Diagnose causally before repairing

Answer these questions in the evidence packet:

  1. Did GitLab compile the configuration? If not, this is not the intended rules failure.
  2. Which two source values created pipelines for the same SHA?
  3. Which workflow rule admitted the push pipeline? The final when: always.
  4. Did the runner cause the duplicate? No; duplication happened before job queueing.
  5. Would changing mr_verify job rules eliminate the redundant pipeline record? No; it could remove a job but would not fix pipeline creation.

8. Repair the workflow boundary

Restore the baseline workflow with the open-MR push suppression. Commit the repair, push once, and record the new SHA. Verify there is one MR pipeline rather than both branch and MR pipelines. Do not use a broad project setting change or disable merge-request pipelines to hide the defect.

Then re-run or simulate the schedule context and prove the repair did not block schedule. This is regression evidence: a narrow duplicate fix should not silently remove another intended pipeline class.

9. API-like/manual reasoning without credentials

The checkpoint does not require an API token. Add this design question to your evidence note: “What would happen if source were api or web?” Under the baseline workflow, neither is admitted, so no pipeline should be created. If your real product needs either source, add it explicitly in a reviewed future change. Never replace the final when: never with a convenience catch-all.

10. Required evidence packet

Repository identity

Disposable project/path and exact CI configuration commit SHAs.

Pipeline identity

For each context: pipeline ID, source, ref, immutable SHA, timestamp.

Workflow result

Expected/admitted/rejected pipeline classes and the matching rule rationale.

Job graph

Present/absent branch_smoke, mr_verify, api_tests, dependency_audit jobs.

Diff evidence

API-changing MR versus web-only MR and api_tests presence/absence.

Duplicate failure

Both pipeline IDs for one broken SHA, sources push + merge_request_event.

Repair evidence

One MR pipeline for repaired SHA plus schedule regression check.

Runner context

Runner ID/version/executor if jobs executed; otherwise “not observed.”

Assumptions

Docs date, GitLab offering/version if known, role limits, schedule simulation note if used.

Cleanup

MR/branch/schedule/synthetic paths removed only from the disposable lab as intended.

11. Verification checklist

  • Exactly the intended pipeline classes are admitted by workflow.
  • The MR-open push does not create a redundant push pipeline after repair.
  • api_tests appears only for MR contexts with API path changes.
  • dependency_audit appears only in the schedule context.
  • No secret values, tokens, production URLs, or privileged runner assumptions appear in logs/evidence.
  • The original duplicate pipelines remain preserved as failure evidence.
  • Cleanup is scoped only to resources created by this checkpoint.

12. Cleanup and rollback

  1. Delete the temporary project schedule if you created one.
  2. Close the disposable merge request.
  3. Delete glci/ch08-checkpoint after preserving non-secret learning evidence.
  4. If the checkpoint was performed in an otherwise empty throwaway project, you may delete that exact project only after verifying its identity. Otherwise keep the project and remove only lab-owned files/refs.

13. What Chapter 08 adds to the production model

You can now prove conditional execution before runtime: which event/source/ref/SHA GitLab saw, whether workflow admitted a pipeline, which job rule matched first, what diff/tree evidence was evaluated, and which jobs entered the graph. This makes rules reviewable as operational policy instead of mysterious YAML.

Chapter 09 moves from which jobs exist to how those jobs depend on one another: stages, DAGs, needs, dependency ordering, critical path, and dataflow. The distinction matters because a job omitted by rules cannot participate in a dependency graph at all.

Next lesson

Next: Stages, needs DAGs, Dependency Graphs, Early Execution, and Pipeline Critical-Path Design: Concepts, Architecture, and Mental Model

Continue with the next lesson in the course sequence and carry forward the evidence-first GitLab CI/CD operating model.

Knowledge check

What two state predictions should be written before running the checkpoint?

After injecting the bug, what evidence proves duplicate pipelines rather than a retried job?

Why not fix duplicate pipelines by changing only mr_verify job rules?

What regression must be checked after restoring MR duplicate suppression?

What does this checkpoint deliberately avoid?

Version and compatibility note

GitLab and GitLab Runner evolve continuously. Treat version-sensitive YAML, runner/executor behavior, APIs, security features, policy controls, tiers, and deprecations as assumptions to verify against the current official GitLab documentation before production use. Preserve the exact project/ref/SHA, compiled configuration, pipeline/job IDs, runner/tool versions, and external target evidence used for any reproducible lab or incident record.

Official references and version notes

Documentation verification date: 2026-09-11. GitLab CI/CD rule semantics evolve; self-managed installations should confirm their deployed GitLab version before relying on newer syntax.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.