Chapter 20Lesson 05~335 minutes

Checkpoint Lab — Includes, Templates, CI/CD Components, Component Catalog, and Reusable Pipeline Architecture

Extract a repeated pipeline fragment into a reusable versioned unit, predict and inspect the merged configuration, introduce one incompatible input change, record provenance, and clean up safely.

CheckpointReusable unitExpanded YAMLProvenanceMigrationCleanup

Learning objectives

  • Predict the final merged jobs before linting.
  • Build a three-file same-commit reusable pipeline with typed inputs.
  • Record provenance and runtime SHA evidence.
  • Introduce and repair one incompatible input value without hiding the failure.
  • Document production dependency trust and cleanup/rollback.
Availability baseline (verified 2026-08-22 against current GitLab 19.3 documentation). include, CI/CD inputs, CI/CD components, the CI/CD Catalog, and CI Lint are available on Free/Premium/Ultimate across GitLab.com, Self-Managed, and Dedicated. Component references must resolve on the same GitLab instance as the consuming project. The mandatory labs require only a disposable Free project and local configuration. Catalog publication is optional because publishing requires a catalog-enabled component project, appropriate project roles, a semantic-version release, and repository metadata. The current glab repo publish catalog command is experimental and therefore is not a mandatory production path.

1. Checkpoint scenario and preflight

You will build a three-file reusable CI arrangement in one disposable Free project. It demonstrates same-commit local reuse, typed inputs, merged-configuration inspection, provenance recording, one deliberate contract failure, and cleanup. No real secret, external component, Catalog publication, deployment, registry deletion, or privileged runner is required.

Assumption Required
GitLab tier/offering Free-compatible on GitLab.com, Self-Managed, or Dedicated.
Project role Enough permission to push a disposable branch and run CI.
Runner Any ordinary eligible runner; if compute is unavailable, CI Lint/merged-YAML evidence still completes the configuration exercise.
Secrets None. Do not add tokens to source or print environment dumps.
Catalog Not required. Publication remains an optional governance extension.

2. Predict two state changes before touching the repository

Write these predictions first:

Prediction Expected
Configuration graph Main file will include one reusable job template and one typed-input file; GitLab will compile them into one merged configuration.
Runtime graph Three harmless jobs will exist; they will execute the same consumer commit SHA and receive no new credential scope.
Provenance Both included files resolve to the exact same Git commit as .gitlab-ci.yml because they are local includes.
Failure drill An invalid typed input will prevent configuration/pipeline creation rather than execute an unintended mode.

3. Create the reusable files

Create .gitlab/ci/ch20-template.yml:

.text_check:
  stage: test
  script:
    - test -n "$TARGET"
    - test -f "$TARGET"
    - wc -c "$TARGET"

Create .gitlab/ci/ch20-contract.yml:

spec:
  inputs:
    profile:
      options: [quick, full]
      default: quick
    emit_summary:
      type: boolean
      default: true
---
contract_check:
  stage: test
  script:
    - printf 'profile=%s summary=%s\n' '$[[ inputs.profile ]]' '$[[ inputs.emit_summary ]]'

Create two harmless fixtures:

mkdir -p labdata
printf 'api fixture\n' > labdata/api.txt
printf 'worker fixture\n' > labdata/worker.txt

4. Compose the main pipeline

stages: [test]

include:
  - local: .gitlab/ci/ch20-template.yml
  - local: .gitlab/ci/ch20-contract.yml
    inputs:
      profile: full
      emit_summary: true

api_check:
  extends: .text_check
  variables:
    TARGET: labdata/api.txt

worker_check:
  extends: .text_check
  variables:
    TARGET: labdata/worker.txt

Before linting, predict the final stage, script, and TARGET for api_check and worker_check, plus the interpolated input values for contract_check.

5. Validate and capture expanded configuration

PROJECT_ID="12345678"
mkdir -p evidence

jq --null-input --arg yaml "$(cat .gitlab-ci.yml)" '{content:$yaml}' \
| glab api --method POST "projects/$PROJECT_ID/ci/lint?include_merged_yaml=true" \
  --header "Content-Type: application/json" --input - \
  > evidence/ch20-lint.json

jq '{valid,errors,warnings}' evidence/ch20-lint.json
jq -r '.merged_yaml' evidence/ch20-lint.json > evidence/ch20-merged.yml

Verify: the lint response is valid and your predicted effective jobs match evidence/ch20-merged.yml.

