Architecture
Design principles
- Opt-in reporting - only workloads with
github-deployment-bridge.io/auto-report=trueare reported; others are skipped quietly. - OCI labels are canonical for build metadata - repository and commit come from standard image labels.
- Kubernetes annotations are optional overrides - deployment-specific environment, URLs, and opt-outs.
- Zero per-app mapping database - no repository-specific configuration beyond annotations on the workload.
- Observe only - the bridge never triggers deployments or mutates cluster workloads.
- Full GitHub Deployments lifecycle - one Deployment per
(owner, repo, environment, commit, deploymentName)with status updates as Flux progresses. - Safe reconcile loop - missing/invalid metadata skips a workload with a warning; transient GitHub/OCI errors retry with backoff (GitHub
Retry-After/ rate-reset honored). - Single-writer cache - SQLite on a PVC is the intentional HA model: one replica, Recreate upgrades, node loss means reschedule downtime (not active-active). Multi-writer would require a different store.
Flux sources
The bridge watches:
Events fire when conditions, observedGeneration, or revision fields change. Reporting runs only when inventory yields at least one resolvable workload image.
Phase derivation
The reporter maps desired phases onto GitHub statuses with an idempotent state machine:
- Catch-up: if the cache is empty and Flux is already terminal, emit only that terminal status (no synthetic history).
- Early states:
queuedthenin_progresswhen first observing an in-progress reconcile for a new commit. - Never transition
success→in_progress. Never send duplicate identical statuses.
Workload discovery
- Parse
.status.inventoryforDeployment,StatefulSet, andDaemonSet. - Resolve
ReplicaSetentries via owner references to their controllingDeployment. - Ignore
Job/CronJob. - Collect
github-deployment-bridge.io/*annotations from the workload (and pod template as fallback).
Empty inventory (including HelmRelease on Flux before 2.8) → skip.
Metadata resolution
Priority for every field:
- Kubernetes annotation
- OCI label
- Controller default (if applicable)
OCI labels
*Required unless overridden by the matching Kubernetes annotation.
Kubernetes annotations
Prefix: github-deployment-bridge.io/
Validation
Missing or invalid required metadata → skip reporting and emit a warning. Never fail reconciliation for that reason.
GitHub Deployment mapping
Deployment payload includes cluster, namespace (workload), sourceNamespace (Flux
Kustomization / HelmRelease namespace), source name (kustomization / helmRelease),
deploymentName, image, optional digest / version, controllerVersion, and any
optional annotation fields (team, service, component, slackChannel, owner,
release, tag). The cluster annotation overrides the controller CLUSTER_NAME env.
Crash recovery also matches older payloads that used the Flux source namespace as
namespace and omitted sourceNamespace.
Status updates set auto_inactive=true. When a newer commit reaches success for the same identity, prior cached success deployments are explicitly marked inactive.
Deduplication cache key: (owner, repo, environment, commitSHA, deploymentName). Before creating a Deployment, the bridge writes a provisional cache row (deployment_id=0). It then searches GitHub for an existing Deployment with the same ref, environment, and payload (crash recovery) and only creates when none is found. The resolved deployment_id is persisted before status updates.