Prepare the initial v0.1.0 release
This commit is contained in:
@@ -10,6 +10,9 @@ delivery are documented. ReleaseKit does not declare binary deliverables. The
|
||||
[product roadmap](docs/roadmap/releasekit.md) records remaining adoption and
|
||||
deployment work.
|
||||
|
||||
See the [v0.1.0 release note](docs/releases/v0.1.0.md) for the initial baseline
|
||||
and installation commands.
|
||||
|
||||
Run the offline Go test suite from the repository root with:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -152,8 +152,8 @@ Use the maintained [tag-delivery workflow](../../examples/woodpecker/tag-deliver
|
||||
in the consumer repository's `.woodpecker/` directory. Set `GO_IMAGE` to an
|
||||
image with Go 1.25 or newer, Git, and a Go version compatible with the consumer
|
||||
module. Replace `RELEASEKIT_VERSION` with an immutable ReleaseKit revision or
|
||||
published version. The example deliberately leaves this deployment pin as a
|
||||
placeholder. Configure the Woodpecker repository secret
|
||||
published version. The example selects the initial `v0.1.0` baseline; update
|
||||
that pin when adopting a later release. Configure the Woodpecker repository secret
|
||||
`releasekit_gitea_token`; the template maps it to `RELEASEKIT_GITEA_TOKEN` only
|
||||
for the delivery step. The repository needs a `delivery` profile. Page-only and
|
||||
binary behavior both use this template; the profile's build target list selects
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Base Policy Version:** 1.8
|
||||
|
||||
**Last Updated**: 2026-10-05
|
||||
**Last Updated**: 2026-10-07
|
||||
|
||||
**Upstream Source:** [oss.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/oss.md)
|
||||
|
||||
@@ -53,7 +53,7 @@ provides texts to copy for applicable licenses and their companions.
|
||||
## Project Licensing
|
||||
|
||||
ReleaseKit's selected grant is LGPL version 3 or later, recorded in
|
||||
[COPYRIGHT](../../COPYRIGHT). It applies to the library and a future release
|
||||
[COPYRIGHT](../../COPYRIGHT). It applies to the library and release
|
||||
executable. Adapted policy documents, agent orientation, and the policy reading
|
||||
guide retain their CC-BY-SA-4.0 scope as identified there and in the
|
||||
[attribution document](../oss/attribution.md).
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Base Policy Version:** 1.4
|
||||
|
||||
**Last Updated**: 2026-10-05
|
||||
**Last Updated**: 2026-10-07
|
||||
|
||||
**Upstream Source:** [release.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md)
|
||||
|
||||
@@ -16,10 +16,10 @@ The repository-specific commands belong in `docs/release.md`. Historical release
|
||||
summaries belong in `docs/releases/`. The procedure must agree with the adopted
|
||||
policy and link to it rather than introduce additional release requirements.
|
||||
|
||||
This policy governs releases of ReleaseKit itself. Consumer release capabilities
|
||||
are designed in the [product roadmap](../roadmap/releasekit.md) and acquire exact
|
||||
public contracts when implemented. ReleaseKit's source publication command and
|
||||
maintainer runbook are implemented; no ReleaseKit release has been published.
|
||||
This policy governs releases of ReleaseKit itself. Go declarations and GoDoc
|
||||
own supported consumer API contracts; the [product roadmap](../roadmap/releasekit.md)
|
||||
records planned adoption and deployment work. The maintainer runbook describes
|
||||
ReleaseKit's implemented source publication and hosted-page delivery procedure.
|
||||
|
||||
## Release Model And Completion
|
||||
|
||||
@@ -121,10 +121,9 @@ publish builds, verify the required build targets. Select those targets for
|
||||
the project's actual support commitments; native testing on each platform
|
||||
and access to particular hardware are not default release prerequisites.
|
||||
|
||||
The default suite and its runnable command will be established with the Go
|
||||
implementation. Documentation adoption checks validate this change; they do not
|
||||
create permanent release gates. ReleaseKit's source-only deliverable adds no
|
||||
binary target matrix.
|
||||
The publication command runs the standard offline Go test suite, followed by
|
||||
any additional product checks. The [maintainer runbook](../release.md) owns its
|
||||
invocation. ReleaseKit's source-only deliverable adds no binary target matrix.
|
||||
|
||||
Additional gates must address a concrete risk that the existing checks do not
|
||||
adequately cover. Do not automatically require linting, race testing, module
|
||||
|
||||
64
docs/releases/v0.1.0.md
Normal file
64
docs/releases/v0.1.0.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# ReleaseKit v0.1.0
|
||||
|
||||
## Summary
|
||||
|
||||
ReleaseKit's initial release provides an opinionated Go library and executable
|
||||
for candidate validation, annotated source-tag publication, version injection,
|
||||
selected-target builds, and Gitea release delivery.
|
||||
|
||||
The root `releasekit` facade owns release orchestration. The separate `buildinfo`
|
||||
facade supplies lightweight runtime version access. Both belong to one Go module
|
||||
with a Go 1.25.0 minimum language version.
|
||||
|
||||
## Capabilities
|
||||
|
||||
- Run the standard offline Go test suite once, followed by optional
|
||||
product-specific checks and selected-target build verification.
|
||||
- Publish the exact annotated tag for a validated candidate already on
|
||||
authoritative `main`, with bounded recovery after failed or ambiguous pushes.
|
||||
- Cross-build selected Go targets with shared version injection, artifact names,
|
||||
digests, and a native version smoke check. Source-only projects select no
|
||||
binary targets.
|
||||
- Deliver committed release notes and declared assets to Gitea, preserving
|
||||
existing content and reporting partial, conflicting, and uncertain outcomes.
|
||||
- Use one managed build-and-deliver operation or supply retained prebuilt
|
||||
artifacts for retries and separate build/delivery environments.
|
||||
- Prepare tagged CI checkouts and dependencies through the shared `ci-deliver`
|
||||
command and maintained Woodpecker workflow.
|
||||
|
||||
See the [CLI contract](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/cli.md),
|
||||
[configuration reference](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/config.md),
|
||||
[consumer delivery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md),
|
||||
and [runtime version guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/runtime-version.md)
|
||||
for supported behavior.
|
||||
|
||||
## Adoption and compatibility
|
||||
|
||||
Consumers can select this initial baseline with:
|
||||
|
||||
```sh
|
||||
go get gitea.maximumdirect.net/eric/ReleaseKit@v0.1.0
|
||||
go install gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@v0.1.0
|
||||
```
|
||||
|
||||
Profiles declare product identity, additional checks, selected binaries and
|
||||
targets, and a Gitea destination. Applications obtain their embedded version
|
||||
through `buildinfo.Version()`.
|
||||
|
||||
For consumers experimenting with earlier development revisions, rename the
|
||||
`ReleaseRequest.Validate` callback to `AdditionalChecks` and remove repeated
|
||||
standard-suite commands from profile `checks`. `DeliveryRequest.Build` now
|
||||
accepts a `*BuildSpec` for managed builds; use `Prebuilt` for an existing
|
||||
`BuildResult`.
|
||||
|
||||
Compatibility follows the [release policy](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/policy/release.md): before
|
||||
v1.0.0, minor releases may change documented contracts with migration guidance;
|
||||
patch releases preserve contracts within their minor line.
|
||||
|
||||
ReleaseKit's deliverables are this immutable source tag and the hosted page
|
||||
containing this complete note. Consumer migration and live Woodpecker deployment
|
||||
remain adoption work tracked in the [product roadmap](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/roadmap/releasekit.md).
|
||||
|
||||
[COPYRIGHT](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/COPYRIGHT) |
|
||||
[LICENSE](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/LICENSE) |
|
||||
[ATTRIBUTION](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/oss/attribution.md)
|
||||
@@ -1,416 +0,0 @@
|
||||
# ReleaseKit pre-release audit
|
||||
|
||||
Date: 2026-10-06. Reviewed source: `536a57916f6565ae8194c4563577dfcebd6cfb69`.
|
||||
Status: historical review evidence and selected target direction for the
|
||||
[implementation plan](implementation.md).
|
||||
Audience: maintainers deciding the shared release standard before `v0.1.0`.
|
||||
|
||||
## Assessment
|
||||
|
||||
ReleaseKit's practical goals are to minimize application-owned release code,
|
||||
duplication across the suite, and the time developers spend on release processes.
|
||||
Shared conventions serve these goals by giving routine decisions one owner.
|
||||
Applications supply product facts and product-specific checks; ReleaseKit owns
|
||||
the procedure, sensible defaults, and recovery guidance.
|
||||
|
||||
Evaluate recommendations by the application code they remove, the shared logic
|
||||
they consolidate, and the recurring decisions they eliminate. Standardization,
|
||||
configuration options, and diagnostic detail are useful when they reduce that
|
||||
work. Keep routine release decisions inside ReleaseKit.
|
||||
|
||||
The core direction is sound. Retain the publication/delivery separation, narrow
|
||||
public facades, standard artifact naming, version injection, and content-aware
|
||||
retries. Fix the reproduced validation and recovery defects in F1–F2 before
|
||||
`v0.1.0`. Treat F3 as a focused improvement to internal build defaults.
|
||||
|
||||
Build-environment reproducibility, hardware-specific configurability, and
|
||||
extensive build inspection are outside the product's optimization goals. Use the
|
||||
available compatible Go toolchain and shared baseline settings. Evaluate new
|
||||
configuration and deployment machinery by the application code and developer
|
||||
work they save. Different toolchains may produce different bytes; existing
|
||||
published content remains protected by digest comparison.
|
||||
|
||||
The implementation covers most mechanics in the [product roadmap](releasekit.md).
|
||||
Representative adoption should demonstrate the
|
||||
[architectural success criteria](../policy/architecture.md#success-criteria)
|
||||
through deleted release code, fewer duplicated checks, and fewer routine decisions.
|
||||
F4–F6 identify opportunities to centralize validation, delivery, and CI setup.
|
||||
|
||||
The existing source transaction supports these goals. Annotated tags preserve
|
||||
the checked-in note and provide an exact object for recovery. Requiring the
|
||||
candidate on authoritative `main` keeps branch publication in preparation.
|
||||
Separate delivery lets source publication finish independently of hosting.
|
||||
Consumer migrations should adopt this common process and retain product identity,
|
||||
target selection, compatibility decisions, and product-specific checks.
|
||||
|
||||
## Scope and evidence
|
||||
|
||||
Reviewed the development guide; agent, architecture, testing, documentation, and
|
||||
release policies; facade ADR; roadmap; public declarations; CLI/configuration
|
||||
and consumer guides; publication, build, delivery, Git and Gitea implementations;
|
||||
and their relevant tests and workflow examples. The
|
||||
[release policy](../policy/release.md) governs ReleaseKit's own releases.
|
||||
The facade and integration contracts define consumer behavior.
|
||||
|
||||
Also inspected the release scripts, module declarations, and available delivery
|
||||
YAML in the six sibling projects named by the roadmap. This read-only sample
|
||||
informed the assessment of adoption needs.
|
||||
Existing extra checks should be retained according to their product-specific value.
|
||||
For example, PromptKit has product-specific executable examples, whereas
|
||||
Narratio currently requires Go 1.26 and several peers require Go 1.25.5.
|
||||
|
||||
Validation on Linux/amd64 with Go 1.26.8:
|
||||
|
||||
- `GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test -mod=readonly -count=1 ./...`
|
||||
passed on the reviewed checkout.
|
||||
- `go run ./internal/apicheck` passed.
|
||||
- Isolated probes against an archive of the reviewed commit reproduced F1–F3
|
||||
below. They used temporary consumer repositories and local bare Git remotes.
|
||||
|
||||
The investigative probes ran in a disposable checkout. Their setup and outcomes
|
||||
are recorded with each finding for future regressions. Validation covered local
|
||||
fixtures on Go 1.26.8. Live Gitea/Woodpecker integration, published-module
|
||||
installation, and minimum-Go-1.25 compatibility remain unverified. These results
|
||||
belong to the original source review; this revision updates its recommendations.
|
||||
|
||||
## Goal coverage
|
||||
|
||||
| Goal | Assessment and evidence |
|
||||
| --- | --- |
|
||||
| One standard source-publication transaction | Substantially implemented in [Publish](../../internal/publish/publish.go): captured candidate, authoritative `main`, annotated tag, exact object/ref push, and bounded recovery. F2 is a correctness exception. |
|
||||
| One validation of the intended candidate | Callback/default validation plus mutable-state rechecks are implemented in [candidate](../../internal/candidate/check.go). F1 can silently narrow the default suite; F4 concerns the selected customization model. |
|
||||
| Consumer-selected binaries or source-only releases | [Build](../../internal/build/build.go) supports target pairs and empty sets. Source-only delivery creates no binary manifest. This is the right distinction. |
|
||||
| Shared runtime version, build flags, naming, and smoke check | Implemented through [buildinfo](../../buildinfo/version.go), the builder, and external consumer build tests. F3 identifies an opportunity for predictable internal defaults. |
|
||||
| Immutable hosted contents and recoverable partial delivery | [Delivery](../../internal/delivery/delivery.go) and [Gitea](../../internal/gitea/) compare notes and asset bytes, reject conflicts, and add missing assets. F7 identifies an outcome-reporting inconsistency. |
|
||||
| Public contract ownership and small runtime dependency graph | Root and runtime facades follow [ADR 0001](../adr/0001-public-facade.md); compiled boundary checks pass. Keep these boundaries. |
|
||||
| Thin application integration and less repeated infrastructure | Representative consumer adoption remains to be evaluated. F5–F6 identify remaining orchestration and setup duplication. |
|
||||
| Ready deployment path | Prepared templates and local fixtures exist. Immutable deployment pins, credentials, activated workflows, and live verification remain explicitly open in the roadmap. |
|
||||
|
||||
## Findings
|
||||
|
||||
### F1 — High: ambient Go flags can turn candidate validation into a false pass
|
||||
|
||||
**Evidence.** `runDefaultValidation` in
|
||||
[internal/candidate/check.go](../../internal/candidate/check.go) controls module
|
||||
network access, workspace discovery, and toolchain selection, but inherits
|
||||
`GOFLAGS`. The default command supplies `-mod=readonly -count=1`; neither flag
|
||||
cancels a test-name filter. Configured checks also inherit the environment through
|
||||
[RunChecks](../../cmd/releasekit/internal/cli/config.go). ReleaseKit's own
|
||||
[profile](../../releasekit.json) explicitly supplies the test command without
|
||||
controlling `GOFLAGS`.
|
||||
|
||||
**Reproduction.** Create a clean `main` fixture with a matching committed note
|
||||
and one `TestFails` that calls `t.Fatal`. `Check` with no callback fails as
|
||||
expected. Set `GOFLAGS=-run=^$` and invoke the same operation against the same
|
||||
commit: it returns nil and reports `[no tests to run]`.
|
||||
The [Go command documentation](https://pkg.go.dev/cmd/go#hdr-Environment_variables)
|
||||
confirms that `GOFLAGS` supplies defaults to commands that recognize its flags.
|
||||
|
||||
**Consequence.** A normal developer setting used for focused testing can cause a
|
||||
release to pass after skipping the default suite. The reproduction uses an
|
||||
unchanged committed candidate and an ordinary shell setting.
|
||||
|
||||
**Recommendation.** Make the standard validation command own its effective Go
|
||||
flags and host target, including values supplied through Go's persistent
|
||||
configuration. Preserve caches and legitimate dependency preparation settings.
|
||||
Share internal Go-environment handling where the semantics match. Preserve
|
||||
the settings appropriate to native tests and static release builds separately.
|
||||
Apply the same baseline to ReleaseKit's own profile. Retain a regression showing
|
||||
that a failing test remains effective under an ambient filter. F4 and Design
|
||||
Choice 1 describe how product-specific checks compose with this baseline.
|
||||
|
||||
### F2 — High: automatic push recovery can query a different endpoint and report false absence
|
||||
|
||||
**Evidence.** [reconcilePush](../../internal/publish/publish.go) calls
|
||||
`Endpoint.QueryTag` using the captured URL and command-scoped remote.
|
||||
[QueryTag](../../internal/git/tag.go) runs the query directly.
|
||||
[Resolve/Recheck](../../internal/git/remote.go) call `verifyScopedURLs` before
|
||||
publication. Git still applies current URL rewrite configuration to the captured
|
||||
literal URL. The manual recovery instructions in
|
||||
[the runbook](../release.md#resolve-failures) already require a URL-equality check.
|
||||
The automatic path lacks the equivalent check.
|
||||
|
||||
**Reproduction.** In a temporary publication fixture, wrap Git so the actual tag
|
||||
push succeeds, then add a local `url.<empty-bare-repository>.insteadOf` rule for
|
||||
the captured endpoint and return exit 77 to simulate a lost acknowledgment.
|
||||
`Publish` returns `state=not_published`, `phase=reconciliation`, and says the
|
||||
authoritative tag is absent. Direct inspection of the original bare repository
|
||||
shows the exact tag object returned in `PublicationResult` is present.
|
||||
|
||||
**Consequence.** The result gives incorrect recovery advice after an ambiguous
|
||||
push. It converts a query to the wrong endpoint into proof that the intended
|
||||
endpoint lacks the published tag. This contradicts the existing recovery
|
||||
contract for the authoritative endpoint.
|
||||
|
||||
**Recommendation.** Within the existing bounded recovery context, verify that the
|
||||
captured endpoint still resolves to itself before the one authoritative tag
|
||||
query. If verification fails, preserve the push error and local tag and return
|
||||
`unknown`. Keep recovery bound to the captured endpoint. Cover the
|
||||
successful-publication/false-absence reproduction and ordinary recovery against
|
||||
an unchanged endpoint. Preserve successful push as the completion point.
|
||||
|
||||
### F3 — Internal improvement: ambient CPU settings change binary compatibility
|
||||
|
||||
**Evidence.** `goEnvironment` in [internal/build/build.go](../../internal/build/build.go)
|
||||
standardizes several Go settings and inherits architecture feature variables,
|
||||
`GOEXPERIMENT`, and the persistent Go environment file.
|
||||
|
||||
**Reproduction.** Build the same committed consumer and `v1.2.3` for
|
||||
`linux/amd64` twice, once with `GOAMD64=v1` and once with `GOAMD64=v2`.
|
||||
Both builds succeed with `SourceVerified=true` and the filename
|
||||
`fixture-v1.2.3-linux-amd64`. Their SHA-256 digests differ, and `go version -m`
|
||||
records the respective feature levels. Go documents these as different target
|
||||
microarchitecture requirements in its
|
||||
[environment reference](https://pkg.go.dev/cmd/go#hdr-Environment_variables).
|
||||
|
||||
**Consequence.** A developer's ambient CPU setting can narrow a binary's hardware
|
||||
compatibility. Different build inputs can also produce a digest conflict during
|
||||
a delivery retry. Existing digest comparison correctly preserves published bytes.
|
||||
The practical benefit of addressing this finding is predictable hardware
|
||||
compatibility with fewer settings for application developers to manage.
|
||||
|
||||
**Recommendation.** Use ordinary baseline CPU settings and shared build flags
|
||||
internally, with the available compatible Go toolchain. Control incidental
|
||||
settings that affect expected compatibility or validation. Keep the application
|
||||
profile focused on its package, binary name, and targets. Exact toolchain
|
||||
pinning and detailed build metadata remain optional operational choices.
|
||||
When a retry requires the original bytes, preserve and reuse those artifacts.
|
||||
Design Choice 2 compares local toolchain use with a centrally maintained build
|
||||
environment for consumers that benefit from shared setup.
|
||||
|
||||
### F4 — Design priority: adding a custom check replaces the entire standard suite
|
||||
|
||||
**Evidence.** [CLI routing](../../cmd/releasekit/main.go) installs a validation
|
||||
callback whenever `checks` is nonempty. [Validate](../../internal/candidate/check.go)
|
||||
then skips its default test command. This agrees with the
|
||||
[configuration contract](../config.md), and the Go API deliberately permits a
|
||||
replacement `Validate` callback.
|
||||
|
||||
**Consequence.** Adding one product-specific example check requires the consumer
|
||||
to remember and reproduce the standard test command, environment, and ordering.
|
||||
The profile becomes a small release program that repeats shared policy. Migrating
|
||||
to built-in tests requires removing their invocation from existing custom scripts
|
||||
to preserve one suite run.
|
||||
|
||||
**Recommendation.** Run the shared offline suite once, followed by optional
|
||||
product-specific checks. Move redundant suite invocations out of consumer scripts.
|
||||
Retain checks for actual product behavior, such as PromptKit's examples. Add
|
||||
alternative test-invocation settings when a concrete consumer requirement
|
||||
justifies them. This choice changes the current customization contract; Design
|
||||
Choice 1 records the replacement-callback alternative.
|
||||
|
||||
### F5 — Design priority: the CLI owns reusable tagged-build delivery orchestration
|
||||
|
||||
**Evidence.** [runDelivery](../../cmd/releasekit/main.go) chooses a temporary
|
||||
output directory, invokes the public builder, converts receipts, and then calls
|
||||
`Deliver`. The [public delivery request](../../delivery.go) accepts an already
|
||||
produced `BuildResult`. A Go consumer wanting the normal build-and-deliver
|
||||
operation must reproduce orchestration already implemented by the CLI. The
|
||||
default CLI path also builds and runs the native smoke executable
|
||||
before `Deliver` verifies that HEAD matches the selected local tag.
|
||||
|
||||
**Consequence.** Temporary storage, build sequencing, tagged-source preflight,
|
||||
and cleanup have more than one potential owner. An invalid tagged checkout can
|
||||
consume a complete cross-build before it is rejected. The CLI owns domain coordination
|
||||
alongside its parsing, presentation, and exit-status responsibilities.
|
||||
|
||||
**Recommendation.** Put the ordinary verify-tagged-source, build-selected-targets,
|
||||
and deliver sequence behind the orchestration facade. Verify the local tagged
|
||||
source before expensive compilation, then retain the necessary checks before
|
||||
remote effects. Let the CLI adapt JSON, credentials, and output to that operation.
|
||||
Use the same build declaration for candidate validation and delivery. Support
|
||||
caller-provided builds for concrete needs such as retrying with retained
|
||||
artifacts, as discussed in Design Choice 3. Keep separate building useful for
|
||||
local development. The ordinary consumer workflow should complete delivery in
|
||||
one invocation; advanced artifact handoffs can use private coordination data
|
||||
when needed.
|
||||
|
||||
### F6 — Adoption priority: shared deployment still depends on copied mechanics
|
||||
|
||||
**Evidence.** The original source-only and binary templates repeated
|
||||
fetch/checkout guards, local exclusions, cache setup, and tool installation;
|
||||
they are now consolidated in the maintained
|
||||
[tag-delivery template](../../examples/woodpecker/tag-delivery.yml). The binary
|
||||
template added an explicit build/receipt/deliver sequence even though the CLI
|
||||
already supports combined delivery. ReleaseKit's
|
||||
[own workflow](../../examples/woodpecker/releasekit-source-delivery.yml) has a
|
||||
separate first-release bootstrap. Consumer pins remain placeholders as documented.
|
||||
|
||||
**Consequence.** Copied CI mechanics require maintenance in each consumer and
|
||||
can drift. A shared installation and update convention would simplify local
|
||||
publication and CI delivery.
|
||||
|
||||
**Recommendation.** Provide one maintained integration entry point and one
|
||||
default delivery sequence for source-only and binary profiles. Consumers select
|
||||
the ReleaseKit version, supply product settings, and provision credentials.
|
||||
Centralize installation and update instructions. Use versioned source
|
||||
installation for the shared CI command. Evaluate a maintained image by the
|
||||
additional setup and maintenance effort it saves.
|
||||
Keep dependency preparation separate from offline validation/builds. A split
|
||||
build/delivery flow remains useful for an actual credential boundary or artifact
|
||||
handoff. See Design Choice 4 for packaging alternatives.
|
||||
|
||||
The original `TestWoodpeckerDeliveryCommandSequences` and the ReleaseKit
|
||||
workflow test reconstructed workflow commands, so YAML drift could leave the
|
||||
tests green. The maintained tag template and ReleaseKit's bootstrap workflow
|
||||
are now exercised from their command blocks by local Git/HTTP fixtures. The Go
|
||||
bootstrap shim verifies template arguments while mapping the pinned module
|
||||
invocation to the test executable; it does not verify published-module
|
||||
availability. Real installation and live Woodpecker execution remain
|
||||
deployment work.
|
||||
|
||||
### F7 — Medium: delivery asset classifications overlap inconsistently
|
||||
|
||||
**Evidence.** In [UploadMissing](../../internal/gitea/upload.go), a failed
|
||||
reconciliation list adds an asset to `Uncertain` while leaving it in `Pending`.
|
||||
The `AssetMissing` reconciliation branch does the same for an unresolved write;
|
||||
the default/unverifiable branch removes it from `Pending`. A reconciled conflict
|
||||
can also remain pending. The existing
|
||||
`TestUploadMissingReportsUnknownWhenReconciliationReadFails` in
|
||||
[upload_test.go](../../internal/gitea/upload_test.go) explicitly expects the
|
||||
same asset in both pending and uncertain collections.
|
||||
|
||||
**Consequence.** Overlapping categories require special handling by consumers.
|
||||
The CLI can present one file as both pending and uncertain, while a
|
||||
slightly different failure reports it only as uncertain. The overall unknown
|
||||
state remains conservative. Consistent categories would simplify recovery
|
||||
reporting and automation.
|
||||
|
||||
**Recommendation.** Prefer mutually exclusive current-outcome categories:
|
||||
confirmed matching, uploaded, known pending, conflicting, and uncertain. Move an
|
||||
asset out of pending when its outcome becomes uncertain or conflicting, and
|
||||
clarify the facade GoDoc. Design Choice 5 records the alternative superset
|
||||
interpretation.
|
||||
|
||||
### F8 — Maintainability: artifact rules have several implementation owners
|
||||
|
||||
**Evidence.** Filename construction occurs in `artifactFilename` in
|
||||
[the builder](../../internal/build/build.go), `receiptArtifactFilename` in
|
||||
[CLI receipt handling](../../cmd/releasekit/internal/cli/receipt.go), and
|
||||
`declaredBuildAssets` in [delivery](../../internal/delivery/assets.go).
|
||||
Target normalization and filename-component validation are also repeated across
|
||||
these boundaries. CLI receipt handling carries substantial domain validation
|
||||
alongside JSON serialization. Build invocation uses its own `exec.CommandContext`
|
||||
path while default validation uses [process.Run](../../internal/process/process.go),
|
||||
with independently constructed Go environments.
|
||||
|
||||
**Consequence.** A change to target identity, naming, or build settings can leave
|
||||
the builder, receipt reader, and delivery validator disagreeing. F1 and F3 show
|
||||
why divergent Go-environment ownership matters beyond cosmetic duplication.
|
||||
|
||||
**Recommendation.** Give internal build/artifact rules one owner and reuse them
|
||||
from receipt and delivery adapters. Share Go invocation/environment construction
|
||||
where the semantics match. Keep the explicit facade conversions required
|
||||
by the ADR. Focus refactoring on the small internal helpers that own these rules.
|
||||
|
||||
## Target state
|
||||
|
||||
Retain the existing source transaction: committed stable-version note, clean
|
||||
`main`, candidate already on authoritative `main`, one validation, selected-target
|
||||
build verification, exact annotated-tag publication, and bounded recovery.
|
||||
Source publication finishes independently of hosted delivery. Keep additive,
|
||||
content-checked delivery and lightweight runtime version access.
|
||||
|
||||
Make ordinary integration a versioned tool invocation plus a small product
|
||||
profile and credential provisioning. The profile supplies product identity,
|
||||
selected binaries and targets, delivery destination, and product-specific checks.
|
||||
ReleaseKit owns the standard suite, routine build settings, delivery sequence,
|
||||
and recovery reporting. Product developers choose versions and write
|
||||
compatibility notes. Evaluate each proposed setting by the work it saves them.
|
||||
|
||||
The [implementation plan](implementation.md) owns the stages, API changes,
|
||||
regression coverage, and completion criteria needed to reach this target.
|
||||
Representative adoption should demonstrate fewer scripts, duplicated tests,
|
||||
setup steps, and recurring release decisions.
|
||||
|
||||
Feature expansion should follow demonstrated consumer needs and measurable
|
||||
reductions in application maintenance or developer effort.
|
||||
|
||||
## Design Choices
|
||||
|
||||
The implementation plan selects the recommended directions below for the
|
||||
upcoming sprint. Alternatives record the tradeoffs for future consumer needs.
|
||||
These choices describe the target behavior; current contracts change as their
|
||||
implementation lands.
|
||||
|
||||
### 1. Should product checks supplement or replace standard validation?
|
||||
|
||||
**Selected direction:** Run the shared offline Go suite once, followed by optional
|
||||
product-specific checks. ReleaseKit owns the command and its routine environment
|
||||
settings. Migrate repeated suite invocations out of application scripts. Add
|
||||
alternative invocation settings when an actual consumer requirement establishes
|
||||
their value. An application adding an example check should declare that check
|
||||
and receive the standard suite automatically. This gives developers one ordinary
|
||||
validation path to understand.
|
||||
|
||||
**Viable alternative:** Keep a replacement callback or complete validation
|
||||
command for products with unusual test layouts. This is a simple composition
|
||||
boundary and can accommodate existing product test infrastructure. It assigns
|
||||
more release responsibility to the application, so its value depends on the
|
||||
specific consumer need.
|
||||
|
||||
### 2. How should ReleaseKit choose build settings?
|
||||
|
||||
**Selected direction:** Use the available compatible Go toolchain, ordinary
|
||||
baseline CPU settings, and shared build flags. Handle incidental settings internally
|
||||
so developers can rely on the selected target's expected compatibility. Keep
|
||||
application configuration small. Toolchain-dependent byte differences are
|
||||
acceptable; digest checks preserve existing published content, and retained
|
||||
artifacts support retries requiring the same bytes. ReleaseKit can own baseline
|
||||
settings internally while applications declare their packages and targets.
|
||||
|
||||
**Viable alternative:** A shared CI image can supply a centrally selected Go
|
||||
version and build environment when this makes installation and support easier.
|
||||
Maintainers own image updates; applications use the shared integration. This is
|
||||
useful where a common environment reduces operational work. Its value should be
|
||||
measured against image maintenance and the suite's differing Go requirements.
|
||||
Explicit hardware variants can be added for a demonstrated product need.
|
||||
|
||||
### 3. Should the library own build-and-deliver, or accept only completed builds?
|
||||
|
||||
**Selected direction:** Provide one facade operation for tagged-source verification,
|
||||
selected-target builds, temporary storage, checksums, uploads, and cleanup.
|
||||
Use it from the CLI so both interfaces share the procedure. Retain separate
|
||||
building for local development and support prebuilt delivery where a concrete
|
||||
handoff or retry requirement justifies it. Routine delivery should require one
|
||||
invocation, with ReleaseKit managing the artifact lifecycle. This minimizes
|
||||
consumer orchestration code.
|
||||
|
||||
**Viable alternative:** Keep separate build and delivery primitives with a
|
||||
maintained composition helper. This suits consumers that require credential
|
||||
isolation between stages or need to retain artifacts for later delivery. Those
|
||||
consumers accept responsibility for the artifact lifecycle in exchange for the
|
||||
operational separation they need.
|
||||
|
||||
### 4. How should the shared executable and CI integration be distributed?
|
||||
|
||||
**Selected direction:** Choose the simplest maintained entry point for installation,
|
||||
updates, and delivery. Use versioned source installation and a shared CI delivery
|
||||
command. The command prepares the tagged checkout, reads its product profile,
|
||||
prepares dependencies for selected binaries, and invokes ordinary facade delivery.
|
||||
Centralize reusable setup and provide one clear upgrade procedure. Applications
|
||||
select a ReleaseKit version and supply product settings and credentials; shared
|
||||
integration owns routine setup.
|
||||
Assess packaging by the consumer code and recurring developer work it removes.
|
||||
|
||||
**Viable alternative:** Publish a maintained CI image containing ReleaseKit and
|
||||
a compatible Go/Git environment when it substantially reduces setup. The image
|
||||
provides a ready-to-run integration and centralizes environment maintenance.
|
||||
It also creates an image publication and update responsibility, which should be
|
||||
reflected in the release procedure. Either packaging choice should give
|
||||
applications a small configuration and a routine invocation.
|
||||
|
||||
### 5. How should delivery results support simple recovery?
|
||||
|
||||
**Selected direction:** Use exclusive outcome categories: matching, uploaded, known
|
||||
pending, conflicting, and uncertain. Present ordinary callers with completion or
|
||||
a clear failure and recovery instruction. Keep asset details available for
|
||||
diagnostics. Derive recovery guidance centrally so each application can present
|
||||
the result directly. Consistent categories simplify implementation and
|
||||
interpretation.
|
||||
|
||||
**Viable alternative:** Pending includes every unfinished declaration, with
|
||||
conflicting/uncertain as diagnostic subsets. This can simplify a progress UI
|
||||
when defined explicitly and applied in every branch. Consumers must then
|
||||
subtract blocked subsets before deriving retry work. Apply the chosen
|
||||
meaning consistently across all outcomes.
|
||||
@@ -1,598 +0,0 @@
|
||||
# ReleaseKit audit implementation plan
|
||||
|
||||
Status: All implementation stages complete.
|
||||
Baseline: `e4be7fa` (2026-10-06). The [audit](audit.md) records the evidence,
|
||||
product goals, and selected direction. This document owns implementation order
|
||||
and completion criteria for that work.
|
||||
|
||||
## How to execute this plan
|
||||
|
||||
Implement one numbered stage per prompt, in order. Each stage includes its
|
||||
production change, relevant tests, and current-contract documentation. Leave the
|
||||
repository compiling and its checks passing at each stage boundary. Record
|
||||
completed stages here with a concise validation result; report the commit
|
||||
identifier in the stage completion response. Read
|
||||
[development guidance](../development.md) and its applicable policies at the
|
||||
start of each stage.
|
||||
|
||||
Use the [agent policy](../policy/agents.md), [architecture
|
||||
policy](../policy/architecture.md), [testing policy](../policy/testing.md), and
|
||||
[documentation policy](../policy/documentation.md). Discover current symbols
|
||||
through the codebase graph, then inspect their callers and tests before editing.
|
||||
The paths below locate the baseline; internal names may evolve during the work.
|
||||
Use ordinary functions and existing internal packages where their ownership
|
||||
fits. Public named types remain facade-owned with explicit internal conversions.
|
||||
|
||||
For each stage, run focused behavioral tests for its changed responsibilities.
|
||||
Then run the existing repository checks from the root:
|
||||
|
||||
```sh
|
||||
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go test -mod=readonly -count=1 ./...
|
||||
GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off go run ./internal/apicheck
|
||||
```
|
||||
|
||||
Prepare dependencies before these offline checks when needed. Review changed
|
||||
GoDoc, examples, local documentation links and fragments, and `git diff --check`.
|
||||
Reuse successful checks for unchanged content. Commit each completed stage
|
||||
under the agent policy. These implementation checks serve the development
|
||||
workflow.
|
||||
|
||||
## Decisions for this sprint
|
||||
|
||||
These choices resolve the audit's design alternatives for implementation:
|
||||
|
||||
- Candidate validation runs the standard offline Go suite once, then optional
|
||||
product checks, then selected-target build verification. Rename the Go
|
||||
callback to `AdditionalChecks`; JSON retains `checks` with additive semantics.
|
||||
- ReleaseKit uses the available compatible Go toolchain, internal baseline CPU
|
||||
settings, and shared build flags. It controls incidental flags and persistent
|
||||
Go settings while preserving operational configuration such as caches.
|
||||
- `Deliver` accepts a build declaration and owns temporary build output,
|
||||
checksums, uploads, and cleanup. An explicit prebuilt path retains original
|
||||
artifacts for retries and supports separated build/delivery environments.
|
||||
- Delivery asset categories are disjoint observations: matching, uploaded,
|
||||
known pending, conflicting, and uncertain. Existing overall delivery states
|
||||
and content-preservation rules remain authoritative.
|
||||
- A versioned source-installed command is the initial shared CI entry point.
|
||||
Add `ci-deliver` for explicit CI checkout and dependency preparation followed
|
||||
by the same facade delivery operation. Ordinary `deliver` remains suitable
|
||||
for an already prepared checkout. CI images remain an operational option.
|
||||
- Shared artifact rules and Go execution settings have small internal owners.
|
||||
Application profiles continue to declare product facts and additional checks.
|
||||
|
||||
The callback and delivery request changes are deliberate pre-release API
|
||||
changes. Update all in-repository callers and their canonical documentation in
|
||||
the corresponding stage. The initial release note should describe the final
|
||||
interfaces and migration impact when that release is prepared.
|
||||
|
||||
The sprint preserves the existing source transaction, successful-tag-push
|
||||
completion point, bounded recovery, content-aware retries, standalone `Build`,
|
||||
and lightweight `buildinfo`. Build observations and private receipts retain
|
||||
their existing source-eligibility meaning. Toolchain-dependent byte differences
|
||||
remain acceptable. Build identity remains an observation of the checked source
|
||||
and produced files under the existing contracts. Live deployment and sibling
|
||||
repository migrations remain separate adoption work in the
|
||||
[product roadmap](releasekit.md).
|
||||
|
||||
## Stage 1 — Keep ambiguous-push recovery on the captured endpoint
|
||||
|
||||
**Covers:** F2. **Primary owners:** `internal/git/tag.go`,
|
||||
`internal/git/remote.go`, `internal/publish/publish.go` and their tests.
|
||||
|
||||
1. Before `Endpoint.QueryTag` performs its remote read, reuse
|
||||
`verifyScopedURLs` with the captured endpoint and command-scoped configuration.
|
||||
Verify that the captured URL still resolves to itself. Use the existing
|
||||
reconciliation context and timeout for both verification and the remote read.
|
||||
2. Treat verification failure as unreadable authoritative state. Preserve error
|
||||
identity through wrapping so `reconcilePush` reports `unknown`, retains the
|
||||
local tag, and preserves the original push failure for diagnosis.
|
||||
3. Keep the captured endpoint as recovery's authority. The local resolution
|
||||
check precedes the existing single remote tag query. Preserve exact tag-object
|
||||
and peeled-commit comparison and successful push as the completion point.
|
||||
4. Update relevant recovery GoDoc and internal guidance to explain the
|
||||
automatic URL-resolution check. Keep the manual recovery runbook consistent.
|
||||
|
||||
**Completion evidence:** Extend the existing local Git publication fixtures with
|
||||
F2's lost-acknowledgment reproduction: actually publish the tag, install a URL
|
||||
rewrite to an empty bare repository, then report a push error. Recovery must
|
||||
return unknown and preserve the tag/error; direct inspection of the original
|
||||
remote must find the intended object. Existing unchanged-endpoint success,
|
||||
absence, conflict, and unreadable-recovery tests continue to pass. Test the
|
||||
behavior through publication; avoid a second copy of the full recovery matrix.
|
||||
|
||||
**Completed:** Recovery now verifies the captured URL before its one tag query.
|
||||
The rewrite reproduction returns unknown, preserves the local tag and both
|
||||
errors, and confirms the object on the original remote. Focused publication
|
||||
tests, the full offline suite, API boundary checks, and documentation whitespace
|
||||
checks pass.
|
||||
|
||||
## Stage 2 — Own effective Go settings for validation and builds
|
||||
|
||||
**Covers:** F1, F3, Go-environment portion of F8. **Primary owners:**
|
||||
`internal/candidate/check.go`, `internal/build/build.go`, `internal/process/`,
|
||||
and a small new `internal/gotool` package.
|
||||
|
||||
1. Put effective Go-environment construction and common invocation behavior in
|
||||
`internal/gotool`. Reuse the existing subprocess boundary for context,
|
||||
working directory, output, and error handling. Support native validation and
|
||||
static target builds as distinct modes of the same implementation.
|
||||
2. Account for both the process environment and values from Go's persistent
|
||||
environment file. Resolve effective Go configuration with the installed Go
|
||||
command under local toolchain selection and a controlled `GOFLAGS`. Ensure
|
||||
configuration discovery itself tolerates the ambient settings being replaced;
|
||||
an experiment override used only for discovery must not become the build
|
||||
default. Carry effective operational settings into child environments, then
|
||||
use `GOENV=off`
|
||||
there so removed settings cannot reappear from the persistent file. Retain
|
||||
ordinary process variables and effective cache, module-cache, temporary,
|
||||
tool-location, and native C-tool settings. Keep informational `go env` output
|
||||
separate from configuration when constructing child environments.
|
||||
3. Own `GOFLAGS`, `GOWORK`, `GOTOOLCHAIN`, module-network settings, target
|
||||
selection, experiment selection, and architecture-feature settings. Standard
|
||||
validation uses `go test -mod=readonly -count=1 ./...`, host OS/architecture,
|
||||
`GOWORK=off`, `GOTOOLCHAIN=local`, `GOPROXY=off`, `GONOPROXY=none`, and
|
||||
`GOSUMDB=off`. Resolve the Go host target independently of ambient cross-build
|
||||
settings. Native tests retain native Go cgo behavior and explicit native
|
||||
C-tool configuration; release builds retain `CGO_ENABLED=0`.
|
||||
4. Clear ambient experiments and architecture tuning for the child so the
|
||||
selected Go toolchain supplies ordinary baseline defaults. Handle the Go
|
||||
feature variables for supported toolchains, including `GOAMD64`, `GOARM`,
|
||||
`GOARM64`, `GO386`, `GOMIPS`, `GOMIPS64`, `GOPPC64`, `GORISCV64`, and `GOWASM`.
|
||||
Clearing must take effect for persisted values as well. Retain the existing
|
||||
release flags, linker injection, target selection, and native version smoke
|
||||
check. Keep these settings internal; the profile needs no new tuning fields.
|
||||
5. Route default validation, build toolchain/host queries, target compilation,
|
||||
and native smoke-build compilation through the shared owner. Preserve useful
|
||||
compiler diagnostics and cancellation. Custom product commands retain their
|
||||
explicitly selected arguments and environment overlays.
|
||||
6. Update the build and check consumer guides and relevant GoDoc with the
|
||||
supported behavior: shared baseline settings and the available compatible
|
||||
toolchain. Exact internal environment construction belongs in internal docs.
|
||||
|
||||
**Completion evidence:** A genuinely failing fixture test still fails with
|
||||
`GOFLAGS=-run=^$` supplied through either the process or a temporary Go env file.
|
||||
An ambient cross-target setting still results in host-native validation. Extend
|
||||
existing build fixtures to demonstrate that ambient/persisted `GOAMD64=v2` and
|
||||
experiment settings do not alter the selected baseline build settings. Inspect
|
||||
build metadata where useful; identical binary bytes are unnecessary evidence.
|
||||
Use a temporary configured cache to demonstrate that persistent cache choices
|
||||
survive. Preserve existing version injection, empty-target, cancellation, and
|
||||
partial-build behavior. Fixtures use temporary Go configuration and never edit
|
||||
the developer's persistent settings.
|
||||
|
||||
**Completed:** Shared Go configuration now drives default validation,
|
||||
toolchain/host queries, target builds, and the native smoke build. Failing
|
||||
validation fixtures prove process and persistent `GOFLAGS` cannot suppress a
|
||||
real test and that cross-target settings still run tests on the host. Build
|
||||
metadata confirms ambient and persistent tuning are cleared, and a temporary
|
||||
persistent cache is used. Focused tests, the full offline suite, API boundary
|
||||
checks, and documentation whitespace checks pass.
|
||||
|
||||
## Stage 3 — Make product checks additive
|
||||
|
||||
**Covers:** F4 and ReleaseKit's own F1 exposure. **Primary owners:** `check.go`,
|
||||
`publish.go`, `internal/candidate/`, CLI profile mapping and fixtures.
|
||||
|
||||
1. Rename `ReleaseRequest.Validate` to
|
||||
`AdditionalChecks func(context.Context, Candidate) error` and update the
|
||||
corresponding internal request and facade conversions. The callback keeps
|
||||
the existing candidate-value ownership and error-wrapping behavior.
|
||||
2. Make `candidate.Validate` always run the shared offline suite first. On
|
||||
success, invoke `AdditionalChecks` once when supplied. Run selected-target
|
||||
build verification after these checks through the existing orchestration.
|
||||
A failure or cancellation ends the sequence and preserves its cause.
|
||||
3. Retain `checks` in JSON as ordered additional commands. Map the CLI's
|
||||
`RunChecks` callback to `AdditionalChecks`. Keep the existing argument-vector
|
||||
and per-command environment semantics.
|
||||
4. Remove repeated standard-suite commands from `releasekit.json` and example
|
||||
profiles. Preserve additional checks that address actual product behavior.
|
||||
Update in-repository callback callers and fixtures to provide small valid Go
|
||||
modules with an effective default suite. A callback fixture must exercise
|
||||
its intended callback behavior after that suite succeeds.
|
||||
5. Update facade GoDoc, `docs/config.md`, `docs/cli.md`, check/publish consumer
|
||||
guides, examples, and affected internal documentation. Explain migration:
|
||||
rename the callback and remove standard-suite invocations from custom checks.
|
||||
|
||||
**Completion evidence:** Through the public facade, prove that a failed standard
|
||||
suite prevents the additional callback and publication, that an additional
|
||||
failure prevents publication while preserving error identity, and that a
|
||||
successful publication runs the standard suite and additional checks once for
|
||||
its captured candidate. Reuse existing mutation/recheck tests with the new
|
||||
callback. One CLI profile test covers ordered extra commands. Keep callback
|
||||
unit coverage and end-to-end suite-count coverage at distinct boundaries.
|
||||
|
||||
**Completed:** `AdditionalChecks` now runs after the standard offline suite in
|
||||
the public check and publish flows; selected builds remain after both. The CLI
|
||||
keeps ordered JSON `checks` as additional commands, and the bundled profiles no
|
||||
longer repeat the standard suite. Facade tests prove suite failure stops checks
|
||||
and publication, additional-check errors retain identity, and successful
|
||||
publication runs both once for its captured candidate. CLI coverage verifies
|
||||
ordered checks. The full offline suite, API boundary check, and documentation
|
||||
whitespace checks pass.
|
||||
|
||||
## Stage 4 — Consolidate artifact identity and declaration rules
|
||||
|
||||
**Covers:** artifact portion of F8. **Primary owners:** `internal/build/`,
|
||||
`internal/delivery/assets.go`, `cmd/releasekit/internal/cli/receipt.go`.
|
||||
|
||||
1. Add a small internal artifact-contract owner for target normalization,
|
||||
filename-component validation, artifact names, and the expected declaration
|
||||
for a build. Choose `internal/artifact` for these shared pure rules.
|
||||
2. Move the existing rules from builder, receipt, and delivery into that owner.
|
||||
Preserve accepted inputs, target order/deduplication, filenames, manifest
|
||||
naming, and validation meaning. Keep build execution in `internal/build`,
|
||||
hosted-content checks in delivery/Gitea, and receipt JSON/path handling in
|
||||
the CLI adapter.
|
||||
3. Use ordinary conversions at facade and receipt boundaries. Preserve
|
||||
facade-owned public types and the current private receipt format. Consolidate
|
||||
repeated declaration comparisons while retaining boundary-specific checks
|
||||
for repository, commit, version, file location, and actual file contents.
|
||||
4. Update the internal package inventory. Keep exact public build/result
|
||||
contracts in GoDoc and private receipt lifecycle in its existing owner.
|
||||
|
||||
**Completion evidence:** Existing build-to-receipt-to-delivery tests retain
|
||||
behavior for normalized targets, filenames, altered files, mismatched identity,
|
||||
and manifests. Add only missing coverage for disagreement between these
|
||||
boundaries. The API/dependency checker confirms that the shared internal owner
|
||||
has not leaked through exported signatures or runtime dependencies.
|
||||
|
||||
**Completed:** `internal/artifact` now owns target normalization, filename
|
||||
components, binary declarations, and checksum-manifest naming. The builder,
|
||||
receipt adapter, and delivery validation share those rules while retaining
|
||||
their build, receipt-path/file, and hosted-content responsibilities. Existing
|
||||
coverage plus a mismatched delivery declaration check preserve cross-boundary
|
||||
behavior. Focused tests, the full offline suite, API boundary checks, and
|
||||
documentation whitespace checks pass.
|
||||
|
||||
## Stage 5 — Make delivery outcomes disjoint and actionable
|
||||
|
||||
**Covers:** F7. **Primary owners:** `internal/gitea/upload.go`, delivery result
|
||||
GoDoc, CLI delivery reporting, and their tests.
|
||||
|
||||
1. Define the five collections as current observations for each reported asset.
|
||||
`Matching` means existing matching content; `Uploaded` means confirmed upload
|
||||
during this invocation; `Pending` means known missing work; `Conflicting`
|
||||
means a detected conflict; `Uncertain` means unresolved state. Each asset
|
||||
appears in at most one collection in a returned result.
|
||||
2. In every upload/reconciliation branch, remove an asset from `Pending` when
|
||||
moving it to matching, uploaded, conflicting, or uncertain. In particular,
|
||||
fix failed reconciliation reads, conflicts, and unresolved writes. Later
|
||||
known-missing assets can remain pending when an earlier upload stops work.
|
||||
3. Preserve the existing overall delivery states and their handling of remote
|
||||
writes. Early failures can return incomplete asset information. Category
|
||||
exclusivity establishes no claim that every declaration has been observed.
|
||||
4. Keep concise state-based recovery guidance in one CLI formatter: correct
|
||||
local/preflight failures before retrying; retry partial delivery after fixing
|
||||
its cause; resolve uncertain remote state before retrying; investigate
|
||||
conflicting content and use a new version when source or published contents
|
||||
require correction. Mention retained original artifacts when a rebuild would
|
||||
conflict. Go callers use the documented overall state and asset categories.
|
||||
5. Update delivery GoDoc, `docs/cli.md`, the delivery consumer guide and Gitea
|
||||
integration documentation. Keep diagnostics available alongside the summary.
|
||||
|
||||
**Completion evidence:** Update the existing reconciliation-read-failure test
|
||||
that currently expects overlap. Extend existing upload tests to cover conflict,
|
||||
missing-after-ambiguous-upload, matching-after-lost-acknowledgment, and later
|
||||
pending assets. Assert category exclusivity and meaningful overall state at the
|
||||
upload boundary. CLI tests verify recovery meaning and exit classification
|
||||
without freezing full diagnostic wording.
|
||||
|
||||
**Completed:** Delivery asset categories now contain disjoint current
|
||||
observations, with later known-missing assets retained when an earlier upload
|
||||
stops work. CLI failures include state-based recovery guidance, while GoDoc and
|
||||
the delivery and Gitea guides describe category meaning and incomplete early
|
||||
observations. Upload and CLI tests cover reconciliation outcomes, recovery
|
||||
classification, and category exclusivity. The full offline suite, API boundary
|
||||
check, and documentation whitespace checks pass.
|
||||
|
||||
## Stage 6 — Give the facade ownership of build-and-deliver
|
||||
|
||||
**Covers:** F5. **Primary owners:** `delivery.go`, `internal/delivery/`,
|
||||
`internal/build/`, and existing temporary-directory helpers.
|
||||
|
||||
1. Change `DeliveryRequest.Build` to `*BuildSpec`. Add
|
||||
`Prebuilt *BuildResult` and `Output io.Writer`. `Build` requests managed builds;
|
||||
`Prebuilt` supplies an existing result. Supplying both is an invalid request
|
||||
because the operation needs one artifact source. With neither, or with an
|
||||
empty selected target set, ordinary delivery is page-only. Preserve the
|
||||
existing handling of empty prebuilt results.
|
||||
2. Implement the reusable orchestration inside `internal/delivery`; the public
|
||||
facade performs conversions. Verify version, product, local tag/HEAD
|
||||
agreement, checkout cleanliness, and the committed release note before
|
||||
compilation. Preserve historical lightweight-tag and detached-HEAD support.
|
||||
3. For nonempty `Build`, create temporary output outside the worktree using the
|
||||
existing helper, invoke the shared builder, and feed its result into the
|
||||
existing asset validation/delivery path. Defer cleanup for success, failure,
|
||||
and cancellation. Return diagnostic progress through `Output`; managed
|
||||
temporary paths have no caller-owned lifetime.
|
||||
4. Before hosted writes, retain the tagged-source eligibility check and the
|
||||
build-result, file-digest, and manifest checks. A checkout change during the
|
||||
build must fail eligibility. Use the same captured tag commit to read the
|
||||
note and validate the build. Reuse the existing builders and delivery client.
|
||||
5. `Prebuilt` retains caller-owned files and existing source/identity/content
|
||||
checks. Its build result declares its targets as today. The CLI continues
|
||||
comparing receipts with the selected profile. This path supports original
|
||||
bytes across retries; callers own retention and cleanup.
|
||||
6. Keep pre-remote build/preflight failures `DeliveryNotAttempted`. Preserve
|
||||
candidate identity when known, wrapped error causes, cancellation, and the
|
||||
current mapping of hosted failures and partial progress.
|
||||
7. Update all Go callers for the request shape. As an intermediate step, map
|
||||
the CLI's current already-built result to `Prebuilt`; Stage 7 removes that
|
||||
duplicate orchestration. Update delivery GoDoc and the consumer guide with
|
||||
the normal `Build` path and the explicit `Prebuilt` lifecycle.
|
||||
|
||||
**Completion evidence:** Add facade-level tests using a real small Go consumer
|
||||
and a local HTTP server for managed binary delivery and page-only delivery.
|
||||
Prove invalid tagged source fails before Go compilation or hosted writes,
|
||||
build failure prevents hosted writes, and managed temporary output is cleaned
|
||||
on success and failure. Extend existing mutation/cancellation coverage where
|
||||
needed. Preserve prebuilt retry, digest conflict, note conflict, and source
|
||||
eligibility coverage. Confirm the two facades' dependency boundaries.
|
||||
|
||||
**Completed:** `Deliver` now owns optional managed builds, page-only requests,
|
||||
and explicit prebuilt artifact delivery behind the public facade. Managed output
|
||||
uses temporary storage outside the checkout and is cleaned after success,
|
||||
failure, and cancellation; source and note checks precede compilation, and
|
||||
eligibility is rechecked before hosted writes. Prebuilt files remain
|
||||
caller-owned. Consumer and internal package guides describe these paths.
|
||||
Facade-level consumer and HTTP tests cover managed upload, page-only delivery,
|
||||
preflight and build failures, checkout mutation, cleanup, cancellation, and
|
||||
prebuilt ownership. The full offline suite, API boundary check, and
|
||||
documentation whitespace checks pass.
|
||||
|
||||
## Stage 7 — Route ordinary CLI delivery through the facade
|
||||
|
||||
**Covers:** the CLI portion of F5. **Primary owners:**
|
||||
`cmd/releasekit/main.go`, CLI receipt adapters, CLI tests and documentation.
|
||||
|
||||
1. Change ordinary `runDelivery` to pass the configured `BuildSpec` and output
|
||||
writer directly to `Deliver`. Remove its temporary-directory and standalone
|
||||
build coordination. Keep profile parsing, credential lookup, presentation,
|
||||
and exit-code selection in the CLI.
|
||||
2. Retain `build --output` and `deliver --assets`. The latter loads and verifies
|
||||
the private receipt, compares it with the selected profile, and supplies
|
||||
`Prebuilt`. Keep stale-receipt invalidation and standalone build behavior.
|
||||
3. Share the final CLI-to-facade delivery adapter so the CI entry point in Stage
|
||||
9 can use it after preparation. Keep ordinary `deliver` free of dependency
|
||||
downloading and checkout mutation.
|
||||
4. Update CLI/configuration guidance and examples to make one `deliver`
|
||||
invocation the normal path. Describe split build/delivery for retained bytes
|
||||
and credential separation. Preserve exit statuses 0, 1, 2, and 3.
|
||||
|
||||
**Completion evidence:** CLI tests cover source-only and binary profiles,
|
||||
preflight failure before compilation, token/profile errors, and the explicit
|
||||
receipt path. Reuse Stage 6 for domain failure coverage. Confirm the maintained
|
||||
ordinary command exercises the facade-owned lifecycle and reports F7's results.
|
||||
|
||||
**Completed:** Ordinary `deliver` now passes configured builds and progress
|
||||
output directly to the public facade; the CLI retains profile, credential,
|
||||
receipt, presentation, and exit-status handling. `--assets` still validates
|
||||
the private receipt and supplies caller-owned artifacts. CLI tests cover
|
||||
page-only and binary profiles, preflight rejection before build progress,
|
||||
retained prebuilt artifacts, retry observations, and temporary-output cleanup.
|
||||
The binary workflow and consumer guidance use one `deliver` invocation by
|
||||
default and explain the separate `build`/`--assets` path. The full offline suite,
|
||||
API boundary check, and documentation whitespace checks pass.
|
||||
|
||||
## Stage 8 — Add reusable CI preparation operations
|
||||
|
||||
**Covers:** preparation ownership in F6. **Primary owners:** a new root
|
||||
`preparation.go`, `internal/git/`, `internal/gotool/`, and a small internal
|
||||
preparation coordinator.
|
||||
|
||||
1. Add facade-owned `TaggedCheckoutRequest` with `RepositoryDir`, `Version`,
|
||||
`Remote`, and `ExpectedCommit` strings, and
|
||||
`PrepareTaggedCheckout(context.Context, TaggedCheckoutRequest) error`.
|
||||
An empty remote selects `origin`. This is an explicit preparation operation
|
||||
for disposable CI checkouts; ordinary delivery keeps its current behavior.
|
||||
2. Validate the version and required expected commit before mutation. Fetch
|
||||
the selected tag from the selected remote with an explicit tag refspec,
|
||||
verify that its peeled commit equals the expected CI commit, detach checkout
|
||||
at that commit, and verify HEAD agreement. Use the existing Git subprocess
|
||||
boundary and preserve Git errors. Use ordinary checkout/fetch behavior;
|
||||
conflicting local changes or tags are reported for the operator to resolve.
|
||||
3. Add `PrepareBuildDependencies(context.Context, string) error`, taking the
|
||||
repository directory. Internally run `go mod download` with the available
|
||||
compatible local Go toolchain and workspace discovery disabled. Preparation
|
||||
uses the caller's dependency-access settings, including proxy/private-module
|
||||
configuration and caches. This operation is explicitly network-capable.
|
||||
Keep offline test/build environments from Stage 2 distinct from preparation.
|
||||
4. Keep both operations behind the root facade with internal implementations.
|
||||
These two additions serve the concrete shared CI workflow and Go consumers
|
||||
with the same preparation needs. Keep their API small: CI-provider variables,
|
||||
JSON profile loading, credentials, and output formatting stay in adapters.
|
||||
5. Add GoDoc and a short preparation section to the delivery consumer guide;
|
||||
update the internal package inventory. State filesystem/network effects and
|
||||
cancellation behavior. Preparation does not publish a tag or hosted content.
|
||||
|
||||
**Completion evidence:** Local Git fixtures verify expected-commit agreement,
|
||||
wrong-tag rejection before checkout, detached checkout, and ordinary local
|
||||
conflict behavior. A subprocess-boundary test verifies dependency preparation
|
||||
uses the repository and preparation environment and propagates failure and
|
||||
cancellation. Keep default tests offline with a local module cache or a small
|
||||
Go-command fixture; no live module server is needed.
|
||||
|
||||
**Completed:** The root facade now exposes `PrepareTaggedCheckout` and
|
||||
`PrepareBuildDependencies`. Checkout preparation fetches an explicit tag
|
||||
refspec, compares the peeled commit with the expected full object ID, and
|
||||
detaches only after a match; tests cover default and selected remotes, wrong
|
||||
commits, conflicting local edits and tags, and input rejection before fetch.
|
||||
Dependency preparation runs `go mod download` with workspace discovery off and
|
||||
the local Go toolchain, preserving caller proxy, private-module, and cache
|
||||
settings; subprocess fixtures verify repository selection, failure details,
|
||||
and cancellation without network access. GoDoc, the delivery consumer guide,
|
||||
and the internal inventory describe effects and ownership. The full offline
|
||||
suite, API boundary check, and documentation whitespace checks pass.
|
||||
|
||||
## Stage 9 — Add the shared CI delivery command
|
||||
|
||||
**Covers:** the shared command portion of F6.
|
||||
**Primary owners:** CLI parsing/routing, CLI command tests, `docs/cli.md`,
|
||||
and `docs/config.md`.
|
||||
|
||||
1. Add:
|
||||
|
||||
```text
|
||||
releasekit ci-deliver [--repo DIR] [--config FILE] [--remote NAME] --commit OID VERSION
|
||||
```
|
||||
|
||||
Options precede the version, consistent with existing commands. Repository
|
||||
and profile defaults match `deliver`; remote defaults to `origin`. The
|
||||
explicit command authorizes preparation of the selected CI checkout.
|
||||
2. Call `PrepareTaggedCheckout`, then load the profile from that checked-out
|
||||
source, then validate the selected delivery configuration and credentials.
|
||||
When the profile selects binaries, call `PrepareBuildDependencies`. Finish
|
||||
through Stage 7's ordinary delivery adapter and `Deliver`. Page-only profiles
|
||||
skip application dependency preparation and binary work. Read custom profile
|
||||
paths under the existing CLI path rules.
|
||||
3. Keep the provider adapter declarative: Woodpecker supplies `CI_WORKSPACE`,
|
||||
`CI_COMMIT_SHA`, and `CI_COMMIT_TAG` as command arguments. The library and
|
||||
ordinary CLI operations remain independent of Woodpecker environment names.
|
||||
Preparation failures return 1; argument/profile/credential errors return 2;
|
||||
final delivery uses the existing success/failure/unknown status mapping.
|
||||
4. Update command usage, `docs/cli.md`, and configuration guidance for the new
|
||||
entry point, its preparation effects, profile-loading order, and exit codes.
|
||||
Keep ordinary `deliver` documented as operating on prepared source.
|
||||
|
||||
**Completion evidence:** Exercise the command with local Git/HTTP fixtures for
|
||||
source-only and binary delivery. Prove the profile is read after checkout,
|
||||
a wrong CI commit fails before application builds or hosted writes, and a
|
||||
source-only module with unavailable dependencies still reaches page delivery.
|
||||
Reuse facade tests for the individual preparation and delivery operations.
|
||||
|
||||
**Completed:** `ci-deliver` now prepares the tagged checkout against the
|
||||
provider-supplied commit, loads the profile from that checkout, validates its
|
||||
delivery settings and credential, downloads dependencies only for selected
|
||||
binary targets, and finishes through the existing delivery facade. Local
|
||||
Git/HTTP fixtures cover source-only and binary delivery, relative custom profile
|
||||
loading, commit mismatch before Go or hosted requests, and unavailable
|
||||
source-only dependencies. CLI and configuration guidance describe preparation,
|
||||
provider arguments, effects, and exit statuses. The full offline suite, API
|
||||
boundary check, and documentation whitespace checks pass.
|
||||
|
||||
## Stage 10 — Consolidate and exercise maintained CI templates
|
||||
|
||||
**Covers:** installation, workflow duplication, and artifact-testing in F6.
|
||||
**Primary owners:** `examples/woodpecker/`, CLI workflow tests, installation
|
||||
instructions, and the product roadmap.
|
||||
|
||||
1. Select versioned source execution as the default bootstrap:
|
||||
`go run gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@PIN ci-deliver ...`.
|
||||
`PIN` is an immutable ReleaseKit revision or published version. Applications
|
||||
choose a compatible Go/Git image and provision the delivery token. The shared
|
||||
command owns checkout checks, conditional dependency preparation, and delivery.
|
||||
The normal Go caches suffice; optional CI cache mounts remain deployment
|
||||
configuration. Document `go install ...@PIN` for a locally retained executable
|
||||
and one upgrade procedure based on changing the selected version.
|
||||
2. Consolidate source-only and binary Woodpecker templates into one maintained
|
||||
`examples/woodpecker/tag-delivery.yml`, with the product profile selecting
|
||||
page-only or binary behavior. Remove the two superseded templates and repair
|
||||
their links. Retain the distinct first-release bootstrap in
|
||||
`releasekit-source-delivery.yml`, since ReleaseKit's own first source release
|
||||
must build its tool from the tagged source. Simplify it around the shared
|
||||
command where this preserves that bootstrap.
|
||||
3. Replace tests that reconstruct the workflow commands with checks tied to the
|
||||
maintained artifact. Use a small extractor for the template's one command
|
||||
block and execute it with controlled CI variables, local Git/HTTP fixtures,
|
||||
and a Go bootstrap shim that maps the pinned remote tool invocation to the
|
||||
CLI built from the test checkout. Validate the module/command/version
|
||||
arguments in the shim. Apply the template's matrix substitutions and
|
||||
Woodpecker dollar escaping before shell execution. Keep the template subset
|
||||
simple enough for a small test helper; a general YAML runner is unnecessary.
|
||||
4. Document bootstrap requirements, token provision, compatible Go selection,
|
||||
optional caches, dependency preparation, and the version upgrade procedure.
|
||||
Align `releasekit.md`'s remaining adoption work with source installation;
|
||||
identify live deployment and the real immutable pin as remaining work.
|
||||
|
||||
**Completion evidence:** Execute the actual maintained command block for both
|
||||
source-only and binary fixture delivery. A repeated invocation preserves
|
||||
matching remote content. The bootstrap shim proves template wiring, not
|
||||
published-module availability. Record that distinction and retain real
|
||||
installation/live Woodpecker verification as deployment work.
|
||||
|
||||
**Completed:** Source-only and binary consumer delivery now share one
|
||||
profile-driven `tag-delivery.yml` using versioned `go run ... ci-deliver`; the
|
||||
duplicated templates were removed. ReleaseKit's separate first-source workflow
|
||||
still builds its CLI from tagged source and then uses `ci-deliver`. CLI workflow
|
||||
tests extract and execute the maintained command blocks with matrix
|
||||
substitution, Woodpecker dollar escaping, local Git/HTTP fixtures, and a Go
|
||||
bootstrap shim. Both profiles deliver successfully twice, preserving matching
|
||||
pages and binary assets. The shim validates command wiring but does not prove
|
||||
published-module availability. Consumer and maintainer guidance now covers
|
||||
bootstrap requirements, credentials, Go compatibility, caches, dependency
|
||||
preparation, and pin upgrades. Real pins and live integration remain deployment
|
||||
work. The full offline suite, API boundary check, and documentation whitespace
|
||||
checks pass.
|
||||
|
||||
## Stage 11 — Validate representative adoption and close the sprint
|
||||
|
||||
**Covers:** audit-wide acceptance and adoption evidence. **Primary owners:**
|
||||
existing external-consumer fixtures, consumer guidance, this plan, and the
|
||||
remaining-work section of `releasekit.md`.
|
||||
|
||||
1. Exercise a source-only consumer with one meaningful extra check and a binary
|
||||
consumer using `buildinfo`, selected targets, and Gitea delivery. Reuse and
|
||||
extend the fixtures from prior stages. Verify publication through local Git
|
||||
remotes and delivery through local HTTP fixtures as separate operations.
|
||||
2. Review available sibling projects named by the product roadmap read-only.
|
||||
Use PromptKit and Narratio as the source-only and binary representatives.
|
||||
Record a concise migration assessment: retained product settings/checks,
|
||||
release code and repeated tests that can be deleted, runtime-version
|
||||
adaptation, and required policy
|
||||
or procedure changes. Label projected deletions as estimates. If a sibling
|
||||
checkout is unavailable, use the audit evidence and label its verification
|
||||
date. Keep implementation tests self-contained in ReleaseKit.
|
||||
3. Assess the final user workflow against the audit: standard tests once,
|
||||
additional checks declared once, one ordinary delivery invocation, one
|
||||
versioned CI entry point, clear recovery, and shared artifact/build rules.
|
||||
Address implementation gaps within their existing stage scope before closing
|
||||
the sprint. Record any new product decision as such.
|
||||
4. Reconcile GoDoc, CLI/configuration references, consumer guides, maintained
|
||||
examples, internal inventory, and the product roadmap with implemented
|
||||
behavior. Keep the audit's original evidence historical. Record completion
|
||||
here and link to the remaining adoption/deployment work.
|
||||
5. Run the standard offline suite and API checks on the final implementation.
|
||||
Run them with the minimum supported Go 1.25 toolchain when available in the
|
||||
implementation environment; otherwise record that verification limitation
|
||||
explicitly. Minimum-version verification is evidence about the existing
|
||||
module requirement, rather than a new permanent release matrix.
|
||||
6. Leave source publication, real installation verification, credentials,
|
||||
workflow activation, live service checks, and changes in sibling repositories
|
||||
for their deployment/adoption tasks. Follow the maintainer release procedure
|
||||
when a release is separately requested. Keep ReleaseKit's own deliverables
|
||||
source-only under the current release policy.
|
||||
|
||||
**Completion evidence:** A concise final record identifies the passing checks,
|
||||
representative workflows, projected adoption savings, implemented API/profile
|
||||
migration, and remaining deployment work. Every F1–F8 finding has an implemented
|
||||
resolution and appropriately scoped evidence. Review and commit the final
|
||||
changes with a clean worktree.
|
||||
|
||||
**Completed:** The source-only consumer publication fixture runs one meaningful
|
||||
compatibility check against its committed note and module, then confirms the
|
||||
annotated tag on a local Git remote. A separate binary consumer fixture builds
|
||||
`buildinfo` binaries for selected Linux targets, checks native version output,
|
||||
and delivers both binaries plus `SHA256SUMS` to a local HTTP Gitea fixture.
|
||||
PromptKit and Narratio were reviewed read-only on 2026-10-06; the product
|
||||
roadmap records retained settings, runtime and policy/procedure adaptations,
|
||||
and projected deletion ranges. No sibling repositories were changed.
|
||||
|
||||
The final documentation review reconciled GoDoc, CLI/configuration references,
|
||||
consumer guidance, Woodpecker examples, the internal inventory, and product
|
||||
roadmap. The pre-release API migration is `Validate` to `AdditionalChecks` and
|
||||
`DeliveryRequest.Build` to `*BuildSpec`, with `Prebuilt` for retained artifacts;
|
||||
JSON `checks` remains the ordered additional-check setting. No new product
|
||||
decision was required. The completed stages address F1–F8; real source
|
||||
publication, an immutable tool pin, credentials, workflow activation, and live
|
||||
Gitea/Woodpecker verification remain deployment work.
|
||||
|
||||
The full offline suite and API boundary check pass with Go 1.25.0. Go formatting,
|
||||
documentation whitespace, and changed local-link checks pass.
|
||||
|
||||
## Open Questions
|
||||
|
||||
No unresolved product choice is required to implement these stages. The
|
||||
selected approaches and rationale are recorded in the audit's design choices.
|
||||
Real deployment pins, credentials, service availability, and per-application
|
||||
migration scheduling are inputs to subsequent deployment/adoption work. They
|
||||
are separate from the implementation acceptance criteria above.
|
||||
@@ -1,7 +1,7 @@
|
||||
# ReleaseKit: shared release process
|
||||
|
||||
Status: Initial implementation, policy adoption, and architecture remediation
|
||||
are complete. Consumer adoption, publication, and live integration work remain.
|
||||
are complete. Consumer adoption and live CI integration work remain.
|
||||
|
||||
This roadmap records the shared release-process opportunity identified in
|
||||
PromptKit, ConfigKit, Audita, Notarius, Narratio, and Scriptorium on 2026-09-29,
|
||||
@@ -227,20 +227,23 @@ publication and delivery operations.
|
||||
|
||||
## Remaining work
|
||||
|
||||
- Prepare and publish the first ReleaseKit source release under the
|
||||
[maintainer procedure](../release.md), then deliver its hosted note page.
|
||||
- Use the [v0.1.0 baseline](../releases/v0.1.0.md) for initial consumer integration
|
||||
under the [maintainer procedure](../release.md).
|
||||
- Choose the broader consumer integration test plan and migration sequence.
|
||||
Evaluate API clarity, product-specific checks, and the infrastructure removed
|
||||
from each consuming repository.
|
||||
- Replace the maintained example's ReleaseKit version placeholder with a real
|
||||
immutable revision or published version. Provision delivery credentials and
|
||||
activate consumer Woodpecker workflows as part of deployment.
|
||||
- Provision delivery credentials and activate consumer Woodpecker workflows
|
||||
using the maintained example's `v0.1.0` pin or a later selected immutable
|
||||
version as part of deployment.
|
||||
- Verify live Gitea delivery and Woodpecker execution. Existing verification uses
|
||||
local Git and HTTP fixtures; no live deployment has been verified.
|
||||
- Keep ReleaseKit executable binary distribution deferred until deliverables
|
||||
are deliberately selected. Selecting binaries would require delivery
|
||||
declarations, target checks, automation responsibilities, and corresponding
|
||||
release policy and procedure updates.
|
||||
- Evaluate a maintained ReleaseKit CI image or specialized validation/build
|
||||
settings when a demonstrated consumer need justifies their maintenance cost
|
||||
under [ADR 0002](../adr/0002-routine-releases.md).
|
||||
|
||||
## Reviewed implementations
|
||||
|
||||
|
||||
@@ -1,164 +0,0 @@
|
||||
# ReleaseKit audit follow-up review
|
||||
|
||||
Date: 2026-10-06.
|
||||
Reviewed source: `55333b0`.
|
||||
Status: Complete. R1 and R2 are resolved.
|
||||
|
||||
## Scope and assessment
|
||||
|
||||
Reviewed the changes since `536a579` against the [audit](audit.md), completed
|
||||
[implementation plan](implementation.md), [architecture policy](../policy/architecture.md),
|
||||
and [routine-release decision](../adr/0002-routine-releases.md). The worktree
|
||||
was clean at the start of the review.
|
||||
|
||||
The selected architecture is substantially implemented. One Go module exposes
|
||||
the root orchestration facade and lightweight `buildinfo` runtime facade.
|
||||
Internal packages own candidate validation, Git publication and recovery,
|
||||
Go environments, artifact declarations, managed delivery builds, Gitea effects,
|
||||
and explicit CI preparation. The CLI adapts profiles, credentials, output, and
|
||||
exit statuses. Standard validation precedes additive product checks; ordinary
|
||||
delivery uses one facade-owned build-and-deliver operation. The maintained
|
||||
consumer workflow invokes the shared versioned CI command.
|
||||
|
||||
The audit's F1–F8 changes are present, with behavioral tests for their selected
|
||||
contracts. R1 below identifies a new defect in the shared Go-environment owner;
|
||||
R2 identifies increased test cost and coupling introduced by additive validation.
|
||||
The review found no additional public-type ownership or dependency-direction
|
||||
gap. The deliberate additive-check, baseline-build, managed-delivery, and CI
|
||||
preparation decisions remain appropriate. The findings call for implementation
|
||||
repairs within those decisions.
|
||||
|
||||
## R1 — Medium: Go discovery treats successful diagnostics as invalid configuration
|
||||
|
||||
Status: Resolved.
|
||||
Category: Correctness and an accidental environment prerequisite.
|
||||
Introduced by: `0809312`.
|
||||
|
||||
**Evidence:** [Go configuration discovery](../../internal/gotool/gotool.go)
|
||||
routes both stdout and stderr into the same buffer in `discover` (lines
|
||||
189–205). `New` parses that combined output as JSON (lines 59–81). A successful
|
||||
`go env -json` invocation with a warning therefore becomes a decoding failure.
|
||||
This affects candidate validation and nonempty builds through their shared owner.
|
||||
|
||||
**Reproduction:** Create a clean `main` repository with a Go 1.25 module, a
|
||||
passing test, a matching committed note, and a source-only product profile.
|
||||
Set `GOPATH` to the installed Go toolchain's `GOROOT`. On Go 1.26.8,
|
||||
`go test -mod=readonly -count=1 ./...` succeeds with a warning on stderr.
|
||||
`releasekit check --repo DIR v1.2.3` fails before running that suite:
|
||||
|
||||
```text
|
||||
prepare Go toolchain: decode Go host settings: invalid character 'w' looking for beginning of value
|
||||
```
|
||||
|
||||
The warning-producing configuration is discouraged by Go, but the Go command
|
||||
accepts it. ReleaseKit's selected environment contract preserves effective
|
||||
operational settings; it establishes no requirement that successful discovery
|
||||
produce an empty diagnostic stream. The same decoding failure follows from any
|
||||
successful discovery command that emits stderr alongside valid stdout JSON.
|
||||
|
||||
**Required remediation:** Capture configuration stdout and diagnostics
|
||||
separately. Parse stdout as JSON and retain stderr for command-failure reporting
|
||||
or ordinary diagnostics. Preserve subprocess error identity, cancellation,
|
||||
effective operational settings, and the selected validation/build environments.
|
||||
|
||||
**Focused verification:** A controlled Go-command fixture returns valid JSON on
|
||||
stdout, a diagnostic on stderr, and exit 0; discovery succeeds and preserves
|
||||
the settings. A failing command retains useful stderr and its cause. Existing
|
||||
ambient/persistent flag, host-target, cache, and architecture-tuning regressions
|
||||
continue to pass. These checks add no warning-free configuration requirement.
|
||||
|
||||
**Resolution (2026-10-07):** Discovery captures stdout and stderr separately,
|
||||
parses configuration from stdout, and preserves diagnostic output and subprocess
|
||||
causes on failure. A subprocess fixture proves successful JSON discovery accepts
|
||||
stderr diagnostics and preserves host/cache settings; another verifies failure
|
||||
diagnostics and exit-error identity. The success regression failed before the
|
||||
fix. Go-environment, candidate-validation, and build regression checks pass.
|
||||
|
||||
## R2 — Medium: Wrapper regression testing repeats the project suite inside itself
|
||||
|
||||
Status: Resolved.
|
||||
Category: Test maintainability and development cost.
|
||||
Introduced by: `3e9b5c1`.
|
||||
|
||||
**Evidence:** [The wrapper regression](../../cmd/releasekit/release_wrapper_test.go)
|
||||
clones the complete repository for each exit-status scenario, overlays a
|
||||
hand-maintained list of production and test files (lines 32–45), and invokes
|
||||
the source publication wrapper. The success, rejected-push, and unknown-push
|
||||
scenarios each run the project's default suite inside the parent suite.
|
||||
An inherited `RELEASEKIT_SKIP_WRAPPER_TEST` flag prevents recursive execution
|
||||
of this one test, while the other publication, delivery, build, and workflow
|
||||
tests run again in each clone.
|
||||
|
||||
During this review, process inspection confirmed the nested native publisher,
|
||||
`go test ./...`, and cloned test binaries. The uncached offline suite passed;
|
||||
the root package took 40.751 seconds and the CLI package took 115.533 seconds
|
||||
on this host. These timings are observations, not proposed test-duration limits.
|
||||
|
||||
The extra executions provide little distinct evidence about wrapper exit-code
|
||||
preservation. The file overlay also couples the fixture to unrelated package
|
||||
changes and supplies only selected uncommitted files, so development checks can
|
||||
exercise a mixture of the current worktree and committed source.
|
||||
|
||||
**Required remediation:** Keep the real source-bootstrap wrapper and local Git
|
||||
exit-status scenarios, while giving their candidate validation a small,
|
||||
self-contained test fixture. Assemble the tool source consistently from the
|
||||
version being tested. Replace the manually maintained production/test overlay
|
||||
and suite-recursion skip mechanism with a fixture that exercises wrapper
|
||||
behavior without rerunning ReleaseKit's complete test suite. Retain the actual
|
||||
publication and recovery behavior already protected by this regression.
|
||||
|
||||
**Focused verification:** The real wrapper still preserves success 0, known
|
||||
failure 1, invalid input 2, and uncertain publication 3. The candidate fixture
|
||||
runs its standard suite, and captured-endpoint recovery still finds the
|
||||
intended object with separate fetch and push repositories. The outer default
|
||||
suite supplies the project's broader behavioral evidence once. Use test scope
|
||||
and command observations for verification rather than a wall-clock gate.
|
||||
|
||||
**Resolution (2026-10-07):** Wrapper fixtures capture the current nonignored
|
||||
source, including tracked and untracked worktree changes, through one inventory.
|
||||
They exclude the project's test files and add one small candidate test with an
|
||||
external validation log. The manually maintained overlay and recursion skip
|
||||
flag are removed. The real source-bootstrap wrapper preserves statuses 0, 1,
|
||||
2, and 3; the validation log confirms one suite execution for each valid
|
||||
candidate and none for invalid input. Captured-endpoint recovery and URL-rewrite
|
||||
guards still pass with separate fetch and push repositories.
|
||||
|
||||
The focused wrapper regression passes in 7.964 seconds on this host. The final
|
||||
uncached offline suite passes, with the CLI package taking 22.842 seconds.
|
||||
These measurements record the observed reduction in duplicated work and add
|
||||
no duration requirement.
|
||||
|
||||
## Completion verification
|
||||
|
||||
Both fixes are implemented with focused regression evidence. The complete
|
||||
offline suite and compiled API/dependency checker pass with Go 1.26.8 on
|
||||
Linux/amd64 using the commands below. Documentation link and whitespace checks
|
||||
pass. Each remediation unit is committed separately with a plain English
|
||||
message. Production changes are confined to Go configuration discovery; the
|
||||
wrapper change preserves the existing publication and recovery contracts.
|
||||
|
||||
## Validation and remaining scope
|
||||
|
||||
The following checks passed on the reviewed source and after remediation with
|
||||
Go 1.26.8 on Linux/amd64:
|
||||
|
||||
```sh
|
||||
GOWORK=off GOPROXY=off GONOPROXY=none GOSUMDB=off GOTOOLCHAIN=local \
|
||||
go test -mod=readonly -count=1 ./...
|
||||
GOWORK=off GOPROXY=off GOTOOLCHAIN=local go run ./internal/apicheck
|
||||
```
|
||||
|
||||
The R1 reproduction used a temporary committed consumer repository and a native
|
||||
CLI built from the reviewed source. Publication and delivery suite checks used
|
||||
local Git and HTTP fixtures. No consuming repository was changed, release was
|
||||
published, deployment was activated, or live hosted delivery was performed.
|
||||
This review did not rerun minimum-Go-1.25 validation; the completed implementation
|
||||
plan records that earlier verification. Real installation, consumer migration,
|
||||
credentials, and live CI/Gitea verification remain adoption/deployment work in
|
||||
the [product roadmap](releasekit.md).
|
||||
|
||||
R1's implicit warning-free discovery prerequisite is the additional restriction
|
||||
identified by this review. The review found no further strengthened guarantee
|
||||
requiring remediation. Preserve existing published-content immutability and the
|
||||
ordinary source-eligibility observations; the findings require no reproducible
|
||||
build promise, stronger concurrency guarantee, or additional release gate.
|
||||
@@ -1,7 +1,7 @@
|
||||
matrix:
|
||||
include:
|
||||
- GO_IMAGE: golang:1.25.0-bookworm
|
||||
RELEASEKIT_VERSION: REPLACE_WITH_IMMUTABLE_VERSION
|
||||
RELEASEKIT_VERSION: v0.1.0
|
||||
|
||||
when:
|
||||
- event: tag
|
||||
|
||||
Reference in New Issue
Block a user