Chapter 29Lesson 05~260 minutes

Checkpoint Lab — Reusable Platform Pipelines, Golden Paths, and Organization-Wide Delivery Design

Publish a local golden-path v1 for two disposable callers, prove a simulated breaking v2 is unsafe, release a compatible v2.1, migrate one caller and retain an explicit exception/rollback record for the other.

CheckpointMigrationRollbackEvidenceTelemetry

Learning objectives

  • Create real local Git SHAs for golden-path v1, deliberately broken v2 and compatible v2.1.
  • Prove two caller contracts before and after the platform change.
  • Predict and verify caller pin, compatibility, permission and governance state changes.
  • Migrate one caller while retaining a bounded exception and last-known-good rollback for the other.
  • Produce a platform evidence packet that can be reviewed without access to production systems.

1. Checkpoint: operate the platform as a versioned product

The checkpoint uses a local delivery-platform Git repository and two local caller repositories. You will publish three real commits: v1, intentionally breaking v2 and compatibility-preserving v2.1. Contract tests must reject v2 before migration. Then app-alpha advances to v2.1, while app-beta remains on v1 under an expiring exception.

Optional GitHub execution can mirror these disposable repositories and replace local lock records with real reusable-workflow uses: lines pinned to the exact platform SHA. The mandatory outcome does not depend on an organization, Enterprise plan, paid runner, cloud provider or live deployment.

2. Preflight and safety guard

  • Work only under a new disposable directory such as gha-platform-checkpoint.
  • Use fake example.invalid identities; do not configure or print credentials.
  • Local Git + Python 3 are sufficient for the mandatory simulation.
  • Optional GitHub execution assumes ubuntu-24.04, Python 3.13, checkout 3d3c42e5aac5ba805825da76410c181273ba90b1, setup-python 5fda3b95a4ea91299a34e894583c3862153e4b97 and upload-artifact 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a.
  • Do not change real organization Actions policy, rulesets, runner groups, environments or secrets for the mandatory checkpoint.

3. Predict state changes before running

Prediction How to verify independently
v1 creates one immutable platform commit used by both callers. git rev-parse platform-v1^{commit} equals each caller lock SHA.
broken v2 changes no caller pin. Caller lock files remain v1 while compatibility command exits nonzero.
v2.1 preserves v1 contract and adds a new output. Contract test passes both callers and JSON diff shows additive output.
alpha migrates; beta does not. Alpha lock equals v2.1 SHA; beta lock equals v1 SHA.
beta divergence is governed. Exception record has owner, reason, expiry and compensating control.
Rollback remains possible. v1 SHA and compatibility evidence are retained after alpha migration.

4. Create the checkpoint layout

gha-platform-checkpoint/
├── delivery-platform/
│   ├── contracts/platform-v1.json
│   ├── contracts/platform-v2-broken.json
│   ├── contracts/platform-v2.1.json
│   └── tools/checkpoint.py
├── app-alpha/
│   ├── platform-contract.json
│   └── platform-lock.json
└── app-beta/
    ├── platform-contract.json
    ├── platform-lock.json
    └── exception.json

5. Write the three platform contracts

{
  "version": "1.0.0",
  "workflows": {
    "ci": {"inputs": ["python-version", "working-directory"], "outputs": ["evidence-digest"]},
    "deploy": {"inputs": ["service", "environment-name", "artifact-digest"], "outputs": ["deployment-record-digest"]}
  }
}
{
  "version": "2.0.0-broken",
  "workflows": {
    "ci": {"inputs": ["python-version", "working-directory"], "outputs": ["evidence-sha256"]},
    "deploy": {"inputs": ["service", "environment-name", "artifact-digest"], "outputs": ["deployment-record-digest"]}
  }
}
{
  "version": "2.1.0",
  "workflows": {
    "ci": {"inputs": ["python-version", "working-directory"], "outputs": ["evidence-digest", "evidence-sha256"]},
    "deploy": {"inputs": ["service", "environment-name", "artifact-digest"], "outputs": ["deployment-record-digest"]}
  }
}

