Skip to content

L03 platform patterns

Lesson 00 mapped the current delivery paths. Lesson 01 made workflow YAML readable as a graph. Lesson 02 turned the repos into a small delivery catalog. This capstone lesson starts from the current fos-workbench and sibling fos setup, then zooms out to the patterns polished CI/CD platforms use around large repos, multirepos, and many users.

The goal is not to adopt a heavy platform tool. The goal is to recognize which platform pattern would solve a concrete delivery problem, and which problem is still too small for platform work.

Azure is not part of the current delivery-platform operating model. The Azure files are deployment-target validation and historical context, not the path used today to ship the fos-workbench tutorial/docs surface or the sibling fos application.

The current setup is intentionally light.

fos-workbench has one main GitHub Actions delivery path. Pull requests and pushes run validation for the editor interface, serving module, generated references, docs-site content, and supporting tutorial checks. On main, deploy-docs publishes the validated docs-site and Observable analyst-dashboards bundle to Cloudflare Pages.

The sibling fos shape has a separate application delivery path. Pull requests validate the app, pushes to main deploy staging, and release tags or manual dispatch request production promotion behind a GitHub environment gate.

Sandcastle feeds this system by turning an issue into a branch and PR. It does not replace CI/CD. The delivery platform is still the system of repo contracts, checks, artifacts, environments, promotion, policy, secrets, observability, and feedback that turns changes into trusted published software.

That current state is enough for this lab because there are few repos, few operators, and visible workflows. A polished platform becomes interesting when the same questions repeat across many repos or many users:

  • Which checks should this repo run?
  • Which files changed, and what needs to rebuild?
  • Which artifact is immutable enough to promote?
  • Which environment can receive it?
  • Which policy gate must approve it?
  • Which deployment controller owns rollout and rollback?
  • Which signal proves the change worked?
  • Which template lets a new repo start without copying old YAML?

Adding more YAML copies commands. Building a delivery platform creates a shared operating model.

More YAML can be fine when there are only one or two workflows. It becomes fragile when every repo invents its own names for build steps, artifacts, environments, approvals, smoke checks, and secrets. A delivery platform is different because it makes those boundaries explicit and reusable. It gives repo owners a small interface: declare what you own, what you build, how you verify it, where it can go, and what evidence proves it is healthy.

That interface can still be implemented with GitHub Actions and markdown for a long time. A polished platform is not defined by Backstage, Argo CD, Flux, Bazel, Harness, or another named tool. Those tools only become useful after the repo has repeated delivery problems that a lighter contract cannot solve.

Use this table as a decision guide. Each pattern maps back to the current repo state and names a realistic next step without adopting a heavy platform tool.

PatternWhat polished platforms use it forCurrent repo stateRealistic next step
Reusable workflowsStandardize common jobs so teams do not paste build, test, publish, and smoke-check logic into every repo.fos-workbench has one main CI workflow; sibling fos has separate PR, staging, and release workflows. The repeated ideas are visible, but they are not yet shared workflow interfaces.Keep the current YAML while the repos are small. If a third repo repeats the same docs publish or Cloudflare Pages smoke-check shape, extract one reusable GitHub Actions workflow for that repeated path.
Change detectionRun only the checks and deployments affected by a change, especially in large repos and multirepos.The lab already separates editor, serving, docs-site, and deployment areas conceptually, but the delivery-platform lesson does not need to rewrite path filters now.Add path-aware documentation to the delivery catalog before changing CI. Only add path filters when test time or unrelated failures become a real operator cost.
Build graphModel jobs, dependencies, and artifacts as a graph instead of a flat command list.Lesson 01 already teaches editor, serving, and deploy-docs as a graph connected by gates and artifacts. Sibling fos has PR, staging, and production promotion stages.Name the graph in docs and PR templates first. If builds become slow or cross-repo dependencies appear, consider a lightweight generated graph view before introducing a monorepo build system.
Immutable artifactsBuild once, version the output, and promote the same artifact instead of rebuilding differently in every environment.fos-workbench promotes generated references, snapshots, the DuckDB/Parquet substrate, the Astro docs bundle, and the Observable analyst-dashboards bundle through CI. Sibling fos promotes SvelteKit build output.Make artifact names and retention rules explicit in the delivery catalog. Do not add an artifact registry until there are multiple release consumers or rollback needs that require durable versions.
Environment promotionMove a trusted artifact through named places with clear gates.fos-workbench publishes from main to the public docs environment. Sibling fos promotes from PR proof to staging, then to production after a GitHub environment approval.Keep Cloudflare Pages and GitHub environments as the mechanism. Add a short promotion runbook that says which trigger, gate, and smoke check belong to each environment.
Deployment controllersDelegate rollout, convergence, health checks, and rollback to a controller rather than hiding them in shell commands.Current docs publishing and sibling app deploys are direct GitHub Actions jobs using Cloudflare Pages. The k3s deployment lessons are deployment operations, not the current delivery path for this module.Stay with GitHub Actions for now. Revisit a controller only when long-running services need progressive rollout, drift reconciliation, or automatic rollback that the current Pages deployments cannot express.
Policy gatesEnforce approvals, required checks, secrets boundaries, and release rules before promotion.Pull-request checks, needs, generated-reference drift checks, Cloudflare secrets, and the sibling fos production environment gate already form the current policy surface.Document which gates are mandatory and which are advisory. Add branch protection or environment rules only when the repo owner wants GitHub to enforce the policy instead of relying on convention.
ObservabilityGive repo owners and operators feedback about build health, deployment health, smoke checks, and runtime symptoms.GitHub checks, docs-site tests, public analytical-surface smoke checks, and sibling fos auth smoke checks are the observable feedback today.Collect the existing status links in the Operator hub or delivery-platform README. Avoid a new observability stack until there are multiple runtime services with repeated diagnosis pain.
RollbackReturn an environment to a known good artifact when promotion succeeds technically but fails operationally.The current lab mostly relies on Git history, Cloudflare Pages deployment history, and failed smoke checks. Rollback is not yet a first-class catalog field.Add rollback notes to the environment contract: what artifact or deployment history would be restored, who decides, and which smoke check proves recovery. Keep it prose-first until rollback is practiced often enough to automate.
Self-service templatesLet a new repo or service start with approved defaults for ownership, CI, CD, secrets, environments, and smoke checks.Lesson 02 provides the catalog row shape, but the lab does not generate new repos or workflows from templates.Create a small markdown template for a new catalog entry. Only turn it into a workflow generator after several repos use the same fields and the manual template becomes the bottleneck.

