Outer delivery loop (PR → merge → GitOps → reconcile)

Take the Crossplane XR the hand-off produced and drive it through a real GitHub PR, a real merge, and a GitOps sync onto the Crossplane cluster from the Hello Pico on Kubernetes lab.

See the Open Engineering Language Server (OELS) onboarding guide for the local install and editor setup.

TipOELS in your editor

While you work through this content, keep the Open Engineering Language Server (OELS) active in VS Code (or any LSP-capable editor). See the OELS onboarding guide linked at the top of this page (also linked from the academy Resources page) for the one-time install and configuration steps.

What OELS validates. OELS only recognizes OE-shaped YAML/JSON: files with a mapping root that declare an apiVersion beginning with open-engineering.io/, a non-empty kind, and a DNS-1123 metadata.name. Ordinary academy metadata.yaml, Quarto/QMD pages and front matter, Kubernetes/Crossplane/runtime manifests, JSON payload samples, and shell scripts are intentionally non-OE — OELS ignores them silently and you should not add synthetic apiVersion/kind headers to force recognition.

Where you see diagnostics. OELS surfaces UnknownProperty, MissingRequiredProperty, IncorrectType, InvalidEnumValue, MalformedIdentifier, UnknownDefinition, and reference-shape hints in the editor Problems panel as you type. These are independent of quarto render: OELS diagnostics do not block rendering, and Quarto errors do not appear in the Problems panel.

The executable check still comes from this exercise. OELS speeds up editing, but the exercise’s own parser, verifier, or verify.sh (for example the pico parse … command shown below) remains the authoritative success check. Run it as usual.

Overview

Outer delivery loop is the first runnable Sandcastle lab that exercises the four stages that begin exactly where the Sandcastle ends:

  1. Review / PR — the durable Sandcastle branch (materialised as an XR by the hand-off lab) is pushed to a real GitHub environment repository and opened as a pull request.
  2. Merge — the PR is merged, moving the environment repo’s source of truth forward.
  3. GitOps delivery — a reconciler (Flux by default, kubectl fallback) pulls the merged XR onto the target cluster.
  4. Downstream Crossplane reconciliation — Crossplane composes the XR into the Kubernetes Job that prints Hello, Pico!.

The whole loop runs against live GitHub and, when a cluster is available, against a live Crossplane installation from the Hello Pico on Kubernetes lab. The Sandcastle is not re-invoked at any stage — the merged branch is the outer loop’s only interface back.

This lab is deliberately scoped to the loop itself. The construction stage is verified by the Sandcastle lab, the promotion into a Crossplane XR is verified by the hand-off lab, and the downstream reconcile is verified by the Hello Pico on Kubernetes lab.

Structure

What you will produce

  • A real GitHub pull request on your environment repository whose head branch carries the hand-off’s xr.yaml at envs/dev/xr.yaml and whose base is the repo’s default branch.
  • A merge commit on the environment repo’s default branch that becomes the source of truth for the XR.
  • Either a Flux GitRepository + Kustomization pair reconciling the merged path, or a kubectl apply from a fresh clone of the merged branch — both drive hello-world-pico-on-kubernetes-xr onto the cluster in the same shape the Hello Pico on Kubernetes lab reconciles it in isolation.

Downloads and screenshots

Runnable files live under downloads/:

  • push-branch.sh — pushes the hand-off’s XR to a feature branch on your GitHub env repo.
  • open-pr.sh — opens the PR via gh.
  • merge-pr.sh — merges the PR via gh.
  • gitops-sync.sh — reconciles the merged XR onto the cluster (Flux mode, kubectl fallback).
  • verify.sh — automatable end-to-end check for the whole loop. Skips cluster stages if no cluster is reachable (or force with --with-cluster / --skip-cluster).

Metadata

Machine-readable descriptor: metadata.yaml. Fields follow the same schema as labs/hello-pico/metadata.yaml.

Referenced from