Checkpoint Lab — CI/CD Components, Component Catalog, inputs, Versioned Reuse, and Organization-Wide Pipeline Building Blocks
The checkpoint lab designs and tests a small reusable component API, verifies one accepted and one rejected consumer, pins immutable identity, captures compiled-job evidence, and produces a compatibility and upgrade note suitable for organization-wide reuse without publishing anything to production.
Learning objectives
- Build a tiny reusable component contract with explicit input types, validation, job naming, output/evidence behavior, and assumptions.
- Test accepted and rejected consumers and prove that invalid inputs fail before runner execution.
- Pin the component to an immutable SHA or governed release and record that identity in the evidence packet.
- Create a compatibility/upgrade note covering SemVer, breaking changes, rollback, permissions, secrets, and side effects.
- Bridge safely to Chapter 14 by distinguishing reusable component APIs from parent-child pipeline orchestration.
1. Checkpoint scenario and acceptance target
You are the maintainer of a tiny organization component named
evidence-stamp. It adds one job that writes a
non-secret evidence file containing the consumer source SHA,
pipeline ID, component contract version, and caller label. The API
must be explicit, collision-safe, testable, and immutable-pin
friendly.
The lab has one valid consumer and one deliberately invalid consumer. The invalid consumer must fail at configuration time. No external secrets, catalog publication, cloud account, registry, or production project is required.
2. Preflight and assumptions
- Disposable GitLab project/namespace or a faithful local file simulation.
- GitLab offering/version recorded; current docs verified 2026-09-11.
- Normal non-privileged runner if executing; otherwise CI Lint/expanded-config evidence is sufficient for configuration-only steps.
- No production credentials or proprietary source.
- Exact source SHA and component identity recorded before each test.
3. Predict state changes before acting
| Prediction | How to verify independently |
|---|---|
|
Valid consumer creates one job named
|
Expanded configuration + pipeline job list |
| Invalid prefix fails before runner assignment | CI Lint/configuration error and absence of job/runner ID |
| Component output artifact is tied to consumer SHA/pipeline/job | Artifact content + producer job metadata |
| Pinned version/ref remains explicit in evidence | Consumer YAML + recorded source/release mapping |
4. Define the tiny component contract
spec:
inputs:
job-prefix:
description: "Lowercase identifier used to avoid job-name collisions"
regex: '^[a-z][a-z0-9-]{1,20}$'
stage:
default: verify
options: [test, verify]
label:
description: "Non-secret evidence label"
default: checkpoint
---
"$[[ inputs.job-prefix ]]-evidence-stamp":
stage: $[[ inputs.stage ]]
image: alpine:3.20.3
script:
- mkdir -p evidence
- printf 'label=%s\n' '$[[ inputs.label ]]' > evidence/stamp.txt
- printf 'sha=%s\n' "$CI_COMMIT_SHA" >> evidence/stamp.txt
- printf 'pipeline=%s\n' "$CI_PIPELINE_ID" >> evidence/stamp.txt
- printf 'job=%s\n' "$CI_JOB_ID" >> evidence/stamp.txt
artifacts:
name: "stamp-$CI_PIPELINE_ID-$CI_JOB_ID"
expire_in: 1 day
paths:
- evidence/stamp.txt
5. Valid consumer
stages: [test, verify]
include:
- local: templates/evidence-stamp.yml
inputs:
job-prefix: app-a
stage: verify
label: contract-v1
consumer-test:
stage: test
image: alpine:3.20.3
script:
- echo "consumer=$CI_COMMIT_SHA"
Validate the expanded configuration. Confirm exactly one generated
app-a-evidence-stamp job with the expected stage,
image, script, and artifact path. If runtime is available, run the
pipeline and download only the non-secret artifact.
6. Invalid consumer and expected failure
include:
- local: templates/evidence-stamp.yml
inputs:
job-prefix: "APP A!"
stage: verify
label: should-not-run
Prediction: configuration fails due to regex validation and no generated job reaches the queue. Preserve the original validation error. The exercise is complete only when you can explain why runner diagnostics are irrelevant here.
7. Replace simulated file identity with an immutable component pin
For a real disposable component project, store the template at
templates/evidence-stamp/template.yml. First test the
component at its current SHA, then create a governed release only if
you own the project and want to practice release workflow.
include:
- component: $CI_SERVER_FQDN/platform-lab/evidence-components/evidence-stamp@0123456789abcdef0123456789abcdef01234567
inputs:
job-prefix: app-a
stage: verify
label: contract-v1
The SHA above is intentionally fake. Replace it only with the exact SHA of your disposable authorized component project. Never copy a fake example identity into production.
8. Write the compatibility and upgrade note
Document the component as v1 contract: required
prefix, allowed stages, safe non-secret label, one generated job,
one short-lived artifact, no secret/privileged/external side
effects. For a future v1.1, adding an optional input with a default
is allowed if old invocations keep compiling and behaving within
contract. Removing label, changing job naming, or
requiring a new secret would require explicit compatibility review
and likely a major version.
| Upgrade field | Required note |
|---|---|
| Old identity | Exact SHA/release currently used |
| New identity | Exact SHA/release proposed |
| Input diff | Added/removed/changed types/defaults/options/regex |
| Generated jobs | Names/stages/rules/images/needs |
| Security | Tokens/secrets/runner/network/permissions changed? |
| Outputs | Artifacts/reports/paths/retention changed? |
| Side effects | API/registry/deployment behavior changed? |
| Rollback | Known-good prior identity and conditions |
9. Evidence packet
| Item | Capture |
|---|---|
| Consumer source | Project/path, ref, exact SHA, pipeline source |
| Component identity | Project/path, component name, requested selector, resolved/pinned SHA or release |
| Contract | spec:inputs definitions and supplied non-secret arguments |
| Compiled jobs | Expanded YAML and generated job name/stage/image/artifact configuration |
| Valid run | Pipeline/job IDs, status, runner/executor/version if observed |
| Invalid run | Exact validation error and proof no runtime job existed |
| Artifact | Producer job/SHA, artifact name/path, digest if calculated, expiry |
| Assumptions | GitLab offering/version, free/disposable path, no catalog publication required |
| Compatibility | Upgrade/rollback note and owner/review policy |
10. Verify the retained artifact independently
If the valid job ran, compute a digest after downloading the artifact. This proves the evidence file you reviewed is the file produced by the recorded job; it does not prove the component itself is trustworthy.
sha256sum evidence/stamp.txt
cat evidence/stamp.txt
The expected file contains only the synthetic label plus consumer SHA, pipeline ID, and job ID. Stop if any secret or unexpected environment dump appears.
11. Optional catalog publication architecture — not required
If this were promoted beyond the lab, the component project would
need a root README, tested templates, protected/reviewed release
flow, catalog-project setting, and a SemVer tag whose pipeline
creates a GitLab release using the release keyword.
That publication is an organizational side effect and should happen
only in an authorized component project.
Do not publish the checkpoint merely to finish the course exercise.
12. Verification and cleanup checklist
- Valid input compiles exactly the expected generated job.
- Invalid input fails before runtime and retains its original validation evidence.
- Job naming cannot collide when callers use unique prefixes.
- No real credential, broad token, privileged runner, production URL, registry, cloud, or deployment target is used.
- Artifact is non-secret, short-lived, tied to exact job/pipeline/SHA, and independently inspectable.
- Component identity is immutable or governed, not an unexplained moving branch.
- Compatibility/upgrade and rollback notes exist before organization-wide rollout.
After exporting evidence, delete only the disposable resources created by this lab.
13. What Chapter 13 adds to the production operating model
You can now treat reusable CI/CD building blocks as versioned APIs: explicit producer ownership, typed/validated inputs, immutable release identity, generated-job evidence, least-privilege assumptions, tests, and an upgrade/rollback policy. Chapter 14 changes the scale of orchestration: parent-child pipelines, generated child configuration, and monorepo decomposition introduce multiple pipeline records and new source/configuration boundaries.
Knowledge check
Why is the invalid consumer an important test rather than an inconvenience?
It proves the API rejects unsupported states during configuration and prevents ambiguous runtime behavior.
What makes the component artifact evidence traceable?
The artifact is produced by a recorded job tied to consumer SHA/pipeline/job IDs, with a known path/name/expiry and optional digest.
Does a pinned component SHA remove the need for source review?
No. It makes identity immutable. You still review what that exact code does and which permissions/side effects it requires.
When would changing the generated job name be a breaking change?
When consumers, merge requirements, automation, needs edges, or observability depend on that stable job identity.
Why is catalog publication optional in this checkpoint?
The learning goal is the component contract/version/evidence model. Catalog publication is a separate organizational release side effect requiring project ownership and release governance.
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. Component, input, catalog, component-context, analytics, and publication behavior is version-sensitive. Re-check the GitLab version deployed on Self-Managed or Dedicated instances before relying on newer syntax.
- CI/CD components and CI/CD Catalog — component projects, version selectors, permissions, testing, publication, security guidance, and current project limits.
-
CI/CD inputs
—
spec:inputs, interpolation, types, defaults, options, regex validation, size limits, and include inputs. -
CI/CD YAML syntax reference
—
include:component,include:inputs, component context, and current parsing semantics. - Pipeline editor — validate and inspect expanded configuration before execution.
- CI Lint — syntax/configuration validation and pipeline simulation where available.
- Component examples — testing components against the current SHA and coupling versioned resources to component releases.
1/1.2 and ~latest. Catalog
releases require SemVer and publication through a GitLab
release job. Components can only be referenced from the
same GitLab instance. Inputs are resolved at pipeline creation;
missing required or invalid typed/options/regex values reject
configuration before runner execution. A string inside one input
must be under 1 KB, and a string containing interpolated input
content must be under 1 MB. Component context fields
(name, sha, version,
reference) are current functionality but should be
version-checked on older instances.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.