14 KiB
Project Delivery Specification
Project delivery reconciles Forgejo source into published artifacts. A ProjectDelivery declares the desired result, a controller resolves continuous refs and accepts declared point revisions, and a cluster-owned Argo WorkflowTemplate defines all execution.
Delivery declaration
flowchart LR
D[ProjectDelivery]
C[Delivery controller]
T[Cluster-owned WorkflowTemplate]
W[Workflow]
V[Vault and VSO]
A[Build cache]
P[Declared publication targets]
D --> C
C -->|template reference and immutable input| W
T --> W
V -->|stage-scoped Secrets| W
W <-->|cache pull, export, and cleanup| A
W --> P
apiVersion: delivery.quorate.dev/v1alpha1
kind: ProjectDelivery
metadata:
name: example
spec:
source:
repository: https://git.quorate.dev/example/project
continuous:
ref: refs/heads/main
paths: [packages/example]
targets:
- kind: QuayOCI
repository: quorate/project
- kind: ExternalOCI
registry: docker.io
repository: example/project
- kind: ForgejoRelease
repository: https://git.quorate.dev/example/project
workflowTemplateRef:
name: example-delivery
source contains exactly one delivery mode:
| Mode | Selector | Trigger identity |
|---|---|---|
continuous |
One complete ref; optional exact paths and positive-duration debounce | Commit SHA or selected Git tree |
point |
A non-empty set of full commit SHAs | Full commit SHA |
continuous.paths contains exact repository-relative file or directory paths. When present, the trigger identity is the selected Git tree state rather than the commit SHA.
Point delivery declares immutable revisions:
source:
repository: https://git.quorate.dev/example/project
point:
revisions:
- 0123456789abcdef0123456789abcdef01234567
- 89abcdef0123456789abcdef0123456789abcdef
status.points records point revisions, Workflow identities and phases, and delivery results.
Point revisions are consumed directly without ref enumeration or resolution.
source.repository identifies the Forgejo repository containing the selected source. Its authority is declaration data rather than an admission boundary.
targets is a non-empty set of workflow-defined publication declarations. The controller treats each declaration as opaque JSON and passes it unchanged. The referenced WorkflowTemplate defines and validates the target kinds and fields it supports.
workflowTemplateRef names a WorkflowTemplate in the ProjectDelivery namespace. Admission rejects cross-namespace references and malformed source selectors.
delivery.quorate.dev/retry names an owned terminal Workflow.
Qualification interface
| Field | Type | Default | Model binding |
|---|---|---|---|
spec.qualification |
Optional object | Absent | Configured resources form Deliveries |
workflowTemplateRef.name |
Same-namespace WorkflowTemplate name | Required | Workflow template |
mode |
Qualification!Policies |
ManualOnly |
policy[delivery] |
interval |
Duration | 0s |
Interval[delivery] |
delivery.quorate.dev/qualify annotation |
<build-workflow-name>/<request-id> |
Absent | request[delivery] |
| Workflow interface | Value |
|---|---|
Input: source-repository, source-ref, source-revision, targets |
Selected successful build's parameters |
Input: delivery-result |
Selected build's opaque publication result |
Model Input(delivery, build) |
Tuple of those parameters and publication result |
Output: qualification-result |
Workflow-defined result identifying tested source, artifacts, and retained reports |
| Result interpretation | Qualification WorkflowTemplate |
Reconciliation and execution
Authority
| Artifact | Authority |
|---|---|
| Project Delivery specification | Declaration and status schema, Workflow interface, objectives, and security |
| Project Delivery state model | Attempt eligibility and history, controller submission, Argo execution synchronization, persistence, lifecycle, and build concurrency |
| Qualification state model | Qualification eligibility, annotation consumption, input capture, interval, and global execution slot |
Build workflow interface
The diagram is the standard ProjectDelivery build workflow DAG shape; deviation from it requires evidence that substantiates the deviation.
flowchart LR
T[Toolchain pull] --> B[Build]
C[Cache pull] --> B
S[Source pull] --> B
B --> E[Cache export and cleanup]
B --> P[Publish to declared targets]
| Parameter | Value |
|---|---|
source-repository |
Declared repository URL |
source-ref |
Complete selected continuous ref, or empty for point delivery |
source-revision |
Resolved full commit SHA |
targets |
Declaration-provided JSON target set |
Delivery objectives
Measure delivery elapsed time from Workflow startedAt to terminal finishedAt, excluding intervals when waiting on WAN is the sole active work.
| Cache state | Requirement |
|---|---|
| Cold | No reusable build state; within 900 seconds. |
| Warm | Reusable build state; within 300 seconds. |
The WorkflowTemplate owns the DAG:
| Concern | Owner |
|---|---|
| Stages, actions, dependencies, retries | Argo WorkflowTemplate |
| Build and assembly image selection | Argo WorkflowTemplate |
| Action and builder image preparation | Cluster |
| Stage Secret references | Argo WorkflowTemplate |
| Secret material and projection | Vault and VSO |
| Stage egress | Kubernetes NetworkPolicy |
| Continuous source selection and duplicate suppression | Delivery controller |
| Cache creation, invalidation, cleanup, and layout | Argo WorkflowTemplate |
| Cache contract | Value |
|---|---|
| Prefix | projects/<project>/<workflow>/cache/<cache>/ |
| Manifest | _latest.json |
| Pull | cacheVersion and inputHashes match |
| Export | Replace _latest.json |
| Cleanup | Remove unreferenced payloads during cache export |
| Controller | No cache inspection or enforcement |
_latest.json field |
Type | Value |
|---|---|---|
schemaVersion |
Integer | 1 |
cacheVersion |
String | Workflow cache version |
inputHashes |
Object | Repository-relative path to SHA-256 map |
payloadKey |
String | objects/<payload-sha256>.tar.zst |
Workflow security requirements
Every delivery WorkflowTemplate and its supporting namespace resources meet these requirements:
| Boundary | Requirement |
|---|---|
| Ownership | Commands, images, target interpretation, Secret references, and pod security are cluster-owned |
| Supply chain | Action and executor images use immutable digests of latest stable releases; deprecated APIs and components are forbidden; source uses the selected full SHA |
| Runtime | gvisor where non-cluster-owned code executes; restricted Pod Security; non-root; RuntimeDefault; no privilege escalation or capabilities; read-only root filesystem |
| Host | No privileged container, host namespace, hostPath, device, or runtime socket |
| Kubernetes | Action containers receive no Kubernetes credential; executor tokens are bound, short-lived, and limited to Workflow task results and artifact GC |
| Delivery stages | A stage is a Pod boundary only when its network, credential, input, or output access differs. Actions with identical access execute in the same Pod. |
| Network | Default deny; each stage permits only executor traffic, artifact handoff, and its declared endpoints |
| Credentials | Vault to VSO to one read-only stage mount; never parameters, environment, commands, logs, or artifacts |
| Handoff | Stages exchange state through the Workflow PVC; publishers transfer immutable output |
| Cache | Cache reads and writes use stage-scoped credentials |
| Ephemeral state | One ephemeral PVC is the sole working data plane for the build Workflow lifetime |
| Build interface | Repository supplies source only; OCI delivery uses cluster-owned apko configuration |
| Resources | CPU requests, memory requests, and memory limits on every pod |
Publication credentials are destination-native, restricted to the declared destination, and mounted only in the publication stage.
Project-delivery credentials are never shared with Smeltery.
Scope
Delivery succeeds when every declared target reports successful publication of the Workflow's immutable output.
| Included | Excluded |
|---|---|
| Source-ref observation and immutable revision selection | Repository visibility |
| Duplicate suppression and Workflow creation | Vulnerability policy and scan gating |
| Project-specific build, test, assembly, and publication DAGs | Candidate repositories and promotion |
| Manual and interval-controlled qualification of published artifacts | Deployment approval and rollout gating |
| Publication digests, checksums, URLs, and Workflow status | Deployment and Flux manifest changes |
| Stage isolation, credentials, and network policy | Per-repository publisher identities and grants; published artifact retention and registry garbage collection |