Build selected targets with version injection

This commit is contained in:
2026-10-05 19:20:58 +00:00
parent c83313b3b9
commit 5d6a6d10bd
12 changed files with 927 additions and 34 deletions

62
docs/consumers/build.md Normal file
View File

@@ -0,0 +1,62 @@
# Build versioned application binaries
Use `releasekit.Build` when an application needs binaries for explicit Go
operating-system and architecture pairs:
```go
import (
"context"
"fmt"
releasekit "gitea.maximumdirect.net/eric/ReleaseKit"
)
func build(ctx context.Context) error {
result, err := releasekit.Build(ctx, releasekit.BuildRequest{
RepositoryDir: "/work/project",
Version: "v1.2.3",
Spec: releasekit.BuildSpec{
MainPackage: "./cmd/project",
BinaryName: "project",
Targets: []releasekit.Target{
{OS: "linux", Arch: "amd64"},
{OS: "linux", Arch: "arm64"},
{OS: "darwin", Arch: "arm64"},
},
},
OutputDir: "dist",
})
if err != nil {
return err // result retains completed artifacts when a later step fails.
}
for _, artifact := range result.Artifacts {
fmt.Println(artifact.Filename, artifact.SHA256)
}
return nil
}
```
`Build` records the repository's current `HEAD`, injects the selected stable
version into `buildinfo.Version`, and returns the compiler identity, normalized
targets, artifact paths, filenames, and SHA-256 digests. Names follow
`<binary>-<version>-<goos>-<goarch>`; Windows targets add `.exe`. A repeated
target pair is built once, at its first position.
The default output directory is `<repository>/dist`; a relative `OutputDir` is
resolved from the repository. Existing files with a selected artifact name are
preserved and cause an error. Other files in the output directory are left in
place. A failed later build or native version check returns the binaries already
generated in `BuildResult.Artifacts`.
Builds use the prepared local Go toolchain, readonly module mode, disabled
module network access, `CGO_ENABLED=0`, `-trimpath`, and `-buildvcs=false`. Each
selected target is compiled explicitly. ReleaseKit then runs the `version`
command on a native binary and requires `<binary> <version>` followed by a
newline. If no selected target matches the Go host, it builds a temporary
native binary for this check and removes it afterward. Cross-compilation does
not promise that a binary runs on another platform.
An empty target list records the source commit and returns without invoking Go,
creating the output directory, or running a version check. It does not require a
main package or binary name. This supports source-only operations without
silently adding a binary check.

View File

@@ -13,4 +13,5 @@ version := buildinfo.Version()
Otherwise it returns the executable's main module version when that metadata is
available and is not `(devel)`. It returns `dev` when neither source provides a
release identifier. Applications should use this accessor for version output;
the runtime implementation and ReleaseKit's builder own the injection detail.
the runtime implementation and [ReleaseKit's build API](build.md) own the
injection detail.

View File

@@ -49,8 +49,8 @@ root with:
go run ./internal/apicheck
```
See the [candidate check guide](consumers/check.md), [internal package
inventory](internal/overview.md), and [implementation plan](roadmap/implementation.md)
See the [candidate check guide](consumers/check.md), [build consumer guide](consumers/build.md),
[internal package inventory](internal/overview.md), and [implementation plan](roadmap/implementation.md)
for current implementation progress.
For prose changes, review the diff and check local links, fragment destinations,

View File

@@ -8,12 +8,14 @@ Implemented internal packages:
- `internal/runtimeinfo` holds the injected version value and selects the
executable's main-module version when no injected value is present.
- `internal/versioncontract` names the linker symbol shared with the future
release builder.
- `internal/versioncontract` names the linker symbol and stable version form
shared with the build and candidate operations.
- `internal/apicheck` checks compiled exports with `go/types` and checks import
direction. Run it with `go run ./internal/apicheck` from the repository root.
- `internal/process` runs cancellable child commands with per-child environment
overlays.
- `internal/build` compiles explicit Go targets with shared version injection,
verifies native version output, and returns generated file digests.
- `internal/candidate` captures and validates one clean local candidate, checks
its committed release note and local tag state, runs validation once, and
rechecks mutable repository state.

View File

@@ -1,7 +1,6 @@
# ReleaseKit staged implementation plan
Status: Proposed. All stages are pending; this document introduces no implemented
features or published contracts.
Status: In progress. Stages 1–10 are complete; later stages remain pending.
Date: 2026-10-05
@@ -683,7 +682,7 @@ ReleaseKit release was published.
## Stage 10: Build selected targets with shared version injection
Status: Pending. Depends on Stage 9.
Status: Complete. Depends on Stage 9.
1. Implement public build values and internal build execution using the fixed
flags, version symbol, filename convention, and prepared Go environment.
@@ -702,6 +701,17 @@ does not select the smoke host. Empty targets perform no build or smoke test;
missing main packages, build failures, incorrect version output, unsafe binary
names, and cancellation fail with useful partial results.
Evidence: `releasekit.Build` and `internal/build` compile Linux amd64, Linux
arm64, and macOS arm64 artifacts using the shared linker symbol and prepared
local Go environment. The consumer fixture imports `buildinfo` and reports the
injected version through its `version` invocation. Results retain the observed
source commit, compiler identity, normalized targets, absolute paths, filenames,
and SHA-256 digests. Tests cover host selection despite ambient cross-target
variables, empty target sets, existing output preservation, partial target
failure, missing packages, incorrect version output, unsafe names, and
cancellation with completed artifacts retained. No byte-reproducibility or
cross-platform execution guarantee is added.
## Stage 11: Integrate candidate builds and artifact command
Status: Pending. Depends on Stage 10.

View File

@@ -2,8 +2,8 @@
This is a proposal based on a review of PromptKit, ConfigKit, Audita, Notarius,
Narratio, and Scriptorium on 2026-09-29. The implementation plan records the
current implemented boundary; builds, delivery, and broader integrations remain
proposed. The public facade architecture is accepted in
current implemented boundary; CLI build integration, delivery, and broader
integrations remain planned. The public facade architecture is accepted in
[ADR 0001](../adr/0001-public-facade.md) and is implemented for runtime version,
candidate validation, and source publication.
The [implementation plan](implementation.md) owns ordered stages, execution
@@ -55,8 +55,9 @@ cleanup.
The [architecture policy](../policy/architecture.md) owns the adopted
responsibility and dependency rules, including the runtime version boundary.
The root `releasekit` package provides the public facade for candidate
validation and source publication; builds and delivery remain planned. The
separate public `buildinfo` package provides lightweight runtime version access.
validation, source publication, and selected-target builds; CLI build
integration and delivery remain planned. The separate public `buildinfo`
package provides lightweight runtime version access.
Each facade owns its public named types and documented contracts. Public
operations, inputs, outcomes, errors, and callbacks express deliberately