Chapter 19Lesson 05~210 minutes

Checkpoint Lab — Environments, Deployments, Environment Tiers, URLs, Deployment History, and Operational Traceability

Perform two traceable simulated deployments, verify exact artifact lineage and external-state snapshots, preserve deployment history, and document a rollback target without rebuilding intended bytes.

Checkpoint labTwo deploymentsRollback evidenceExternal stateCleanup

Learning objectives

  • Predict how two pipeline executions change environment history, deployment identity, target digest, and health evidence before running them.
  • Perform two simulated deployments to one stable environment while preserving exact source and artifact identity.
  • Verify target state independently after each deployment and keep the evidence required to distinguish GitLab record state from target state.
  • Select and document a rollback target using the original source SHA and artifact digest rather than a newly rebuilt approximation.
  • Produce an evidence packet and cleanup plan that is safe for a disposable GitLab project and local simulation.

1. Checkpoint mission: two traceable deployments and one rollback dossier

Create two pipeline executions against one disposable training/ch19-checkpoint environment. Each execution must build one synthetic artifact, record its digest, deploy those exact bytes to the simulation, create one GitLab deployment record, and verify the target snapshot independently. After the second deployment, document how you would roll back to deployment 1 without rebuilding its payload.

The checkpoint is complete only when the evidence lets another engineer answer: what source produced each payload, what exact bytes were deployed, which GitLab records represent those changes, what did the target report, and which retained payload is the rollback target?

2. Assumptions and free-path boundaries

Item Checkpoint assumption
GitLab capability Free-tier environment/deployment records; no protected-environment approval required
Runner Any authorized runner capable of Alpine container or equivalent shell execution; record actual runner/executor
Image alpine:3.22; coreutils installed at runtime for sha256 tooling
Target Filesystem snapshot artifact used as a faithful external-target simulation
Environment training/ch19-checkpoint, tier testing
URL https://training.invalid/ch19-checkpoint (intentionally non-routable metadata)
Credentials None; no cloud account, PAT, secret, registry credential, or production system
Retention Checkpoint artifacts expire_in: 1 week; complete rollback exercise within retention window

3. Write predictions before execution

Record at least these predictions in evidence/predictions.md before the first push:

  1. Pipeline A creates environment training/ch19-checkpoint if it does not exist and creates deployment D1 tied to SHA-A.
  2. Pipeline B reuses the same environment identity and appends deployment D2 tied to SHA-B rather than creating a second environment.
  3. The build artifact digest changes after the controlled source change, and the simulated target digest matches that pipeline’s artifact digest after each deploy.
  4. The verify job does not create an ordinary deployment record because it uses action: verify.
  5. Rollback target D1 remains identifiable by source SHA-A + digest-A + retained artifact location even after D2 becomes current.

4. Checkpoint pipeline

stages: [build, deploy, verify]

build:checkpoint:
  stage: build
  image: alpine:3.22
  script:
    - apk add --no-cache coreutils
    - mkdir -p dist evidence
    - cp src/app.txt dist/app.txt
    - sha256sum dist/app.txt | tee dist/app.sha256
    - printf 'source=%s
ref=%s
sha=%s
pipeline=%s
job=%s
'         "$CI_PIPELINE_SOURCE" "$CI_COMMIT_REF_NAME" "$CI_COMMIT_SHA" "$CI_PIPELINE_ID" "$CI_JOB_ID"         > evidence/build-identity.txt
  artifacts:
    expire_in: 1 week
    paths: [dist/, evidence/build-identity.txt]

deploy:checkpoint:
  stage: deploy
  image: alpine:3.22
  needs:
    - job: build:checkpoint
      artifacts: true
  resource_group: ch19-checkpoint-environment
  script:
    - apk add --no-cache coreutils
    - sha256sum -c dist/app.sha256
    - mkdir -p target/current evidence
    - cp dist/app.txt target/current/app.txt
    - cp dist/app.sha256 target/current/app.sha256
    - sha256sum target/current/app.txt | tee evidence/target-observed.sha256
    - printf 'sha=%s
