ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
201
docs/spec/project-delivery-spec.md
Normal file
201
docs/spec/project-delivery-spec.md
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
# 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
|
||||
|
||||
```mermaid
|
||||
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
|
||||
```
|
||||
|
||||
```yaml
|
||||
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:
|
||||
|
||||
```yaml
|
||||
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](project-delivery/ProjectDelivery.tla) | Attempt eligibility and history, controller submission, Argo execution synchronization, persistence, lifecycle, and build concurrency |
|
||||
| [Qualification state model](project-delivery/Qualification.tla) | 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.
|
||||
|
||||
```mermaid
|
||||
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 |
|
||||
Loading…
Reference in a new issue