9.6 KiB
Roadmap: forge delivery boundary and credential preflight
Status: implementation complete; review corrections are tracked in remediation.
The implementation plan owns stages, concrete design choices, task sequencing, and verification.
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. Add operation-specific credential preflight through that boundary so delivery stops on credential problems before expensive preparation or builds.
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.
Historical planning baseline
The original source baseline was ac78e7d, following the published v0.5.0
module migration and the subsequent token-file and forbidden-file changes.
The following describes that revision, before implementation of this roadmap.
- delivery.go exposes
GiteaDestinationthroughDeliveryRequest.Destinationand converts it intogitea.Destination. - internal/delivery resolves source
identity, checks tagged source, reads notes, coordinates builds, and directly
calls
gitea.Clientfor release and asset operations. Its result conversion and failure classification use Gitea-owned internal types. - release.go combines Gitea HTTP operations with hosted-tag verification, matching-page acceptance, release creation, and reconciliation of ambiguous creates.
- assets.go and 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.
- 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.
The Gitea integration guide and public Go declarations now describe the implemented contracts. Behavioral tests provide regression coverage for the selected behavior. The architecture policy governs facade ownership and dependency direction.
Targeted end state
Neutral public destination and explicit forge selection
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.
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.
Shared delivery responsibilities
Shared internal code owns:
- Automatic credential preflight coordination before expensive delivery work.
- 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.
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.
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. 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 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.
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. Read-only credential preflight precedes expensive local artifact work; local content verification still completes before hosted release or asset writes. Credential environment/file selection and forbidden-file validation retain their existing responsibilities. Backend-specific address validation stays with that backend.
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. 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. Credential preflight operates through the backend boundary in both library and CLI delivery, with accurate failure distinctions and documented permission limits.
Additional forge implementations and compatibility claims belong to later work. Release preparation and publication continue under the existing procedure.