93 lines
4.5 KiB
Markdown
93 lines
4.5 KiB
Markdown
# ADR 0006: Separate delivery policy from forge protocols
|
|
|
|
## Status
|
|
|
|
Accepted.
|
|
|
|
## Date
|
|
|
|
2026-11-01
|
|
|
|
## Context
|
|
|
|
ReleaseKit's delivery workflow handles release-page matching and creation
|
|
recovery, remote asset comparison, upload ordering, retries, and partial or
|
|
uncertain outcomes. Those policies are useful independently of the Gitea HTTP
|
|
protocol, but the earlier client-owned flow coupled them to Gitea types and
|
|
operations.
|
|
|
|
Delivery also benefits from checking credentials and repository access before
|
|
managed builds, dependency preparation, or complete artifact hashing. Gitea
|
|
exposes authenticated repository reads, but its `permissions.push` metadata and
|
|
basic token evidence do not establish permission to write release pages or
|
|
assets. A read-only check must represent that evidence limit without claiming
|
|
that later writes are guaranteed.
|
|
|
|
The root `releasekit` facade owns public types, while implementation packages
|
|
remain internal. The CLI owns credential loading and process exit status.
|
|
Source publication has separate Git authentication and completion semantics.
|
|
|
|
## Decision
|
|
|
|
The root facade owns `Forge`, `DeliveryDestination`, explicit backend selection,
|
|
and public preflight errors. `internal/forge` defines the internal backend
|
|
contract and neutral release, asset, failure, and write-evidence values.
|
|
`internal/delivery` owns shared delivery coordination and policy.
|
|
`internal/gitea` owns Gitea destination rules, authenticated preflight requests,
|
|
protocol operations, codecs, handles, streaming, and conversion to neutral
|
|
failures. `internal/artifact` owns local asset declarations and verification.
|
|
Shared delivery, forge, and artifact packages have no production dependency
|
|
path to the Gitea adapter.
|
|
|
|
Delivery selection is explicit. The supported value is `gitea`; neither a URL
|
|
nor an omitted selection chooses a backend. There is no compatibility alias for
|
|
the removed public Gitea destination type.
|
|
|
|
The facade exposes `PreflightDelivery` and runs the same read-only backend
|
|
preflight automatically during `Deliver`. Gitea preflight authenticates through
|
|
repository-scoped reads and classifies missing or rejected credentials,
|
|
inaccessible destinations, and unavailable verification. It does not issue a
|
|
test release or upload, require extra user/admin token scopes, or treat
|
|
unexposed write permission evidence as a failure. Success confirms only the
|
|
authentication, repository access, and permission evidence available through
|
|
that check; ordinary writes remain authoritative. Preflight failures preserve
|
|
their causes and leave delivery `not_attempted`.
|
|
|
|
The CLI requires `delivery.forge` only for `deliver` and `ci-deliver`. Binary
|
|
CI delivery performs a standalone preflight after checkout/profile/token
|
|
preparation and before application dependency downloads, then `Deliver`
|
|
rechecks. Page-only CI relies on automatic delivery preflight. `check`,
|
|
`build`, and source `publish` do not require delivery configuration or hosted
|
|
credentials. Local artifact verification follows preflight but completes before
|
|
hosted writes.
|
|
|
|
## Alternatives considered
|
|
|
|
- Keep delivery policy in the Gitea client. This retains protocol coupling and
|
|
makes shared recovery behavior harder to exercise without the adapter.
|
|
- Select Gitea from the URL or preserve the old Gitea-specific facade type.
|
|
This hides backend selection and keeps the public contract tied to one
|
|
adapter.
|
|
- Probe permissions with a test release or asset, or require additional user
|
|
scopes. Those operations can create remote state or demand evidence unrelated
|
|
to release delivery; the repository read does not expose the required
|
|
release-write proof.
|
|
- Skip preflight and let the first write discover credential problems. That
|
|
delays a known failure until after costly local work and provides no
|
|
standalone check for callers preparing their own delivery.
|
|
|
|
## Consequences
|
|
|
|
- Shared policy can be tested with controlled backends, while local HTTP tests
|
|
focus on Gitea protocol behavior and assembled integration flows.
|
|
- Consumers must replace the removed Gitea-specific destination type, set
|
|
`ForgeGitea` in API calls, and add `"forge": "gitea"` to delivery profiles.
|
|
- Delivery may make additional authenticated read requests before local
|
|
artifact hashing. It still verifies full local content before any hosted
|
|
write.
|
|
- Credential, access, and availability failures have distinct public error
|
|
kinds and CLI classifications. Successful preflight does not certify future
|
|
release or asset writes.
|
|
- Source publication retains native Git authentication and is not gated by
|
|
hosted delivery preflight.
|