Files
releasekit/docs/roadmap/host-native-launchers.md

163 lines
8.6 KiB
Markdown

# Roadmap: host-native consumer launchers
Status: planned; implementation pending.
## Purpose
Make ReleaseKit's maintained launchers and generated recovery commands prepare
and execute the release tool for the maintainer's host when inherited `GOOS`
and `GOARCH` select a different application target. Centralize the recipe and
regression coverage so consumers can retain small launchers and product-specific
wiring tests.
This is a launcher correctness improvement. It requires no public bootstrap API,
validation option, or test-helper package. This roadmap selects no release version
and describes work to be implemented after this documentation pass.
## Current baseline
CommandKit reports that a prepared v0.8.0 tool invocation on Linux/amd64 with
`GOOS=windows GOARCH=arm64` built a Windows executable and failed with an exec
format error. Its local launcher already selects the Go host target before
building the release executable. The report's reproduction exercised tool
execution without attempting publication.
The maintained [multi-module launcher](../../examples/multi-module/release.sh)
selects a module and profile, copies module metadata into temporary storage,
prepares the selected ReleaseKit dependency, and invokes `go tool releasekit`.
It sets `GOWORK=off` and `GOTOOLCHAIN=local`, but inherits `GOOS` and `GOARCH`.
Target-dependent dependency inspection therefore also sees the inherited target.
The [adoption guide](../consumers/adoption.md) includes a minimal `go tool`
launcher. The [single-module CI template](../../examples/woodpecker/tag-delivery.yml)
and [multi-module CI template](../../examples/multi-module/woodpecker.yml) also
invoke the selected tool without explicit host-target normalization.
The [maintainer launcher](../../scripts/release),
[source delivery template](../../examples/woodpecker/releasekit-source-delivery.yml),
and [manual delivery retry](../release.md) build and execute the tool with the
same inherited-target assumption. The CLI's [generated recovery command](../../cmd/releasekit/main.go)
inherits the target from the shell where it is run, and [recovery dependency
preparation](../../internal/gotool/recovery.go) also inherits the target.
Existing [launcher tests](../../cmd/releasekit/multi_module_example_test.go)
exercise synthetic module selection, publication arguments, child statuses
0 through 3, and preservation of source module metadata. Those fixtures provide
the starting point for foreign-target regression coverage.
## Targeted end state
Maintained launchers and module-based recovery use `GOHOSTOS` and `GOHOSTARCH`
from the selected Go toolchain as `GOOS` and `GOARCH` while preparing and running
ReleaseKit. The tool executes on that host even when the caller was working with
a foreign application target. Normalize before target-dependent dependency
inspection as well as tool execution. Generated recovery commands select the
host when run, using the Go toolchain that will execute the command.
Application targets continue to come from existing release profiles. The
launcher's host selection preserves module-selected tool versions, profile and
argument routing, source-file preservation, temporary-file cleanup, existing
workspace/toolchain settings, and child exit statuses. Consumers retain their
own selectors, products, endpoints, and release order.
The scope is inherited `GOOS` and `GOARCH` handling for the maintainer tool. It
does not establish a hermetic environment, broaden hardware or platform support,
or add release gates. Existing Go/toolchain failures remain ordinary bootstrap
failures. No new fallback toolchain or download policy is introduced.
## Work needed
### 1. Normalize the maintained multi-module launcher
**Rationale:** A consumer should be able to invoke its release launcher after
cross-build work without first repairing its shell environment.
**Target:** The selected ReleaseKit executable and its dependency preparation
use the Go host target.
**Work:** Query the host OS and architecture through the same Go toolchain used
for bootstrap, under the launcher's existing workspace and toolchain settings.
Apply both values within the tool-running scope before target-dependent Go
commands. Preserve `go tool`, temporary module metadata, selected-module version
resolution, and existing publication arguments. Use ordinary shell error handling
for host-query failures. Avoid hard-coded host values or a new bootstrap layer.
### 2. Align supported invocation recipes
**Rationale:** The same inherited-target failure can affect local and CI tool
execution. Maintained recipes should give consumers consistent behavior.
**Target:** The adoption example, consumer and maintainer launchers, CI
templates, and generated recovery commands select the host target when
preparing and invoking ReleaseKit.
**Work:** Apply the same small normalization recipe to the adoption example and
the single-module and multi-module CI templates. Preserve tag verification before
bootstrap, tagged module selection, profile routing, credentials, and temporary
metadata handling. Apply host selection to the maintainer launcher, source
delivery template, and manual delivery retry. Update the multi-module README
and consumer guidance to explain host selection and profile-owned application
targets. Document that consumers adopt the corrected launcher or template; a
module dependency upgrade alone does not rewrite their copied scripts.
Apply host selection to module-based recovery dependency preparation and to the
Go invocation printed by `publish`. Preserve registered-tool selection, private
bootstrap metadata for API-only consumers, the native executable fallback,
explicit record selection, and recovery exit statuses.
### 3. Extend existing behavioral coverage
**Rationale:** Successful execution under a foreign target directly protects
against the reported defect while existing fixtures protect delegation behavior.
**Target:** A synthetic selected tool runs on the test host despite foreign
target variables, with the current routing and cleanup behavior intact.
**Work:** Extend the existing launcher fixture with a controlled target different
from the test host. Exercise real Go tool preparation and execution; a source-text
assertion alone cannot establish that the executable runs. Verify that the
selected module's tool version and publication arguments reach the child and
that statuses 0, 1, 2, and 3 propagate. Check unchanged source module files and
existing temporary bootstrap cleanup. Reuse unaffected tests rather than adding
a parallel launcher or publication-engine suite.
Verify host selection at the dependency inspection step itself, using a
host-specific fixture or an environment assertion at `go list -deps`. Cover
affected CI/bootstrap recipes through their existing test harnesses where
practical. Extend the existing handoff tests to exercise recovery preparation
under a foreign target, then run the printed command under a foreign target in
a separate invocation. Preserve profile-selected application targets. Use
synthetic local tools and test-owned module caches under the
[fixture-isolation guidance](../development.md#testing-synthetic-modules).
The regression needs no actual publication, hosted service, or external platform
runner. Choose a representative supported foreign target instead of introducing
a platform matrix.
### 4. Validate and document adoption
**Rationale:** Consumers should be able to copy a verified recipe and reduce
their local tests to their own wiring.
**Target:** Maintained examples, guidance, and tests agree on the native bootstrap
behavior and its scope.
**Work:** Run the relevant launcher and workflow tests, the normal offline suite,
and required facade checks when implementation lands. Check shell/example syntax,
documentation links, and whitespace. Include a concise release-note entry for
the inherited-target fix and affected recipes. Explain that ReleaseKit owns
generic bootstrap and publication-engine coverage while consumers verify their
selectors and profile mapping. This does not require consumers to remove tests
that protect their own behavior.
## Completion evidence
Completion requires host selection before dependency inspection and successful
host execution under a foreign target, including for generated recovery commands.
Preserve selected tool identity and arguments, child-status forwarding, unchanged
source metadata, and existing cleanup behavior. The maintained local and CI
recipes and adoption guidance must use the same host-selection approach.
Application build targets must retain their existing profile-driven behavior.
There are no significant open design decisions for this scope. Exact shell
variable names and fixture arrangement can be selected during implementation.