The breaking change is intentionally narrow: v2 removes evidence-digest. v2.1 restores it and adds evidence-sha256. This makes compatibility causality obvious instead of hiding the exercise behind unrelated implementation changes.

6. Add the independent compatibility checker

from pathlib import Path
import json, subprocess, sys

def git(*args, cwd):
    return subprocess.check_output(["git", *args], cwd=cwd, text=True).strip()

def compatible(platform_path, caller_path):
    p=json.loads(Path(platform_path).read_text())
    c=json.loads(Path(caller_path).read_text())
    errors=[]
    for wf, expected in c["workflows"].items():
        actual=p["workflows"].get(wf, {})
        for key in ("inputs","outputs"):
            for item in expected.get(key,[]):
                if item not in actual.get(key,[]): errors.append(f"{wf}: missing {key[:-1]} {item}")
    return errors

platform=Path(sys.argv[1]); alpha=Path(sys.argv[2]); beta=Path(sys.argv[3])
selected = [sys.argv[4]] if len(sys.argv) > 4 else ["v1", "v2-broken", "v2.1"]
failed=False
for repo in (platform, alpha, beta):
    print(repo.name, git("rev-parse","HEAD",cwd=repo))
for version in selected:
    cp=platform/f"contracts/platform-{version}.json"
    for caller in (alpha,beta):
        errs=compatible(cp, caller/"platform-contract.json")
        if errs: failed=True
        print(version, caller.name, "PASS" if not errs else "FAIL", errs)
sys.exit(1 if failed else 0)

The checker reads declared platform and caller contracts. It does not use the platform output itself to decide what callers require, so the test can expose a platform omission. In a production platform, add executable fixture repositories and real workflow-run tests in addition to schema/contract checks.

7. Create v1, v2-broken and v2.1 as real Git revisions

set -euo pipefail
cd gha-platform-checkpoint/delivery-platform
git init -b main
git add contracts/platform-v1.json tools/checkpoint.py
git -c user.name='Platform Lab' -c user.email='platform@example.invalid' commit -m 'platform v1'
git tag platform-v1
V1="$(git rev-parse platform-v1^{commit})"

# Add the deliberately incompatible contract as the next release.
git add contracts/platform-v2-broken.json
git -c user.name='Platform Lab' -c user.email='platform@example.invalid' commit -m 'platform v2 breaking experiment'
git tag platform-v2-broken
V2="$(git rev-parse platform-v2-broken^{commit})"

# Add the additive compatibility repair.
git add contracts/platform-v2.1.json
git -c user.name='Platform Lab' -c user.email='platform@example.invalid' commit -m 'platform v2.1 compatibility repair'
git tag platform-v2.1
V21="$(git rev-parse platform-v2.1^{commit})"
printf 'v1=%s
v2-broken=%s
v2.1=%s
' "$V1" "$V2" "$V21" | tee ../release-map.txt

8. Lock both callers to v1 before compatibility testing

{
  "platform_release": "platform-v1",
  "platform_sha": "REPLACE_WITH_REAL_V1_SHA",
  "ci_workflow": ".github/workflows/ci.yml",
  "deploy_workflow": ".github/workflows/deploy.yml"
}

Use the exact SHA from release-map.txt. Initialize and commit each caller repository after writing the lock and v1 caller contract. Record each caller HEAD SHA. If you later mirror the lab to GitHub, the equivalent change is a caller workflow pin such as owner/delivery-platform/.github/workflows/ci.yml@<that exact 40-character SHA>.

9. Prove the intentionally broken v2 fails before migration

set +e
python delivery-platform/tools/checkpoint.py delivery-platform app-alpha app-beta v2-broken   | tee first-platform-compatibility.txt
STATUS=${PIPESTATUS[0]}
set -e
# Also run the focused v2 contract checker if implemented separately.
# Preserve all output before any repair or caller-pin edit.
printf 'checker_status=%s
' "$STATUS" >> first-platform-compatibility.txt

The evidence must show that evidence-digest is required by both callers but absent from v2. Broken v2 may remain as a tag/commit in this disposable repository because that object is evidence; the safe action is to block adoption, not erase history.