6. Record dependency provenance before execution

git rev-parse HEAD > evidence/consumer-before.txt
git hash-object .gitlab-ci.yml .gitlab/ci/ch20-template.yml .gitlab/ci/ch20-contract.yml \
  > evidence/source-blob-ids.txt
sha256sum .gitlab-ci.yml .gitlab/ci/ch20-template.yml .gitlab/ci/ch20-contract.yml \
  > evidence/source-sha256.txt

The Git blob IDs identify repository content; SHA-256 provides an additional portable evidence digest. Neither proves trust by itself, but both make later comparisons precise.

7. Commit, push, and verify runtime identity

git switch -c ch20/checkpoint
git add .gitlab-ci.yml .gitlab/ci/ch20-template.yml .gitlab/ci/ch20-contract.yml labdata/ evidence/
git commit -m "lab: checkpoint reusable pipeline architecture"
git push -u origin ch20/checkpoint

git rev-parse HEAD

Inspect the resulting pipeline. Verify that all jobs belong to this SHA and that no external endpoint, registry, environment, or secret-bearing variable was introduced.

8. Deliberately break the typed contract

Change only the input value:

include:
  - local: .gitlab/ci/ch20-contract.yml
    inputs:
      profile: turbo
      emit_summary: true

turbo is outside the declared options. Run CI Lint again and preserve the validation error. This is the desired failure mode: configuration is rejected before a job can execute with an undefined policy.

9. Repair the smallest cause and re-verify

Restore profile: full (or add a deliberately reviewed new option in the contract with an appropriate compatibility decision). Lint again and compare the before/after errors and merged YAML. Do not add allow_failure; this is a configuration contract problem, not a runtime failure to suppress.

10. Convert the provenance record into a production dependency statement

Write a short dependency record such as:

dependency: platform/ci-components/verify
mechanism: include:component
consumer-policy: full semantic release
requested-version: 2.3.1
resolved-commit: <record exact reviewed SHA>
source-reviewed-by: <team/person>
runner-requirement: unprivileged
credentials-required: none
rollback: pin previous known-good release/SHA

This record is more operationally useful than “we use the shared template.”

11. Optional Catalog design review

Without enabling anything, verify whether a future component project would satisfy current publication prerequisites: project description, root README, templates/, tests, semantic tag, release job, Catalog-project setting, Owner to enable the setting, and Maintainer/Owner for publication. Treat the experimental glab repo publish catalog command as optional until your instance explicitly supports it.

12. Cleanup and rollback

Keep the evidence files if they are useful learning records. Remove synthetic branch/project resources only after verification.

git switch main
# Inspect before destructive remote deletion.
git ls-remote --heads origin ch20/checkpoint
# If and only if this is your disposable lab branch:
# git push origin --delete ch20/checkpoint
git branch -D ch20/checkpoint 2>/dev/null || true

If you created an optional disposable component project, record its final SHA and consumers first, then delete the project through the UI/API only if no other project depends on it.

13. What Chapter 20 adds to the production GitLab operating model

Your pipeline model now has an explicit software-supply layer: reusable CI code has owners, typed interfaces, immutable provenance, tests, release compatibility, least-privilege execution, consumer migration, and rollback. Chapter 21 will use that model to optimize execution safely—interrupting obsolete work, retrying intentionally, debugging failures, and controlling pipeline cost without destroying evidence.

Knowledge check

What evidence proves what GitLab actually compiled from multiple reusable files?

Why is the deliberately invalid profile: turbo failure useful?

What two identities should a consumer record for an external component dependency?

What is the least-privilege rule for a reusable component?

A Catalog release breaks consumers. What is the safest immediate migration control?

Why is Catalog publication not mandatory for this checkpoint?

Summary

You built, inspected, broke, repaired, and documented a reusable pipeline dependency without paid features or live external infrastructure. The durable production pattern is: small contract, explicit owner, merged-config inspection, immutable provenance, representative tests, least privilege, compatible releases, and a known rollback.

Official references

Primary sources used for the current GitLab 19.3 behavior taught in this lesson:

Next chapter

Chapter 21 — Pipeline Performance, Interruptible Jobs, Retry, Failure Handling, Debugging, and Cost Control

With reusable architecture established, the next chapter measures pipeline waste and latency, applies interruptibility and retry deliberately, preserves failure evidence, and controls execution cost.

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
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.