pipeline=%s
job=%s
environment=%s
env_id=%s
'         "$CI_COMMIT_SHA" "$CI_PIPELINE_ID" "$CI_JOB_ID" "$CI_ENVIRONMENT_NAME" "$CI_ENVIRONMENT_ID"         > evidence/deployment-receipt.txt
  environment:
    name: training/ch19-checkpoint
    deployment_tier: testing
    url: https://training.invalid/ch19-checkpoint
  artifacts:
    expire_in: 1 week
    paths: [target/current/, evidence/]

verify:checkpoint:
  stage: verify
  image: alpine:3.22
  needs:
    - job: deploy:checkpoint
      artifacts: true
  script:
    - apk add --no-cache coreutils
    - sha256sum -c target/current/app.sha256
    - grep '^health=ok$' target/current/app.txt
    - printf 'verified_sha=%s pipeline=%s job=%s
' "$CI_COMMIT_SHA" "$CI_PIPELINE_ID" "$CI_JOB_ID"
  environment:
    name: training/ch19-checkpoint
    action: verify

The resource_group carries Chapter 18’s concurrency lesson forward. It prevents overlapping checkpoint deployment jobs from owning the same simulated environment at the same time; it does not replace artifact or health verification.

5. Pipeline A: create deployment D1

  1. Use payload version=checkpoint-v1 and health=ok.
  2. Commit/push and record SHA-A, pipeline A ID, all job IDs, digest-A, environment ID, deployment D1 ID/status/actor, and target observed digest-A.
  3. Download and retain the build artifact within the disposable lab window. Record its artifact/job location in the evidence packet.
  4. Confirm the environment is available and tier testing. The non-routable URL is not a failed health check; the target snapshot is the health/version evidence for this simulation.

6. Pipeline B: update once and create deployment D2

Change only the synthetic payload:

GitLab CI/CD Chapter 19 checkpoint
health=ok
version=checkpoint-v2
  1. Commit/push and record SHA-B, pipeline B ID, job IDs, digest-B, deployment D2 ID/status/actor, and target observed digest-B.
  2. Confirm the environment ID/name is unchanged.
  3. Confirm the deployment history now contains D1 then D2 for the same environment.
  4. Confirm digest-B differs from digest-A and target read-back matches digest-B.

7. Deliberate provenance failure: break the target copy, not the YAML parser

On a disposable third branch/commit, modify the deploy script to copy a fixed old-bytes file while still exiting zero. Preserve the new deployment/job IDs and let verify:checkpoint fail on the digest/content check.

Diagnose it using the evidence chain: source SHA and build digest are correct; compilation/job creation are correct; deployment job is green; GitLab deployment exists; target observed digest is wrong. Repair only the copy/provider step and rerun the smallest safe deployment+verification scope with the same intended artifact if your project design can do so.

Do not delete the broken deployment; it is the checkpoint’s first-failure evidence.

8. Rollback dossier: identify exact v1 bytes before attempting recovery

Document the rollback target for D1:

Field Required value
Environment training/ch19-checkpoint + environment ID
Deployment D1 ID/IID/status/actor/time
Source SHA-A + ref
Artifact producer job ID + digest-A + retained location
Target evidence observed digest-A and health result after D1
Rollback mechanism rerun/redeploy old deployment job only if it can consume the retained exact artifact; otherwise promote/retrieve immutable payload by digest
Verification after rollback target read-back must equal digest-A and health check must pass

GitLab rollback can create a new deployment that points to the older commit and reruns deployment logic. The checkpoint does not require you to alter a real target. Your plan must explicitly refuse “rebuild SHA-A and assume it is the same.”

9. Required evidence packet

Category Required evidence
Source/config CI_PIPELINE_SOURCE, refs, SHA-A/SHA-B, exact YAML commits, merged-config assumption
Pipelines/jobs Pipeline A/B IDs, build/deploy/verify job IDs and statuses
Runtime Runner/executor and alpine:3.22 identity; unknowns marked explicitly
Artifact digest-A/digest-B, producer job IDs, retention/location
Environment environment ID/name/state/tier/URL
Deployments D1/D2 IDs/statuses/actors/SHA/ref and ordering
External simulation target observed digest and health result after each deployment
Failure broken deployment/job ID, expected digest, observed wrong digest, repaired transition
Rollback D1 rollback dossier with exact digest and verification plan
Assumptions why .invalid URL and filesystem snapshot are faithful limitations rather than production health proof

