2026-11-01 17:44:47 +00:00
|
|
|
# Roadmap: forge delivery boundary and credential preflight
|
2026-11-01 16:23:58 +00:00
|
|
|
|
2026-11-01 16:37:50 +00:00
|
|
|
Status: accepted; implementation has not started.
|
|
|
|
|
|
|
|
|
|
The [implementation plan](implementation.md) owns stages, concrete design
|
|
|
|
|
choices, task sequencing, and verification.
|
2026-11-01 16:23:58 +00:00
|
|
|
|
|
|
|
|
## Objective and scope
|
|
|
|
|
|
|
|
|
|
Introduce an internal boundary between shared hosted-release delivery and the
|
|
|
|
|
Gitea implementation. The result should support adding another forge through
|
|
|
|
|
an adapter while reusing ReleaseKit's release and asset-delivery policy.
|
2026-11-01 17:44:47 +00:00
|
|
|
Add operation-specific credential preflight through that boundary so delivery
|
|
|
|
|
stops on credential problems before expensive preparation or builds.
|
2026-11-01 16:23:58 +00:00
|
|
|
|
|
|
|
|
ReleaseKit's `Publish` operation validates and publishes source through Git.
|
|
|
|
|
Its `Deliver` operation verifies tagged source and delivers release notes and
|
|
|
|
|
declared assets to a hosting service. This refactor concerns the latter operation
|
|
|
|
|
and its composition through the existing public facade and CLI.
|
|
|
|
|
|
|
|
|
|
Gitea is the concrete backend for this work. Forgejo, GitHub, GitLab, and other
|
|
|
|
|
backends remain future implementation work. The boundary should express the
|
|
|
|
|
operations used by the current delivery workflow and allow refinement when a
|
|
|
|
|
second backend supplies concrete requirements.
|
|
|
|
|
|
|
|
|
|
## Current baseline
|
|
|
|
|
|
|
|
|
|
The source baseline is `ac78e7d`, following the published v0.5.0 module migration
|
|
|
|
|
and the subsequent token-file and forbidden-file changes.
|
|
|
|
|
|
|
|
|
|
- [delivery.go](../../delivery.go) exposes `GiteaDestination` through
|
|
|
|
|
`DeliveryRequest.Destination` and converts it into `gitea.Destination`.
|
|
|
|
|
- [internal/delivery](../../internal/delivery/delivery.go) resolves source
|
|
|
|
|
identity, checks tagged source, reads notes, coordinates builds, and directly
|
|
|
|
|
calls `gitea.Client` for release and asset operations. Its result conversion
|
|
|
|
|
and failure classification use Gitea-owned internal types.
|
|
|
|
|
- [release.go](../../internal/gitea/release.go) combines Gitea HTTP operations
|
|
|
|
|
with hosted-tag verification, matching-page acceptance, release creation,
|
|
|
|
|
and reconciliation of ambiguous creates.
|
|
|
|
|
- [assets.go](../../internal/gitea/assets.go) and
|
|
|
|
|
[upload.go](../../internal/gitea/upload.go) combine HTTP operations with
|
|
|
|
|
manifests, local-file verification, remote-content comparison, asset
|
|
|
|
|
observations, upload sequencing, and retry bookkeeping.
|
|
|
|
|
- CLI credential resolution supplies an explicit token from the configured
|
|
|
|
|
environment variable or token file. The profile describes a Gitea repository;
|
|
|
|
|
it has no forge selector.
|
2026-11-01 17:44:47 +00:00
|
|
|
- CLI loading checks token availability, but forge API authentication first occurs
|
|
|
|
|
through delivery requests after application dependency preparation and managed
|
|
|
|
|
builds. Library delivery also checks a blank token only at the later Gitea
|
|
|
|
|
request boundary. There is no dedicated authenticated credential preflight.
|
2026-11-01 16:23:58 +00:00
|
|
|
|
|
|
|
|
The [Gitea integration guide](../integrations/gitea.md) and public Go declarations
|
|
|
|
|
document the baseline contracts. Current behavioral tests provide regression
|
|
|
|
|
coverage to assess against those contracts. The
|
|
|
|
|
[architecture policy](../policy/architecture.md) governs facade ownership and
|
|
|
|
|
dependency direction.
|
|
|
|
|
|
|
|
|
|
## Targeted end state
|
|
|
|
|
|
2026-11-01 16:25:54 +00:00
|
|
|
### Neutral public destination and explicit forge selection
|
|
|
|
|
|
2026-11-01 16:37:50 +00:00
|
|
|
Replace `GiteaDestination` with a facade-owned neutral destination type and
|
|
|
|
|
require explicit forge selection in the public API and delivery configuration.
|
|
|
|
|
Gitea is the sole supported selection initially.
|
2026-11-01 16:25:54 +00:00
|
|
|
An omitted, blank, or unsupported selection produces a validation error; Gitea
|
|
|
|
|
is selected explicitly rather than inferred from a default or destination URL.
|
|
|
|
|
|
|
|
|
|
The destination represents the addressing and credentials needed for current
|
|
|
|
|
delivery through neutral public names. Concrete backend construction uses the
|
|
|
|
|
selected forge. Additional backends may extend that model when their addressing
|
|
|
|
|
and protocol requirements are implemented.
|
|
|
|
|
|
2026-11-01 16:23:58 +00:00
|
|
|
### Shared delivery responsibilities
|
|
|
|
|
|
|
|
|
|
Shared internal code owns:
|
|
|
|
|
|
2026-11-01 17:44:47 +00:00
|
|
|
- Automatic credential preflight coordination before expensive delivery work.
|
2026-11-01 16:23:58 +00:00
|
|
|
- Captured source identity, local tag/commit checks, committed release notes,
|
|
|
|
|
managed or prebuilt artifact coordination, and local artifact verification.
|
|
|
|
|
- The existing logical rules for accepting matching hosted content, reporting
|
|
|
|
|
conflicts, creating missing content, and reconciling uncertain writes.
|
|
|
|
|
- Manifest generation, content comparison, and asset observations used to decide
|
|
|
|
|
which declared assets require delivery.
|
|
|
|
|
- Aggregation into the existing public delivery outcomes and asset categories.
|
|
|
|
|
|
|
|
|
|
These operations consume backend-neutral internal values and operations. The
|
|
|
|
|
generic delivery workflow has no dependency on `internal/gitea`. The facade or
|
|
|
|
|
private composition code constructs the concrete backend and supplies it to
|
|
|
|
|
shared delivery.
|
|
|
|
|
|
2026-11-01 17:44:47 +00:00
|
|
|
### Credential preflight
|
|
|
|
|
|
|
|
|
|
Delivery automatically checks the credentials required for its selected backend.
|
|
|
|
|
Local checks establish availability and valid destination settings; a read-only
|
|
|
|
|
backend probe establishes authentication and access to the configured repository.
|
|
|
|
|
Reliable evidence of insufficient required permissions stops the operation.
|
|
|
|
|
Unexposed permissions remain unverified; successful reads establish no blanket
|
|
|
|
|
guarantee that later writes will succeed. Preflight performs no test writes and
|
|
|
|
|
preserves ordinary delivery authorization and recovery handling.
|
|
|
|
|
|
|
|
|
|
Library and ordinary CLI delivery perform preflight before managed builds and
|
|
|
|
|
full artifact verification. CI loads the verified tagged profile first, then
|
|
|
|
|
performs preflight before application dependency preparation. A callable facade
|
|
|
|
|
operation lets consumers check a destination before their own preparation,
|
|
|
|
|
without requiring a release tag or note to exist.
|
|
|
|
|
|
|
|
|
|
Failures distinguish missing or rejected credentials, insufficient permissions,
|
|
|
|
|
an inaccessible destination, and unavailable or unverifiable service responses.
|
|
|
|
|
Delivery reports `not_attempted` for these pre-write failures. Diagnostics retain
|
|
|
|
|
useful causes while excluding tokens. Each check describes access at that time;
|
|
|
|
|
later operations retain their normal checks.
|
|
|
|
|
|
|
|
|
|
Required credentials follow operation scope. Candidate checking and standalone
|
|
|
|
|
builds remain credential-free. Source publication continues using Git's native
|
|
|
|
|
SSH/HTTPS authentication and existing remote guards, independently of hosted
|
|
|
|
|
delivery credentials. This feature adds no Gitea-token requirement to `Publish`.
|
|
|
|
|
|
2026-11-01 16:23:58 +00:00
|
|
|
### Backend responsibilities
|
|
|
|
|
|
|
|
|
|
The Gitea adapter owns destination validation specific to Gitea, API routes,
|
|
|
|
|
authentication headers, request and response formats, pagination, multipart
|
|
|
|
|
uploads, attachment downloads, and HTTP-specific error interpretation.
|
2026-11-01 17:44:47 +00:00
|
|
|
It also owns authenticated credential probes and interpretation of available
|
|
|
|
|
permission evidence, using repository-scoped checks without requiring unrelated
|
|
|
|
|
account or administration scopes.
|
|
|
|
|
|
|
|
|
|
The internal contract supplies the logical operations needed to preflight
|
|
|
|
|
credentials, inspect a hosted tag, find or create a release, enumerate assets,
|
|
|
|
|
read asset content, and upload an asset. Release and asset references carry
|
|
|
|
|
backend-owned handles; shared orchestration works with logical identity and content rather than
|
2026-11-01 16:23:58 +00:00
|
|
|
interpreting Gitea's positive integer IDs.
|
|
|
|
|
|
|
|
|
|
The contract also carries the evidence needed for existing recovery behavior:
|
|
|
|
|
whether a write was attempted, whether its outcome is established or uncertain,
|
|
|
|
|
and actionable failure information. Generic code interprets delivery outcomes;
|
|
|
|
|
the adapter interprets protocol responses. A logical backend operation may
|
|
|
|
|
involve multiple HTTP requests.
|
|
|
|
|
|
|
|
|
|
The operations and values stay internal under the existing facade policy.
|
|
|
|
|
Current Gitea behavior is the concrete compatibility target. This work does
|
|
|
|
|
not establish compatibility guarantees for unimplemented forges or a public
|
|
|
|
|
plugin protocol.
|
|
|
|
|
|
2026-11-01 16:37:50 +00:00
|
|
|
## Behavioral scope and compatibility
|
|
|
|
|
|
|
|
|
|
The refactor preserves the existing Gitea delivery contracts for complete note
|
|
|
|
|
bodies, retained existing titles, stable release state, content conflicts,
|
|
|
|
|
unrelated attachments, additive retries, and source-only or binary delivery.
|
|
|
|
|
Read-only inspection failures and unresolved writes retain their distinct
|
|
|
|
|
outcomes. Recovery retains write history, including confirmed progress after
|
|
|
|
|
an ambiguous create. The current integration guide owns the concrete protocol
|
|
|
|
|
and follow-up lookup behavior.
|
|
|
|
|
|
|
|
|
|
Local verification reuse, streaming, cancellation, stream closure, temporary
|
|
|
|
|
build ownership, and upload cleanup remain part of the affected workflow.
|
2026-11-01 17:44:47 +00:00
|
|
|
Read-only credential preflight precedes expensive local artifact work; local
|
|
|
|
|
content verification still completes before hosted release or asset writes.
|
2026-11-01 16:37:50 +00:00
|
|
|
Credential environment/file selection and forbidden-file validation retain
|
|
|
|
|
their existing responsibilities. Backend-specific address validation stays
|
|
|
|
|
with that backend.
|
|
|
|
|
|
2026-11-01 17:44:47 +00:00
|
|
|
The public destination replacement, required forge selection, and earlier
|
|
|
|
|
credential failures are deliberate changes for the next minor release.
|
|
|
|
|
Migration guidance describes consumer edits under the project's direct-cutover
|
|
|
|
|
approach.
|
2026-11-01 16:37:50 +00:00
|
|
|
Current contract documents and examples change with implementation; historical
|
|
|
|
|
release notes retain their original contents.
|
|
|
|
|
|
|
|
|
|
Completion means shared delivery and asset policy have independent internal
|
|
|
|
|
ownership, Gitea implements the backend boundary, existing Gitea contracts work
|
|
|
|
|
through it, and the neutral public destination and explicit selection are
|
|
|
|
|
consistent across the API, configuration, examples, and documentation.
|
2026-11-01 17:44:47 +00:00
|
|
|
Credential preflight operates through the backend boundary in both library and
|
|
|
|
|
CLI delivery, with accurate failure distinctions and documented permission limits.
|
2026-11-01 16:37:50 +00:00
|
|
|
|
|
|
|
|
Additional forge implementations and compatibility claims belong to later work.
|
|
|
|
|
Release preparation and publication continue under the
|
|
|
|
|
[existing procedure](../release.md).
|