E2E
The E2E framework verifies that a pattern works against a real cluster before it is published. When e2e.yaml is present in a pattern directory, ork push runs it automatically and blocks publication if any expectation fails.
For the complete field reference —
setup,expect,cluster,commands— see the E2E schema.
E2E status in ork patterns
ork patterns
Orkestra Registry
─────────────────────────────────────────────────────────────
NAME LATEST KIND E2E TAGS DESCRIPTION
postgres v1.0.0 Katalog ✓ postgres, database,... A declarative PostgreSQL de...
kafka v1.0.0 Katalog ✓ kafka, messaging, s... A declarative Apache Kafka ...
redis v1.0.0 Katalog ✓ redis, cache, key-v... A declarative Redis deploym...
deployment-stack v1.0.0 Katalog ✗ deployment, service... A declarative application d...
The E2E column shows ✓ when the published artifact carries io.orkestra.e2e.status=passed. ✗ means no E2E was run or it was force-pushed. Consumers can filter to verified patterns only:
ork patterns --e2e-passed
How it gates publication
# E2E runs automatically if e2e.yaml is present
ork push postgres:v14 ./patterns/postgres/
# Skip the gate — use --force
ork push postgres:v14 ./patterns/postgres/ --force
Whether the gate passed, was skipped, or was force-overridden, the result is baked into the OCI artifact as annotations:
io.orkestra.e2e.status passed | skipped | forced
io.orkestra.e2e.duration 45s
io.orkestra.e2e.tested_at 2026-05-24T10:00:00Z
io.orkestra.e2e.runner local | github-actions | gitlab-ci
ork inspect and ork patterns show this status for every pattern — a ✓ passed (45s · tested 2h ago) gives consumers confidence before they import.
Running E2E locally
Pull a pattern and run its E2E before importing it:
ork pull postgres:v14
ork e2e --file ~/.orkestra/registry/ghcr.io/orkestra-registry/postgres/v14/e2e.yaml
Or run against a pattern you are developing locally:
ork e2e --file ./patterns/postgres/e2e.yaml
By default, ork e2e provisions a temporary kind cluster, runs all expectations, then tears it down. Use --cluster to run against an existing kubeconfig context:
ork e2e --file ./e2e.yaml --cluster my-dev-context
e2e.yaml — pattern shape
A minimal E2E for a registry pattern. The setup block applies prerequisite namespaces or secrets before the operator starts; wait ensures they exist before the CR is applied.
apiVersion: orkestra.orkspace.io/v1
kind: E2E
metadata:
name: postgres-e2e
description: Verify the postgres pattern creates a StatefulSet and headless Service
spec:
katalog: ./katalog.yaml
crd: ./crd.yaml
cr: ./cr.yaml
cluster:
provider: kind
name: ork-e2e
reuse: false
setup:
apply:
- ./prereqs/namespace.yaml # target namespace
wait:
- kind: Namespace
name: databases
timeout: 10s
expect:
- name: StatefulSet ready
after: cr-applied
timeout: 120s
resources:
- kind: StatefulSet
name: my-postgres
namespace: databases
ready: true
- name: Service exists
after: cr-applied
timeout: 30s
resources:
- kind: Service
name: my-postgres
namespace: databases
- name: Cleanup verified
after: cr-deleted
timeout: 30s
resources:
- kind: StatefulSet
name: my-postgres
namespace: databases
count: 0
→ Full field reference: E2E schema
Testing a multi-operator pattern
When a pattern contains more than one Katalog — a Komposer that imports several sources — one E2E per sub-Katalog keeps each test small and focused. A suite file at the category root imports them all, so a single ork e2e verifies the whole pattern before publication.
Layout in a registry pattern directory:
multi-tenancy/
komposer.yaml
e2e.yaml ← suite (pure aggregator)
01-basic-namespacing/
katalog.yaml crd.yaml cr.yaml e2e.yaml
02-cross-access-control/
katalog.yaml crd.yaml cr.yaml e2e.yaml
03-shared-platform/
katalog.yaml crd.yaml cr.yaml e2e.yaml
The suite file:
apiVersion: orkestra.orkspace.io/v1
kind: E2E
metadata:
name: multi-tenancy-suite
description: >
Runs all three multi-tenancy sub-examples in the same cluster.
imports:
- ./01-basic-namespacing/e2e.yaml
- ./02-cross-access-control/e2e.yaml
- ./03-shared-platform/e2e.yaml
ork push discovers e2e.yaml at the pattern root and runs it. The suite provisions one cluster and runs each import in it sequentially — three sub-tests for the cost of one cluster lifecycle.
ork validate -f e2e.yaml reports each import with a ✓ before any cluster is involved:
✓ multi-tenancy-suite
imports : 3 file(s)
✓ ./01-basic-namespacing/e2e.yaml
✓ ./02-cross-access-control/e2e.yaml
✓ ./03-shared-platform/e2e.yaml
3 import(s) valid
→ Full field reference: imports schema
E2E in CI
The io.orkestra.e2e.runner annotation records the environment. When ork push runs inside GitHub Actions, it records github-actions. Consumers can see that the pattern was verified in CI, not just locally.
Use --no-e2e to skip the gate in CI steps that only build artifacts without running tests:
ork push postgres:v14 ./patterns/postgres/ --no-e2e