diff --git a/docs/roadmap/host-native-launchers.md b/docs/roadmap/host-native-launchers.md new file mode 100644 index 0000000..0294b50 --- /dev/null +++ b/docs/roadmap/host-native-launchers.md @@ -0,0 +1,142 @@ +# Roadmap: host-native consumer launchers + +Status: planned; implementation pending. + +## Purpose + +Make ReleaseKit's maintained consumer launchers 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. + +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 consumer launchers obtain `GOHOSTOS` and `GOHOSTARCH` from the selected +Go toolchain and use them 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. + +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 minimal adoption launcher and consumer CI templates 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. Review other maintained executable bootstrap examples for the +same target assumption and align affected paths. 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. + +### 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. + +Cover affected CI/bootstrap recipes through their existing test harnesses where +practical, including normalization before dependency inspection. 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 execution under a foreign target, preserved 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.