10. Verify v2.1, migrate alpha and create beta exception

Run python delivery-platform/tools/checkpoint.py delivery-platform app-alpha app-beta v2.1 and require exit status 0 for both caller contracts. Update app-alpha’s lock from v1 SHA to v2.1 SHA and commit that one dependency change. Keep app-beta on v1 and write this exception:

{
  "repository": "app-beta",
  "exception": "remain on platform-v1 during release freeze",
  "owner": "app-beta-maintainer",
  "approved_by": "platform-lab-owner",
  "created": "2026-09-10",
  "expires": "2026-10-10",
  "target": "platform-v2.1",
  "compensating_control": "v1 remains supported; platform security fixes are backported during exception"
}

This is an escape hatch with a return path. It does not grant permission to bypass a real organization policy. If an enterprise ruleset or runner-group control blocks a caller, use the organization’s formal approval process rather than encoding bypass=true in a workflow input.

11. Optional GitHub execution path

If you create three disposable GitHub repositories, push each local history, verify remote SHAs, then insert the exact platform commit SHA into the two caller workflows. Keep permissions: {} globally, grant contents: read only to CI checkout, and explicitly map any future secrets. Do not use @main or secrets: inherit in this checkpoint.

If you have Team/Enterprise runner groups or ruleset required workflows, inspect them read-only and document how they would bind the platform. Do not enable them merely to satisfy the lab. Mark the evidence as simulated architecture when those features are unavailable.

12. Required evidence packet

Field Required proof
Platform releases v1, broken-v2 and v2.1 tag→commit mappings.
Caller revisions alpha/beta HEAD SHAs and contract files.
Caller pins alpha v2.1 SHA; beta v1 SHA.
Compatibility first failure for v2 plus passing v2.1 results.
Permissions expected caller/called token permissions; no inherited secrets.
Runner boundary hosted runner assumption or simulated runner-group contract.
Template/reuse boundary copied caller shell distinguished from referenced workflows.
Exception beta owner, reason, expiry, compensating control and target version.
Upgrade channel how a newer SHA would be proposed/reviewed.
Telemetry version distribution, success/failure result and exception age.
Rollback last-known-good v1 SHA and exact alpha pin-revert procedure.
Limitations local contract simulation does not prove organization audit/ruleset/runner-group behavior.

13. Prove rollback without deleting evidence

To simulate a v2.1 runtime regression after alpha migrates, create a failing caller fixture but keep the v2.1 compatibility artifacts. Preserve the failed alpha run/simulation output. Then revert only alpha’s platform-lock.json to the stored v1 SHA, commit the change and rerun the v1 fixture. The failure remains inspectable; rollback changes the dependency pin, not history.

14. Cleanup and closeout

  • Copy the evidence packet outside the disposable repositories if you need to retain it.
  • Delete only gha-platform-checkpoint after confirming it is the exact lab directory.
  • If you mirrored the lab to GitHub, delete only those disposable repositories after preserving run IDs/log locations and tag→SHA mappings.
  • Do not delete a real shared platform repository, organization policy, runner group or environment as part of cleanup.

15. What Chapter 29 adds — and the bridge to Chapter 30

Chapter 29 turns individual workflow techniques into an operable internal platform: small versioned contracts, immutable caller pins, tested upgrades, explicit trust boundaries, governed exceptions and outcome telemetry. Chapter 30 adds observability mechanics—logs, step summaries, debug logging and annotations—so both platform owners and consumer teams can diagnose those distributed workflows quickly.

Next lesson

Workflow Logs, Step Summaries, Debug Logging, Annotations, and Observability: Core Concepts and Mental Model

Continue with the next lesson to build on the current concepts, evidence, security boundaries, and operational practices.

Knowledge check

Why must the broken v2 failure be preserved even though no caller migrated?

What two facts prove app-alpha actually migrated?

Why is app-beta’s exception safer than adding a bypass-policy input?

If alpha fails after migration, what should be preserved before rollback?

What does Chapter 30 contribute next?

Official references and version notes

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.