Skip to content

Build once, test many: cross-compiled binaries verified by self-install on target machines #652

Closed as not planned

Description

@David-Noble-at-work

Epic: #444. Depends on: #639 (pin the host toolchain so a cross-compile build completes at all).

The goal, stated by USER 2026-08-24: build on one machine and test on many. No maintained Linux or Windows environment on every box being targeted — instead, cross-compile the binaries once, ship them to the target, and verify by self-installing there.

Today the only cross-platform gate is make vet, which compiles and runs nothing. That is precisely why #639 hid: a defect that only manifests when a binary executes cannot be caught by a gate that never executes one.

What exists already

  • dist (Makefile:286-287) cross-compiles under explicit GOOS/GOARCH/CGO_ENABLED=0 — but only writ and lore, 2 of the 7 binaries make build produces (lore, star, writ, devlore-test, devlore-docs, devlore-index, devlore-inventory).
  • TestSelfInstallScenario (cmd/scenario) already drives self-install end to end, and make test-scenario runs it on all three platforms in CI — but against binaries built on each platform, which is the workflow this issue replaces.
  • Product recipes (Makefile:136-142) already carry $(GOEXE), so they anticipate cross-compilation.

What has to be worked out

  1. Which binaries ship. All seven, or the user-facing subset? devlore-inventory and star are build tools — a target machine has no obvious use for them, but devlore-test may be exactly what runs on the target.
  2. How binaries reach the target. Artifact upload, a release, a shared path, scp — and whether that is CI's job or a local make target.
  3. What "verify" means on the target. Self-install and exit 0, or self-install and then run a scenario subset? The stronger form needs devlore-test and its data/*.star fixtures on the target too.
  4. Where it runs. CI matrix job, or an operator-driven flow the user invokes by hand across their own boxes. The stated motivation — not maintaining environments — points away from CI runners and toward real machines.
  5. CGO_ENABLED. dist forces 0. Whether every binary tolerates that, and whether it should be uniform, is unverified.
  6. The regression guard. Independent of the full workflow, CI should run a cross-compile build so Cross-compiling the product cross-compiles the build tools too #639 cannot silently return. That is the cheap half and could land well before the rest.

Suggested first cut

Item 6 alone, immediately after #639: a CI step that runs GOOS=linux make build and GOOS=windows make build. It protects the fix, costs one job, and needs none of the decisions above settled.

Activity

  1. David-Noble-at-work commented on Aug 24, 2026

    @David-Noble-at-work
    ContributorAuthor

    Duplicate of #598, which was ruled 2026-08-21 and is the more complete statement. Closing this; filing it was my error — I did not check for an existing issue before opening one.

    #598 already answers four of the six questions this issue raised as open:

    This issue asked #598 already rules
    Which binaries ship products lore, writ, star, devlore-test; dev tools (devlore-docs, devlore-index, devlore-inventory, scenario) stay host-only
    How they reach the target layout build/<goos>-<goarch>/<binary>[.exe]; "installing anywhere is a copy"
    Where it runs make build = full matrix by default, PLATFORMS= override for the inner loop; tests stay native per platform in CI
    CGO_ENABLED moot — the codebase is pure Go, zero import "C", verified 2026-08-21

    It also states the same motivation in the same terms: "the build should come to the machine instead."

    The one item here not already in #598 is the regression guard — a CI step that actually runs a cross-compile build, so #639 cannot silently return. That has been noted on #639 instead, where it belongs.

    Two of my observations are worth carrying over to #598, since they narrow it:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Epic:QualityCoverageCode quality, coverage, and the lint gatestaskImplementation work item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions