Refocus release audit on developer effort
This commit is contained in:
@@ -1,43 +1,41 @@
|
||||
# ReleaseKit pre-release audit
|
||||
|
||||
Date: 2026-10-06. Reviewed source: `536a57916f6565ae8194c4563577dfcebd6cfb69`.
|
||||
Status: findings and recommendations; no design changes adopted by this document.
|
||||
Status: review findings and proposed changes, revised for the clarified product goals.
|
||||
Audience: maintainers deciding the shared release standard before `v0.1.0`.
|
||||
|
||||
## Assessment
|
||||
|
||||
ReleaseKit is a sound foundation for the intended standard, but I recommend
|
||||
resolving two reproduced correctness defects and one demonstrated build-standard
|
||||
gap before tagging it. Its publication
|
||||
and delivery separation, narrow public facades, standard artifact naming,
|
||||
version injection, and content-aware delivery retries are worth retaining.
|
||||
The implementation covers most of the mechanics in the
|
||||
[product roadmap](releasekit.md). It does not yet demonstrate both
|
||||
[architectural success criteria](../policy/architecture.md#success-criteria):
|
||||
substantial removal of consumer infrastructure and adoption of one coherent
|
||||
standard. Those require representative adoption evidence.
|
||||
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.
|
||||
|
||||
The main architectural choices have concrete benefits: annotated tags preserve
|
||||
the checked-in note and provide an exact object for recovery; requiring the
|
||||
candidate on authoritative `main` keeps branch publication out of the release
|
||||
transaction; and separate delivery prevents a hosting outage from redefining
|
||||
source-release success. None needs replacement to achieve the stated goals.
|
||||
Selected build targets and product-specific checks are appropriate variation;
|
||||
independent implementations of the publication transaction are not.
|
||||
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.
|
||||
|
||||
The larger design opportunity is to make ReleaseKit own more of the ordinary
|
||||
path: a standard validation baseline, a declared build environment, and shared
|
||||
delivery orchestration usable equally through Go and the CLI. Today, consumers
|
||||
can still supply an entire replacement validation process, repeat CI setup, and
|
||||
assemble binary delivery themselves when using the Go API. These are supported
|
||||
choices, not violations of the present contracts, but they weaken the stated
|
||||
objective of minimizing variation.
|
||||
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.
|
||||
|
||||
Compatibility with existing consumer scripts is not a reason to preserve these
|
||||
choices. The recommendations below favor a coherent long-term standard, while
|
||||
retaining product identity, target selection, compatibility decisions, and
|
||||
product-specific behavioral checks with the consumer. They do not propose
|
||||
mandatory new lint, race, signing, live-service, or approval gates.
|
||||
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
|
||||
|
||||
@@ -45,13 +43,13 @@ 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; its
|
||||
requirements are not automatically imposed on every consumer API operation.
|
||||
[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 was a read-only
|
||||
sample of adoption needs, not an audit or migration of those repositories.
|
||||
Their existing extra checks are evidence to evaluate, not requirements to copy.
|
||||
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.
|
||||
|
||||
@@ -61,14 +59,13 @@ Validation on Linux/amd64 with Go 1.26.8:
|
||||
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;
|
||||
no production refs, credentials, or hosted content were used.
|
||||
below. They used temporary consumer repositories and local bare Git remotes.
|
||||
|
||||
The probes were investigative tests in a disposable checkout, not additions to
|
||||
the default suite. Their setup and outcomes are recorded with each finding so
|
||||
regressions can be written against the intended fixes. No live Gitea or
|
||||
Woodpecker deployment, published-module installation, or minimum-Go-1.25 run was
|
||||
performed. The test pass therefore does not establish those properties.
|
||||
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
|
||||
|
||||
@@ -77,10 +74,10 @@ performed. The test pass therefore does not establish those properties.
|
||||
| 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 leaves important build inputs ambient. |
|
||||
| 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 | Plausible but not demonstrated by consumer adoption. F5–F6 identify remaining orchestration and setup duplication. |
|
||||
| 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
|
||||
@@ -104,27 +101,26 @@ The [Go command documentation](https://pkg.go.dev/cmd/go#hdr-Environment_variabl
|
||||
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 without the complete default suite. The caller need not edit
|
||||
source or intentionally bypass validation.
|
||||
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.
|
||||
Use one internal Go-environment policy shared with the builder where appropriate;
|
||||
do not give validation the builder's `CGO_ENABLED=0` blindly. A standard native
|
||||
test run and a static release build have different needs. Apply the same baseline
|
||||
to ReleaseKit's own profile. Retain a regression that proves a failing test
|
||||
cannot disappear under an ambient filter. F4 and Open Question 1 address how
|
||||
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 Open Question 1 address how
|
||||
intentional product-specific checks should 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) does not call
|
||||
`verifyScopedURLs`, although [Resolve/Recheck](../../internal/git/remote.go)
|
||||
use that verification before publication. Git still applies current URL rewrite
|
||||
configuration to the captured literal URL. The manual recovery instructions in
|
||||
[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.
|
||||
|
||||
@@ -137,25 +133,21 @@ 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 an existing recovery
|
||||
contract; it is not a request for broader filesystem or transport hardening.
|
||||
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`. Do not resolve the remote name anew and substitute its current
|
||||
endpoint. Cover both the successful-publication/false-absence reproduction and
|
||||
an ordinary unchanged-endpoint recovery. No extra read-back gate is needed after
|
||||
a successful push.
|
||||
`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 — High for binary adoption: target identity omits effective build inputs
|
||||
### F3 — Internal improvement: ambient CPU settings change binary compatibility
|
||||
|
||||
**Evidence.** `goEnvironment` in [internal/build/build.go](../../internal/build/build.go)
|
||||
standardizes several Go settings but inherits architecture feature variables,
|
||||
`GOEXPERIMENT`, and the persistent Go environment file. Build identity records
|
||||
GOOS/GOARCH and compiler text, but not those effective inputs. The
|
||||
[receipt](../../cmd/releasekit/internal/cli/receipt.go) and public `BuildResult`
|
||||
cannot distinguish their effects.
|
||||
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`.
|
||||
@@ -165,23 +157,20 @@ 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.** Identical declared targets can require different CPUs and yield
|
||||
conflicting bytes during delivery retries. Existing content comparison correctly
|
||||
refuses replacement, but cannot make an undeclared build environment repeatable.
|
||||
A clean Git checkout does not resolve this; `SourceVerified` correctly makes no
|
||||
attestation claim. This is a gap in the desired shared build standard, rather
|
||||
than a violation of a documented promise of fixed CPU baselines or reproducible
|
||||
bytes. The missing selection should be made deliberately before binary adoption.
|
||||
**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.
|
||||
This finding supports predictable defaults; its earlier high-priority assessment
|
||||
placed too much weight on build-environment standardization.
|
||||
|
||||
**Recommendation.** Select documented baseline architecture features for the
|
||||
supported targets and control the relevant environment and Go configuration
|
||||
file. Choose the release toolchain explicitly and preserve that selection with
|
||||
the tagged declaration or immutable delivery environment. If custom feature
|
||||
levels are supported, declare them and include them in artifact/build identity.
|
||||
Do not silently derive them from a developer shell. Reuse the selected inputs
|
||||
for candidate builds and tagged delivery. See Open Question 2 for the tradeoff
|
||||
between a fixed baseline and richer declared variants. This recommendation does
|
||||
not promise universally reproducible or hermetic builds.
|
||||
**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.
|
||||
Open Question 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
|
||||
|
||||
@@ -193,43 +182,41 @@ 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 alternative release program. This relocates shared
|
||||
policy instead of fully centralizing it. Conversely, simply adding mandatory
|
||||
default tests to the current behavior would run them twice for existing check
|
||||
scripts that already run the suite.
|
||||
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.** Before first adoption, select a baseline-plus-additional-checks
|
||||
model, with a narrow explicit way to express a justified alternative test
|
||||
invocation when necessary. Migrate redundant suite invocations out of consumer
|
||||
scripts. Keep only checks for actual product behavior, such as PromptKit's
|
||||
examples. Do not preserve every consumer's race/vet/build loop merely to avoid
|
||||
breaking their old workflow. This is a proposed contract change, not a bug fix;
|
||||
Open Question 1 records a viable replacement-callback alternative.
|
||||
**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 proposal changes the current customization contract; Open
|
||||
Question 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`, not a build declaration. A Go consumer wanting the normal
|
||||
build-and-deliver operation must reproduce orchestration that CLI consumers get
|
||||
for free. The default CLI path also builds and runs the native smoke executable
|
||||
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 does use supported
|
||||
facades, but owns more domain coordination than the architecture's parsing,
|
||||
presentation, and exit-status responsibility suggests.
|
||||
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. Decide
|
||||
whether caller-provided builds remain an advanced supported mode, as discussed
|
||||
in Open Question 3. Keep the private receipt as local coordination data if that
|
||||
mode remains; do not promote it into a provenance or portable-attestation format.
|
||||
whether a concrete consumer needs caller-provided builds, as discussed in
|
||||
Open Question 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
|
||||
|
||||
@@ -241,31 +228,27 @@ 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.** Core library duplication is reduced, but routine CI mechanics
|
||||
still become consumer-owned copies that can drift. A chosen ReleaseKit version
|
||||
and Go toolchain also need a clear installation/update convention for both local
|
||||
publication and CI delivery. Merely requiring every application to invent a
|
||||
wrapper would leave part of the roadmap's original problem unsolved.
|
||||
**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 a maintained, versioned integration entry point and
|
||||
one default delivery sequence for both source-only and binary profiles. Keep
|
||||
product declarations, immutable tool/toolchain pins, and secret references in
|
||||
consumer configuration. Keep network-enabled dependency preparation separate
|
||||
from offline validation/builds. Splitting build and delivery is justified when
|
||||
it establishes an actual credential or artifact handoff boundary, not simply
|
||||
because both commands exist. See Open Question 4 for packaging alternatives.
|
||||
ReleaseKit's bootstrap can remain special until the first version is available.
|
||||
**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. Choose source installation or a
|
||||
maintained image according to the setup and maintenance effort each 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 Open Question 4 for packaging alternatives.
|
||||
|
||||
The current workflow tests are useful but narrower than their names may imply.
|
||||
`TestWoodpeckerDeliveryCommandSequences` in
|
||||
[the CLI workflow tests](../../cmd/releasekit/woodpecker_test.go) executes
|
||||
equivalent commands;
|
||||
[the ReleaseKit workflow test](../../cmd/releasekit/releasekit_delivery_workflow_test.go)
|
||||
similarly reconstructs the sequence. They do not execute the maintained YAML
|
||||
through Woodpecker or exercise the pinned installation step. A YAML drift can
|
||||
therefore leave those tests green. Validate the actual selected integration at
|
||||
adoption, and keep a small check tied to the maintained artifact. This is
|
||||
integration-development evidence, not a new per-release live-service gate.
|
||||
similarly reconstructs the sequence. Execution of the maintained YAML and
|
||||
installation step remains unverified. A YAML drift can leave these tests green.
|
||||
Validate the selected integration during adoption and keep a small check tied to
|
||||
the maintained artifact. Use that evidence to maintain the shared integration.
|
||||
|
||||
### F7 — Medium: delivery asset classifications overlap inconsistently
|
||||
|
||||
@@ -278,19 +261,18 @@ can also remain pending. The existing
|
||||
[upload_test.go](../../internal/gitea/upload_test.go) explicitly expects the
|
||||
same asset in both pending and uncertain collections.
|
||||
|
||||
**Consequence.** Public consumers cannot treat the collections as consistent
|
||||
categories. The CLI can present one file as both pending and uncertain, while a
|
||||
**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 is conservative, so this is not a false-success defect, but it makes
|
||||
recovery reporting and automation less clear.
|
||||
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. Alternatively, explicitly define pending as a superset
|
||||
of all unfinished assets and implement that rule consistently; see Open
|
||||
Question 5. Update the behavioral tests to protect the selected meaning instead
|
||||
of preserving inconsistent branch bookkeeping.
|
||||
Question 5. Update behavioral tests to protect the selected meaning.
|
||||
|
||||
### F8 — Maintainability: artifact rules have several implementation owners
|
||||
|
||||
@@ -310,137 +292,114 @@ 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 actually match. Keep explicit facade conversions required
|
||||
by the ADR; replacing them with public aliases would trade a little duplication
|
||||
for a larger compatibility burden. Do not introduce a generic workflow engine,
|
||||
plugin registry, or public Git/Gitea implementation packages to solve these
|
||||
localized problems.
|
||||
where the semantics match. Keep the explicit facade conversions required
|
||||
by the ADR. Focus refactoring on the small internal helpers that own these rules.
|
||||
|
||||
## Recommended standard and release sequencing
|
||||
|
||||
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 ambiguity
|
||||
recovery. Source publication finishes independently of hosted delivery. Keep
|
||||
additive, content-checked delivery and lightweight runtime version access.
|
||||
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.
|
||||
|
||||
Strengthen that standard around a small committed declaration: product identity,
|
||||
selected binary targets, explicit toolchain/build choices, delivery destination,
|
||||
and product-specific checks added to the shared validation baseline. The ordinary
|
||||
consumer integration should be a pinned tool invocation plus that declaration
|
||||
and secret provisioning. Authoring compatibility notes and choosing the version
|
||||
remain product decisions; ReleaseKit need not guess them from commit messages.
|
||||
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.
|
||||
|
||||
Recommended order:
|
||||
|
||||
1. Fix F1–F3 and retain focused behavioral regressions. F1–F2 affect the first
|
||||
source release itself; F3 should be resolved before advertising standard
|
||||
binary adoption.
|
||||
2. Decide Open Questions 1–3 and 5 before settling the first public API and
|
||||
configuration contracts. Implement the selected changes, including F7, with
|
||||
their canonical GoDoc/configuration/consumer documentation. Consolidate F8
|
||||
while touching those owners.
|
||||
3. Prove one representative source-only integration with an extra product check
|
||||
and one binary integration using the selected common workflow. Identify the
|
||||
actual scripts and duplicated tests removable from each. Temporary local
|
||||
adoption trials can precede a published module; do not make sibling checkouts
|
||||
dependencies of ReleaseKit's normal build or default suite.
|
||||
4. Select the packaging direction in Open Question 4, prepare immutable pins and
|
||||
credentials, and test the actual workflow/service integration separately.
|
||||
First-source-release bootstrap is legitimate; live artifact availability
|
||||
still does not become a source-publication completion gate.
|
||||
5. Prepare the `v0.1.0` note and follow the existing maintainer procedure once the
|
||||
selected pre-release work is complete. This audit does not tag or publish.
|
||||
1. Fix F1–F2 and retain focused behavioral regressions before tagging `v0.1.0`.
|
||||
2. Settle the validation and delivery API choices in Open Questions 1 and 3.
|
||||
Adopt clear result categories under Question 5. Implement the selected
|
||||
changes with their canonical documentation and consolidate F8 in those owners.
|
||||
3. Address F3 through internal compatibility defaults, using Open Question 2 to
|
||||
keep build configuration proportionate to actual consumer needs.
|
||||
4. Exercise one source-only consumer with an extra product check and one binary
|
||||
consumer through the common integration. Measure removed scripts, duplicated
|
||||
tests, setup steps, and recurring release decisions. Keep ReleaseKit's default
|
||||
suite independent of sibling checkouts.
|
||||
5. Choose the simplest shared installation and update path under Open Question 4.
|
||||
Verify the maintained integration during deployment preparation. Follow the
|
||||
existing maintainer procedure for the release note and source publication;
|
||||
report hosted delivery separately.
|
||||
|
||||
Not every possible release feature belongs in this first version. There is no
|
||||
review evidence requiring a general multi-module release engine, prerelease
|
||||
channels, multi-program bundles, arbitrary packaging hooks, mandatory signatures,
|
||||
or stronger source attestations. Add such capabilities for an adopted need,
|
||||
without weakening the ordinary shared path to accommodate hypothetical cases.
|
||||
Feature expansion should follow demonstrated consumer needs and measurable
|
||||
reductions in application maintenance or developer effort.
|
||||
|
||||
## Open Questions
|
||||
|
||||
### 1. Should product checks supplement or replace standard validation?
|
||||
|
||||
**Recommended:** Run the shared offline suite once, followed by declared
|
||||
product-specific checks. Where a product truly needs a different invocation of
|
||||
that same suite, expose a narrow explicit selection with documented semantics,
|
||||
not an unrestricted implicit replacement. This centralizes the shared obligation
|
||||
while allowing meaningful product checks and avoiding duplicate tests. Remove
|
||||
old suite invocations when migrating custom scripts.
|
||||
**Recommended:** 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. This gives developers one ordinary validation path to understand.
|
||||
|
||||
**Viable alternative:** Keep the current replacement callback/command list and
|
||||
make each product own one complete validation command. This is idiomatic for a
|
||||
small Go orchestration library and accommodates unusual test layouts without an
|
||||
expanding configuration schema. It is optimal if validation is intentionally a
|
||||
consumer boundary; it is less aligned with the user's goal of maximal shared
|
||||
standardization. Adoption guidance and tests would need to establish the common
|
||||
baseline rather than assuming the library enforces it.
|
||||
**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 much of the build environment belongs in release identity?
|
||||
### 2. How should ReleaseKit choose build settings?
|
||||
|
||||
**Recommended:** Standard baseline feature levels and flags, plus an explicitly
|
||||
selected toolchain preserved with the release inputs or an immutable build-image
|
||||
pin. Control ambient feature/experiment settings and persistent Go configuration.
|
||||
Keep cache locations and dependency access during preparation operational.
|
||||
Different products can select toolchains meeting their modules' requirements;
|
||||
standardization is the selection mechanism, not forcing every product onto an
|
||||
inadequate Go version. This minimizes accidental variants and makes retries
|
||||
explainable without claiming hermeticity.
|
||||
**Recommended:** Use the available compatible Go toolchain, ordinary baseline CPU
|
||||
settings, and shared build flags. Handle incidental environment 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.
|
||||
|
||||
**Viable alternative:** Declare a richer target variant including CPU features,
|
||||
build tags, and other justified options, and encode variant identity in artifact
|
||||
names, receipts, and manifests. That supports genuine hardware-specific products
|
||||
correctly but adds public API and validation cost. Use it when such variants are
|
||||
actual deliverables. Continuing to inherit unrecorded settings is not an equally
|
||||
good alternative for a standardized release builder.
|
||||
**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?
|
||||
|
||||
**Recommended:** Make declared tagged-source build-and-deliver the normal facade
|
||||
operation, with source verification and temporary storage owned internally.
|
||||
The CLI and Go callers then share one implementation. Retain prebuilt input only
|
||||
if a real split-stage consumer needs it, with the current digest/source checks
|
||||
and a clear lifecycle. A plain request struct and straightforward orchestration
|
||||
are sufficient; no public state-machine framework is needed.
|
||||
**Recommended:** 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 requirement justifies it. This minimizes consumer orchestration code.
|
||||
|
||||
**Viable alternative:** Keep `Build` and `Deliver` as the only primitives and
|
||||
provide a canonical composition helper/example. This makes build environments
|
||||
and credential isolation explicit and keeps the delivery operation narrow.
|
||||
It is appropriate when most consumers intentionally hand artifacts between
|
||||
separate stages, but asks ordinary Go callers to assemble more release logic.
|
||||
For portable stage handoff, deliberately design a portable artifact description;
|
||||
the current absolute-path receipt is intentionally local.
|
||||
**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?
|
||||
|
||||
**Recommended:** A versioned shared CI runner/entry point, packaged with a known
|
||||
ReleaseKit executable and compatible Go/Git environment, selected by immutable
|
||||
image digest. Consumers provide the profile, selected image/toolchain, and secret
|
||||
reference. Use one maintained flow for source-only and binary delivery. This
|
||||
removes repeated installer/setup shell from applications and gives integration
|
||||
fixes a versioned owner. It requires deliberately adopting image distribution,
|
||||
which the current source-only release policy does not yet declare; local
|
||||
maintainers can still install the versioned Go command.
|
||||
**Recommended:** Choose the simplest maintained entry point for installation,
|
||||
updates, and delivery. Begin with versioned source installation if it keeps
|
||||
consumer integration small. Centralize reusable setup and provide one clear
|
||||
upgrade procedure. Assess packaging by the consumer code and recurring developer
|
||||
work it removes.
|
||||
|
||||
**Viable alternative:** Keep source-only tool distribution through pinned
|
||||
`go install` and maintain a small canonical bootstrap/template. It needs less
|
||||
hosting infrastructure and naturally supports different Go versions. Prefer
|
||||
calling one combined delivery operation where credential isolation permits it.
|
||||
The cost is repeated setup and template-update work in consumers; test the real
|
||||
template and provide an explicit pin/update convention. Do not add executable
|
||||
binary distribution merely to remove a few shell lines if this alternative
|
||||
proves adequately small in adoption trials.
|
||||
**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. Are delivery result collections exclusive categories or overlapping views?
|
||||
### 5. How should delivery results support simple recovery?
|
||||
|
||||
**Recommended:** Exclusive outcome categories, with pending meaning known work
|
||||
remaining and uncertain meaning remote effect unresolved. A caller can render
|
||||
or act on each category without deduplicating it against the others. Overall
|
||||
state continues to prevent automatic retries after uncertain writes.
|
||||
**Recommended:** 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. 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,
|
||||
but must be defined explicitly and applied in every branch. Consumers must then
|
||||
subtract blocked subsets before deriving retry work. Either is maintainable;
|
||||
the present mixture is not.
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user