Start with the delivery problem, not the tool.

Choose reusable workflows when multiple repos need the same proven job shape. Choose change detection when unrelated checks waste enough time to change operator behavior. Choose a build graph when dependencies are hard to see. Choose immutable artifacts when rebuilding during promotion makes releases untrustworthy. Choose environment promotion when the question is “where can this artifact go next?” Choose deployment controllers when rollouts and convergence are too complex for a single publish step. Choose policy gates when the risk is unauthorized or under-verified promotion. Choose observability when the problem is not knowing what failed. Choose rollback when recovery needs to be faster than “debug and patch forward.” Choose self-service templates when new repos repeat the same setup questions.

For the current fos-workbench and sibling fos setup, the most realistic next steps are small:

  1. Keep the delivery catalog current when a delivery path changes.
  2. Add a catalog-entry template before adding a catalog product.
  3. Write rollback notes for public docs and sibling app environments.
  4. Extract a reusable workflow only after a repeated workflow shape appears.
  5. Keep Azure out of the current delivery story unless a lesson is explicitly about the Azure deployment target.

Those steps improve the platform without pretending the lab already needs a centralized internal developer platform.

These checkpoint questions force you to choose an appropriate pattern for a concrete scenario.

  1. A third repo starts publishing a docs-site bundle to Cloudflare Pages using the same build, deploy, and smoke-check shape as fos-workbench. Which pattern should you reach for first?

    Expected reasoning: reusable workflows. The repeated job shape is now real, so extracting one shared workflow reduces copy-paste without adopting a heavy platform tool.

  2. A pull request changes only lesson prose, but the slowest application tests in another area keep failing for unrelated reasons. Which pattern addresses that problem, and what should you do before changing CI?

    Expected reasoning: change detection. First document the desired ownership and path boundaries in the delivery catalog; then add path filters only if the cost is recurring and visible.

  3. A production deploy finishes, but an auth smoke check proves private data is reachable without authorization. Which pattern helps the operator recover?

    Expected reasoning: rollback. The system needs a known good artifact or deployment history, a decision owner, and a recovery smoke check. The failed smoke check is observability, but the recovery move is rollback.

  4. A new service team asks for “the standard way” to create CI, staging, production approval, secrets, and smoke checks. Which pattern should the delivery platform provide?

    Expected reasoning: self-service templates. The platform should expose the catalog shape as an approved starting point before building a full generator.

  5. Someone proposes adopting a controller because it sounds more professional, but all current deploys are static Pages publishes with simple smoke checks. Should this module recommend that now?

    Expected reasoning: no. Deployment controllers solve rollout, convergence, drift, and rollback problems for running services. The current delivery paths do not yet show enough pain to justify that tool.