10. Verification checklist

  • Exactly one logical environment identity was used for the two intended deployments.
  • D1 maps to SHA-A/digest-A and D2 maps to SHA-B/digest-B.
  • The build artifact is never rebuilt inside the deploy job.
  • The deployment job verifies the artifact digest before copying it.
  • The verify job uses action: verify and validates target evidence independently.
  • The deliberately broken green deploy is preserved and its verify failure explains the external-state mismatch.
  • The rollback dossier names exact retained bytes by digest and refuses unverified rebuild equivalence.
  • No real URL, cloud resource, protected production environment, or credential was used.

11. Cleanup / rollback

  1. Restore the correct deployment script after the deliberate failure.
  2. Close/delete only the disposable checkpoint branches/project resources you created.
  3. Let checkpoint artifacts expire after the evidence/rollback exercise or delete them only inside the disposable project if required.
  4. If you stop the environment, record the final state and remember that stopped does not prove external deletion.
  5. Do not erase unrelated deployment history, environment-scoped variables, shared runner settings, or project-wide safety controls.

12. What Chapter 19 adds—and the bridge to Chapter 20

Chapter 19 turns “deployment” into an auditable chain: exact source → exact artifact → deployment job → stable environment identity → GitLab deployment record → independently verified target state → retained rollback identity. That chain lets operators distinguish CI success, GitLab CD metadata, and real health instead of treating them as one green box.

Chapter 20 extends the same evidence model to dynamic review apps, where the harder problem is lifecycle: deterministic environment names/slugs, per-merge-request URLs, ephemeral resource IDs, stop jobs, auto_stop_in, route maps, and proof that resources were actually cleaned up.

Knowledge check

What must stay identical when documenting a byte-accurate rollback target?

Why does the checkpoint use one stable environment name for D1 and D2?

What does the deliberate broken green deploy teach?

Why is resource_group still useful in Chapter 19?

What lifecycle problem becomes central in Chapter 20?

Next chapter

Chapter 20 — Review apps and dynamic environments

Apply the same traceability model to per-merge-request ephemeral stacks, URLs, stop actions, auto-stop, route maps, and cleanup proof.

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-12. Environment/deployment keywords, environment actions, deployment-tier variable support, auto-stop behavior, rollback UI behavior, environment-scoped variables, and deployment safety are version-sensitive. Re-check the GitLab and Runner versions used by production delivery before applying the exact examples.

  • Environments — environment identity/state, tiers, URLs, stop/auto-stop behavior, environment-scoped variables, and operational views.
  • Deployments — deployment history, deployment refs, retry/rollback behavior, and auditability.
  • Deployment safety — deployment serialization, outdated-job prevention, protected environments, and rollback considerations.
  • CI/CD YAML syntax reference — environment, environment:name, url, action, auto_stop_in, deployment_tier, and related job semantics.
  • Deployments API — deployment IDs, statuses, SHA/ref, user, environment, and history queries.
  • Environments API — environment metadata/state/tier management when API access is appropriate.
  • CI/CD variables — environment scope behavior and precedence boundaries.

Current assumptions used in this chapter: environments and deployment history are available on Free, Premium, and Ultimate across GitLab.com, Self-Managed, and Dedicated. Environment states include available, stopping, and stopped. environment:action currently supports start (default, creates a deployment after job start), prepare, verify, access, and stop; the latter four model lifecycle/access work rather than ordinary deployment creation. Deployment tiers are production, staging, testing, development, and other; CI/CD-variable support for deployment_tier was added in GitLab 18.5. auto_stop_in uses natural-language durations; stop processing is background work and is not an exact real-time timer. The mandatory labs use synthetic artifacts, a stable training/ch19 environment, alpine:3.22, a reserved .invalid URL, and filesystem/artifact snapshots as a faithful target simulation—no cloud account, protected production environment, or real credential is required.

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.