Upgrade ReleaseKit and simplify release tooling
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- GO_IMAGE: golang:1.25.5
|
- GO_IMAGE: golang:1.26.8-bookworm
|
||||||
|
|
||||||
when:
|
when:
|
||||||
- event: tag
|
- event: tag
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ reports for review and subprocess integration.
|
|||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
From a checkout, build with Go 1.25.5 or newer:
|
From a checkout, build with Go 1.26.0 or newer:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go build -o ./bin/audita ./cmd/audita
|
go build -o ./bin/audita ./cmd/audita
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ ownership. Commit discipline and agent Git restrictions are in the
|
|||||||
|
|
||||||
## Baseline Validation
|
## Baseline Validation
|
||||||
|
|
||||||
Use Go 1.25.5 or newer. From the repository root:
|
Use Go 1.26.0 or newer for source builds. The selected release toolchain is
|
||||||
|
documented in the [release procedure](release.md#prerequisites). From the
|
||||||
|
repository root:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go build -o ./bin/audita ./cmd/audita
|
go build -o ./bin/audita ./cmd/audita
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ License and notices: [LGPL v3](licenses/LGPL-3.0.txt) |
|
|||||||
|
|
||||||
## ReleaseKit
|
## ReleaseKit
|
||||||
|
|
||||||
Selected module: `gitea.maximumdirect.net/eric/ReleaseKit` at `v0.1.0`.
|
Selected module: `gitea.maximumdirect.net/eric/ReleaseKit` at `v0.3.0`.
|
||||||
|
|
||||||
Copyright (C) 2026 Eric Rakestraw
|
Copyright (C) 2026 Eric Rakestraw
|
||||||
|
|
||||||
@@ -46,79 +46,79 @@ SPDX-License-Identifier: LGPL-3.0-or-later
|
|||||||
|
|
||||||
License and notices: [LGPL v3](licenses/LGPL-3.0.txt) |
|
License and notices: [LGPL v3](licenses/LGPL-3.0.txt) |
|
||||||
[GPL v3](licenses/GPL-3.0.txt) |
|
[GPL v3](licenses/GPL-3.0.txt) |
|
||||||
[COPYRIGHT](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/COPYRIGHT).
|
[COPYRIGHT](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e43df4416e0ed987349b2ea04a2c68c25e552772/COPYRIGHT).
|
||||||
|
|
||||||
[Source](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1).
|
[Source](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/e43df4416e0ed987349b2ea04a2c68c25e552772).
|
||||||
|
|
||||||
## Go runtime and standard library
|
## Go runtime and standard library
|
||||||
|
|
||||||
Selected toolchain: Go 1.25.5 for the distributed Linux binaries.
|
Selected toolchain: Go 1.26.8 for the distributed Linux binaries.
|
||||||
|
|
||||||
Copyright 2009 The Go Authors.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
||||||
[LICENSE](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/LICENSE) |
|
[LICENSE](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/LICENSE) |
|
||||||
[PATENTS](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/PATENTS).
|
[PATENTS](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/PATENTS).
|
||||||
|
|
||||||
[Source](https://github.com/golang/go/commit/fefb02adf45c4bcc879bd406a8d61f2a292c26a9).
|
[Source](https://github.com/golang/go/commit/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e).
|
||||||
|
|
||||||
## Go vendored golang.org/x/crypto
|
## Go vendored golang.org/x/crypto
|
||||||
|
|
||||||
Material: `golang.org/x/crypto` at `v0.39.0` in the Go 1.25.5 standard library.
|
Material: `golang.org/x/crypto` at `v0.46.1-0.20251210140736-7dacc380ba00` in the Go 1.26.8 standard library.
|
||||||
|
|
||||||
Copyright 2009 The Go Authors.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
||||||
[LICENSE](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/crypto/LICENSE) |
|
[LICENSE](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/crypto/LICENSE) |
|
||||||
[PATENTS](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/crypto/PATENTS).
|
[PATENTS](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/crypto/PATENTS).
|
||||||
|
|
||||||
[Source](https://github.com/golang/go/commit/fefb02adf45c4bcc879bd406a8d61f2a292c26a9).
|
[Source](https://github.com/golang/go/commit/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e).
|
||||||
|
|
||||||
## Go vendored golang.org/x/net
|
## Go vendored golang.org/x/net
|
||||||
|
|
||||||
Material: `golang.org/x/net` at `v0.41.0` in the Go 1.25.5 standard library.
|
Material: `golang.org/x/net` at `v0.47.1-0.20260731170545-cb1d721f7fb3` in the Go 1.26.8 standard library.
|
||||||
|
|
||||||
Copyright 2009 The Go Authors.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
||||||
[LICENSE](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/net/LICENSE) |
|
[LICENSE](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/net/LICENSE) |
|
||||||
[PATENTS](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/net/PATENTS).
|
[PATENTS](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/net/PATENTS).
|
||||||
|
|
||||||
[Source](https://github.com/golang/go/commit/fefb02adf45c4bcc879bd406a8d61f2a292c26a9).
|
[Source](https://github.com/golang/go/commit/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e).
|
||||||
|
|
||||||
## Go vendored golang.org/x/sys
|
## Go vendored golang.org/x/sys
|
||||||
|
|
||||||
Material: `golang.org/x/sys` at `v0.33.0` in the Go 1.25.5 standard library.
|
Material: `golang.org/x/sys` at `v0.39.0` in the Go 1.26.8 standard library.
|
||||||
|
|
||||||
Copyright 2009 The Go Authors.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
||||||
[LICENSE](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/sys/LICENSE) |
|
[LICENSE](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/sys/LICENSE) |
|
||||||
[PATENTS](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/sys/PATENTS).
|
[PATENTS](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/sys/PATENTS).
|
||||||
|
|
||||||
[Source](https://github.com/golang/go/commit/fefb02adf45c4bcc879bd406a8d61f2a292c26a9).
|
[Source](https://github.com/golang/go/commit/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e).
|
||||||
|
|
||||||
## Go vendored golang.org/x/text
|
## Go vendored golang.org/x/text
|
||||||
|
|
||||||
Material: `golang.org/x/text` at `v0.26.0` in the Go 1.25.5 standard library.
|
Material: `golang.org/x/text` at `v0.32.0` in the Go 1.26.8 standard library.
|
||||||
|
|
||||||
Copyright 2009 The Go Authors.
|
Copyright 2009 The Go Authors.
|
||||||
|
|
||||||
SPDX-License-Identifier: BSD-3-Clause
|
SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
License and notices: [BSD 3-Clause](licenses/BSD-3-Clause-Go.txt) |
|
||||||
[LICENSE](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/text/LICENSE) |
|
[LICENSE](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/text/LICENSE) |
|
||||||
[PATENTS](https://github.com/golang/go/blob/fefb02adf45c4bcc879bd406a8d61f2a292c26a9/src/vendor/golang.org/x/text/PATENTS).
|
[PATENTS](https://github.com/golang/go/blob/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e/src/vendor/golang.org/x/text/PATENTS).
|
||||||
|
|
||||||
[Source](https://github.com/golang/go/commit/fefb02adf45c4bcc879bd406a8d61f2a292c26a9).
|
[Source](https://github.com/golang/go/commit/c293dd49cbe25e1fe8d97d94a5cb618e7b6d831e).
|
||||||
|
|
||||||
## go-yaml v4
|
## go-yaml v4
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
The [release policy](policy/release.md) owns release requirements. This runbook
|
The [release policy](policy/release.md) owns release requirements. This runbook
|
||||||
uses the native commands in [scripts/release.sh](../scripts/release.sh), which
|
uses the native commands in [scripts/release.sh](../scripts/release.sh), which
|
||||||
builds and invokes ReleaseKit. A confirmed source tag completes the release;
|
invokes the module-selected ReleaseKit tool. A confirmed source tag completes
|
||||||
Woodpecker reports binary delivery separately.
|
the release; Woodpecker reports binary delivery separately.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@@ -12,16 +12,16 @@ which must point to `https://gitea.maximumdirect.net/eric/audita.git`; the
|
|||||||
primary branch is `main`. Source publication needs no delivery credential.
|
primary branch is `main`. Source publication needs no delivery credential.
|
||||||
Woodpecker uses the existing `GITEA_RELEASE_TOKEN` secret for delivery.
|
Woodpecker uses the existing `GITEA_RELEASE_TOKEN` secret for delivery.
|
||||||
|
|
||||||
The source-build minimum is Go 1.25.5, declared in [go.mod](../go.mod).
|
The source-build minimum is Go 1.26.0, declared in [go.mod](../go.mod).
|
||||||
This patch minimum is required by the selected PromptKit dependency.
|
This minimum is required by the selected ReleaseKit dependency.
|
||||||
Distributed executables do not require a Go installation. The selected release
|
Distributed executables do not require a Go installation. The selected release
|
||||||
toolchain is Go 1.25.5, matching the current Woodpecker image and distributed
|
toolchain is Go 1.26.8, matching the current Woodpecker image and distributed
|
||||||
runtime notices. Use that local installation for tool bootstrap, candidate
|
runtime notices. Use that local installation for tool bootstrap, candidate
|
||||||
validation, and release builds. Replace the installation path below with its
|
validation, and release builds. Replace the installation path below with its
|
||||||
actual directory:
|
actual directory:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export PATH="/path/to/go1.25.5/bin:$PATH"
|
export PATH="/path/to/go1.26.8/bin:$PATH"
|
||||||
export GOTOOLCHAIN=local
|
export GOTOOLCHAIN=local
|
||||||
go version
|
go version
|
||||||
```
|
```
|
||||||
@@ -40,10 +40,12 @@ GOWORK=off GOTOOLCHAIN=local go mod download
|
|||||||
```
|
```
|
||||||
|
|
||||||
If dependency preparation changes `go.mod` or `go.sum`, include those changes in
|
If dependency preparation changes `go.mod` or `go.sum`, include those changes in
|
||||||
the committed candidate. The release wrapper separately builds the ReleaseKit
|
the committed candidate. ReleaseKit's CLI is registered as a Go tool dependency;
|
||||||
version selected by `go.mod` into ignored `bin/releasekit`. It uses temporary
|
`go mod tidy` retains its dependencies and checksums. The release wrapper changes
|
||||||
copies of `go.mod` and `go.sum` for tool dependency preparation; that build is
|
to the repository root and invokes `go tool releasekit` with workspace discovery
|
||||||
tool preparation, not candidate validation.
|
and automatic toolchain downloads disabled. Go builds or reuses the selected
|
||||||
|
tool from its normal build cache. Tool preparation precedes offline candidate
|
||||||
|
validation.
|
||||||
|
|
||||||
## Prepare and publish the candidate
|
## Prepare and publish the candidate
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ out detached, and confirms the source tree is clean. It copies the tagged
|
|||||||
`go.mod` and `go.sum` into temporary module metadata outside the checkout. Go
|
`go.mod` and `go.sum` into temporary module metadata outside the checkout. Go
|
||||||
confirms that this configuration selects ReleaseKit, then builds its CLI using
|
confirms that this configuration selects ReleaseKit, then builds its CLI using
|
||||||
an alternate `-modfile`. The bootstrap executable and temporary files remain
|
an alternate `-modfile`. The bootstrap executable and temporary files remain
|
||||||
outside the tagged source. The workflow runs with the existing Go 1.25.5 image,
|
outside the tagged source. The workflow runs with the selected Go 1.26.8 image,
|
||||||
`GOWORK=off`, and `GOTOOLCHAIN=local`.
|
`GOWORK=off`, and `GOTOOLCHAIN=local`.
|
||||||
|
|
||||||
The resulting executable receives:
|
The resulting executable receives:
|
||||||
@@ -125,8 +127,8 @@ after source publication; its status and logs report delivery progress or
|
|||||||
failure.
|
failure.
|
||||||
|
|
||||||
ReleaseKit handles content-aware retries and retained-artifact recovery. See
|
ReleaseKit handles content-aware retries and retained-artifact recovery. See
|
||||||
the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md)
|
the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.3.0/docs/consumers/publish.md)
|
||||||
and [delivery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md)
|
and [delivery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.3.0/docs/consumers/delivery.md)
|
||||||
for those mechanics. A delivery failure does not undo a confirmed source
|
for those mechanics. A delivery failure does not undo a confirmed source
|
||||||
release. Retry the same immutable tag after resolving the reported state; do not
|
release. Retry the same immutable tag after resolving the reported state; do not
|
||||||
replace published files or a checksum manifest.
|
replace published files or a checksum manifest.
|
||||||
@@ -139,11 +141,11 @@ captured authoritative endpoint and publication state. Resolve the result
|
|||||||
against that endpoint before retrying. An exact remote tag-object match, with
|
against that endpoint before retrying. An exact remote tag-object match, with
|
||||||
its source available on remote `main`, can confirm publication. If the remote
|
its source available on remote `main`, can confirm publication. If the remote
|
||||||
state cannot be read, the result remains unknown; do not remove or replace the
|
state cannot be read, the result remains unknown; do not remove or replace the
|
||||||
tag while uncertain. Follow the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md)
|
tag while uncertain. Follow the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.3.0/docs/consumers/publish.md)
|
||||||
for object-level recovery details.
|
for object-level recovery details.
|
||||||
|
|
||||||
A source-release success and artifact-delivery status are separate. For a
|
A source-release success and artifact-delivery status are separate. For a
|
||||||
partial or uncertain delivery, inspect the job output and follow the pinned
|
partial or uncertain delivery, inspect the job output and follow the pinned
|
||||||
[delivery recovery guidance](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md).
|
[delivery recovery guidance](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.3.0/docs/consumers/delivery.md).
|
||||||
A source or published-content correction requires a new appropriate version;
|
A source or published-content correction requires a new appropriate version;
|
||||||
leave the original tag and its contents intact.
|
leave the original tag and its contents intact.
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# ReleaseKit v0.3.0 Upgrade Roadmap
|
# ReleaseKit v0.3.0 Upgrade Roadmap
|
||||||
|
|
||||||
**Last updated:** 2026-10-08
|
**Last updated:** 2026-10-08
|
||||||
**Status:** Release policy adopted; library and toolchain upgrade pending.
|
**Status:** Implementation complete; first upgraded release and live delivery
|
||||||
|
observation pending.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
@@ -11,9 +12,9 @@ ReleaseKit; Audita supplies product facts, compatibility decisions, release
|
|||||||
notes, and thin integration wiring. Standardization and less locally owned
|
notes, and thin integration wiring. Standardization and less locally owned
|
||||||
release code remain the reasons for adoption.
|
release code remain the reasons for adoption.
|
||||||
|
|
||||||
This roadmap replaces the completed initial-adoption roadmap. It defines the
|
This roadmap replaces the completed initial-adoption roadmap. It records the
|
||||||
upgrade's target state and required work; a later implementation plan can own
|
upgrade's target state and completed scope. The upgrade was implemented in one
|
||||||
ordered execution steps.
|
pass without a separate staged plan.
|
||||||
|
|
||||||
## Current Baseline
|
## Current Baseline
|
||||||
|
|
||||||
@@ -41,10 +42,11 @@ At Audita commit `17421bc5f352f3fdeb67561b2b60b49979822228`:
|
|||||||
The initial adoption's [review findings](remediation.md) are resolved. They are
|
The initial adoption's [review findings](remediation.md) are resolved. They are
|
||||||
historical context, not additional work for this upgrade.
|
historical context, not additional work for this upgrade.
|
||||||
|
|
||||||
Since that baseline, Audita has adopted release policy 1.6 and updated its
|
Since that baseline, Audita has adopted release policy 1.6, registered and
|
||||||
provenance, policy attribution, and release runbook. The current Go minimum and
|
upgraded the ReleaseKit tool to v0.3.0, simplified the local wrapper, and
|
||||||
selected release toolchain remain 1.25.5. The dependency, tool registration,
|
updated CI and notices. The current Go minimum is 1.26.0; the selected release
|
||||||
bootstrap simplification, and Go 1.26 upgrade described below remain pending.
|
toolchain is 1.26.8. The scope below records the requirements fulfilled by this
|
||||||
|
implementation.
|
||||||
|
|
||||||
## Selected Upstream Revisions
|
## Selected Upstream Revisions
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ increases in minor releases, with the increase and required source-consumer
|
|||||||
action explained in the release note. Patch releases preserve the consumer
|
action explained in the release note. Patch releases preserve the consumer
|
||||||
minimum. Other compatibility changes remain governed by the adopted policy.
|
minimum. Other compatibility changes remain governed by the adopted policy.
|
||||||
|
|
||||||
## Work Required
|
## Implemented Scope
|
||||||
|
|
||||||
### Module Selection and Local Tooling
|
### Module Selection and Local Tooling
|
||||||
|
|
||||||
@@ -208,3 +210,22 @@ asynchronously when the first upgraded release is published and address any
|
|||||||
deployment failures through the shared recovery procedure. No significant
|
deployment failures through the shared recovery procedure. No significant
|
||||||
feature decisions remain open; implementation details and final release
|
feature decisions remain open; implementation details and final release
|
||||||
preparation can be resolved within the agreed scope.
|
preparation can be resolved within the agreed scope.
|
||||||
|
|
||||||
|
## Implementation Completion
|
||||||
|
|
||||||
|
Completed with Go 1.26.8. The readonly offline full suite passed. The real local
|
||||||
|
wrapper selected ReleaseKit v0.3.0; disposable Go-tool fixtures verified native
|
||||||
|
argument boundaries, statuses 0/2/3, and unchanged module files. The CI workflow
|
||||||
|
matches the v0.3.0 maintained template with Audita's existing secret mapping.
|
||||||
|
The real ReleaseKit builder produced both required Linux artifacts using the
|
||||||
|
test identifier v0.0.0, passed its native version smoke check, and emitted
|
||||||
|
matching artifact digests in its build receipt. Temporary output was removed.
|
||||||
|
The new release-tool dependencies are absent from Audita's runtime dependency
|
||||||
|
list. ReleaseKit and Go runtime/vendor attribution identify their selected
|
||||||
|
source revisions, with existing applicable license texts reused.
|
||||||
|
|
||||||
|
This verification built modified local source and did not claim a clean,
|
||||||
|
published release candidate. Release preparation will validate its final
|
||||||
|
committed candidate through the ordinary publication command. No tags, source
|
||||||
|
pushes, hosted uploads, or LLM calls were made during implementation; live
|
||||||
|
artifact delivery remains a separate observation for the next release.
|
||||||
|
|||||||
8
go.mod
8
go.mod
@@ -1,11 +1,12 @@
|
|||||||
module gitea.maximumdirect.net/eric/audita
|
module gitea.maximumdirect.net/eric/audita
|
||||||
|
|
||||||
go 1.25.5
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitea.maximumdirect.net/eric/ConfigKit v0.5.0
|
gitea.maximumdirect.net/eric/ConfigKit v0.5.0
|
||||||
gitea.maximumdirect.net/eric/ReleaseKit v0.1.0
|
gitea.maximumdirect.net/eric/ReleaseKit v0.3.0
|
||||||
gitea.maximumdirect.net/eric/promptkit v0.12.0
|
gitea.maximumdirect.net/eric/promptkit v0.12.0
|
||||||
|
golang.org/x/mod v0.40.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,7 +16,10 @@ require (
|
|||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect
|
||||||
|
github.com/yuin/goldmark/v2 v2.1.6 // indirect
|
||||||
go.yaml.in/yaml/v4 v4.0.0-rc.6 // indirect
|
go.yaml.in/yaml/v4 v4.0.0-rc.6 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
tool gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit
|
||||||
|
|||||||
8
go.sum
8
go.sum
@@ -1,7 +1,7 @@
|
|||||||
gitea.maximumdirect.net/eric/ConfigKit v0.5.0 h1:2KwG10+kApWM3avOoYA+p768xcbHUp7tQ2rqizBNpyg=
|
gitea.maximumdirect.net/eric/ConfigKit v0.5.0 h1:2KwG10+kApWM3avOoYA+p768xcbHUp7tQ2rqizBNpyg=
|
||||||
gitea.maximumdirect.net/eric/ConfigKit v0.5.0/go.mod h1:tYWpsrbLyu05r8+1MapWp5fN6ZrX9I8hU2xEPedYmYk=
|
gitea.maximumdirect.net/eric/ConfigKit v0.5.0/go.mod h1:tYWpsrbLyu05r8+1MapWp5fN6ZrX9I8hU2xEPedYmYk=
|
||||||
gitea.maximumdirect.net/eric/ReleaseKit v0.1.0 h1:Ejk85+9Of+A8M7Mod91iB3KxrrQYgnJcz9hPA6fL1a4=
|
gitea.maximumdirect.net/eric/ReleaseKit v0.3.0 h1:aTMn+50MEpHpHI2RoCCmJYsy7Ohrpa+RSva63Kq0/tU=
|
||||||
gitea.maximumdirect.net/eric/ReleaseKit v0.1.0/go.mod h1:KmH607Vc/RK/zKrCB96cWh0QZYvkbxBFvtqV+BkKaxs=
|
gitea.maximumdirect.net/eric/ReleaseKit v0.3.0/go.mod h1:LVodqNQ3OIKv9NBq+fFeyMByd1lHY25YOmmpah/NaNI=
|
||||||
gitea.maximumdirect.net/eric/promptkit v0.12.0 h1:oIFWEg6GPxtmX3Plqv0euP+FnK1LCk/t4xDy6oKCpP4=
|
gitea.maximumdirect.net/eric/promptkit v0.12.0 h1:oIFWEg6GPxtmX3Plqv0euP+FnK1LCk/t4xDy6oKCpP4=
|
||||||
gitea.maximumdirect.net/eric/promptkit v0.12.0/go.mod h1:pFOOy5v1zH17stEi9rmHYmfbuLjnfVMcUhfmk+4VtJY=
|
gitea.maximumdirect.net/eric/promptkit v0.12.0/go.mod h1:pFOOy5v1zH17stEi9rmHYmfbuLjnfVMcUhfmk+4VtJY=
|
||||||
gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v3 v3.20260930.0 h1:lzfCDbzJQRGzIlRPRprnAV9hVVL5zUQy80VMQ0kbYa0=
|
gitea.maximumdirect.net/eric/promptkit-backend-openrouter/v3 v3.20260930.0 h1:lzfCDbzJQRGzIlRPRprnAV9hVVL5zUQy80VMQ0kbYa0=
|
||||||
@@ -24,8 +24,12 @@ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0t
|
|||||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 h1:KRzFb2m7YtdldCEkzs6KqmJw4nqEVZGK7IN2kJkjTuQ=
|
||||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||||
|
github.com/yuin/goldmark/v2 v2.1.6 h1:igy0q9JcqovoFXFx/XjtU8sHVhcUHavPj2sA3EoKJUE=
|
||||||
|
github.com/yuin/goldmark/v2 v2.1.6/go.mod h1:G6M4/qOFtfn01/o14BU1UR2Lo5N3S9Qo7xCuz/sHjGQ=
|
||||||
go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4=
|
go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4=
|
||||||
go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
|
go.yaml.in/yaml/v4 v4.0.0-rc.6/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
|
||||||
|
golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
|
||||||
|
golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|||||||
@@ -3,23 +3,4 @@ set -euo pipefail
|
|||||||
|
|
||||||
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
script_dir=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
|
||||||
cd "$script_dir/.."
|
cd "$script_dir/.."
|
||||||
|
GOWORK=off GOTOOLCHAIN=local exec go tool releasekit "$@"
|
||||||
releasekit_module=gitea.maximumdirect.net/eric/ReleaseKit
|
|
||||||
bootstrap_dir=$(mktemp -d "${TMPDIR:-/tmp}/releasekit-bootstrap.XXXXXX")
|
|
||||||
trap 'rm -rf "$bootstrap_dir"' EXIT
|
|
||||||
cp go.mod "$bootstrap_dir/go.mod"
|
|
||||||
if [[ -f go.sum ]]; then
|
|
||||||
cp go.sum "$bootstrap_dir/go.sum"
|
|
||||||
else
|
|
||||||
: > "$bootstrap_dir/go.sum"
|
|
||||||
fi
|
|
||||||
cp "$bootstrap_dir/go.mod" "$bootstrap_dir/releasekit.mod"
|
|
||||||
cp "$bootstrap_dir/go.sum" "$bootstrap_dir/releasekit.sum"
|
|
||||||
|
|
||||||
mkdir -p bin
|
|
||||||
GOWORK=off GOTOOLCHAIN=local go list -mod=mod -modfile="$bootstrap_dir/releasekit.mod" -m "$releasekit_module" >/dev/null
|
|
||||||
GOWORK=off GOTOOLCHAIN=local go build -mod=mod -modfile="$bootstrap_dir/releasekit.mod" \
|
|
||||||
-o ./bin/releasekit "$releasekit_module/cmd/releasekit"
|
|
||||||
rm -rf "$bootstrap_dir"
|
|
||||||
trap - EXIT
|
|
||||||
exec ./bin/releasekit "$@"
|
|
||||||
|
|||||||
@@ -2,64 +2,30 @@ package scripts
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"go/version"
|
||||||
"maps"
|
"maps"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
"slices"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/mod/modfile"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const goStub = `#!/usr/bin/env bash
|
const goStub = `#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
case ${1:?missing Go command} in
|
printf '%s\0' "$PWD" "GOWORK=$GOWORK" "GOTOOLCHAIN=$GOTOOLCHAIN" "$@" > "$RELEASEKIT_GO_LOG"
|
||||||
list)
|
if [[ ${RELEASEKIT_BOOTSTRAP_STATUS:-0} != 0 ]]; then
|
||||||
log=$RELEASEKIT_LIST_LOG
|
|
||||||
printf '%s\0' "$PWD" "GOWORK=$GOWORK" "GOTOOLCHAIN=$GOTOOLCHAIN" "$@" > "$log"
|
|
||||||
modfile=
|
|
||||||
for argument in "$@"; do
|
|
||||||
case $argument in -modfile=*) modfile=${argument#-modfile=} ;; esac
|
|
||||||
done
|
|
||||||
[[ -n $modfile && -f $modfile && -f ${modfile%.mod}.sum ]]
|
|
||||||
cp "$modfile" "$RELEASEKIT_MODULE_LOG"
|
|
||||||
cp "${modfile%.mod}.sum" "$RELEASEKIT_SUM_LOG"
|
|
||||||
if [[ ${RELEASEKIT_BOOTSTRAP_STATUS:-0} != 0 ]]; then
|
|
||||||
exit "$RELEASEKIT_BOOTSTRAP_STATUS"
|
exit "$RELEASEKIT_BOOTSTRAP_STATUS"
|
||||||
fi
|
fi
|
||||||
printf '%s\n' v0.1.0
|
[[ $1 == tool && $2 == releasekit ]]
|
||||||
;;
|
shift 2
|
||||||
build)
|
|
||||||
printf '%s\0' "$PWD" "GOWORK=$GOWORK" "GOTOOLCHAIN=$GOTOOLCHAIN" "$@" > "$RELEASEKIT_BUILD_LOG"
|
|
||||||
if [[ ${RELEASEKIT_BOOTSTRAP_STATUS:-0} != 0 ]]; then
|
|
||||||
exit "$RELEASEKIT_BOOTSTRAP_STATUS"
|
|
||||||
fi
|
|
||||||
output=
|
|
||||||
while (($#)); do
|
|
||||||
case $1 in
|
|
||||||
-o)
|
|
||||||
shift
|
|
||||||
output=${1:?missing output path}
|
|
||||||
;;
|
|
||||||
-o=*) output=${1#-o=} ;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
[[ -n $output ]]
|
|
||||||
cat > "$output" <<'RELEASEKIT_TOOL'
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
printf '%s\0' "$PWD" "$@" > "$RELEASEKIT_ARGS_LOG"
|
printf '%s\0' "$PWD" "$@" > "$RELEASEKIT_ARGS_LOG"
|
||||||
exit "${RELEASEKIT_TOOL_STATUS:-0}"
|
exit "${RELEASEKIT_TOOL_STATUS:-0}"
|
||||||
RELEASEKIT_TOOL
|
|
||||||
chmod +x "$output"
|
|
||||||
;;
|
|
||||||
*) exit 64 ;;
|
|
||||||
esac
|
|
||||||
`
|
`
|
||||||
|
|
||||||
func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
||||||
@@ -71,10 +37,7 @@ func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
|||||||
cmd.Dir = layout.caller
|
cmd.Dir = layout.caller
|
||||||
cmd.Env = layout.environment(map[string]string{
|
cmd.Env = layout.environment(map[string]string{
|
||||||
"RELEASEKIT_ARGS_LOG": layout.argsLog,
|
"RELEASEKIT_ARGS_LOG": layout.argsLog,
|
||||||
"RELEASEKIT_BUILD_LOG": layout.buildLog,
|
"RELEASEKIT_GO_LOG": layout.goLog,
|
||||||
"RELEASEKIT_LIST_LOG": layout.listLog,
|
|
||||||
"RELEASEKIT_MODULE_LOG": layout.moduleLog,
|
|
||||||
"RELEASEKIT_SUM_LOG": layout.sumLog,
|
|
||||||
"RELEASEKIT_TOOL_STATUS": strconv.Itoa(toolStatus),
|
"RELEASEKIT_TOOL_STATUS": strconv.Itoa(toolStatus),
|
||||||
})
|
})
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
@@ -84,58 +47,13 @@ func TestReleaseWrapperForwardsNativeArgumentsAndStatus(t *testing.T) {
|
|||||||
if len(output) != 0 {
|
if len(output) != 0 {
|
||||||
t.Fatalf("unexpected output: %q", output)
|
t.Fatalf("unexpected output: %q", output)
|
||||||
}
|
}
|
||||||
|
wantGo := append([]string{layout.repo, "GOWORK=off", "GOTOOLCHAIN=local", "tool", "releasekit"}, args...)
|
||||||
listInvocation := readNULArguments(t, layout.listLog)
|
if got := readNULArguments(t, layout.goLog); !reflect.DeepEqual(got, wantGo) {
|
||||||
buildInvocation := readNULArguments(t, layout.buildLog)
|
t.Fatalf("Go invocation=%q, want %q", got, wantGo)
|
||||||
for name, invocation := range map[string][]string{"list": listInvocation, "build": buildInvocation} {
|
|
||||||
if len(invocation) < 4 || invocation[0] != layout.repo {
|
|
||||||
t.Fatalf("%s invocation=%q, want repository %q", name, invocation, layout.repo)
|
|
||||||
}
|
}
|
||||||
if invocation[1] != "GOWORK=off" || invocation[2] != "GOTOOLCHAIN=local" {
|
wantTool := append([]string{layout.repo}, args...)
|
||||||
t.Fatalf("%s environment=%q", name, invocation[1:3])
|
if got := readNULArguments(t, layout.argsLog); !reflect.DeepEqual(got, wantTool) {
|
||||||
}
|
t.Fatalf("tool invocation=%q, want %q", got, wantTool)
|
||||||
}
|
|
||||||
listArgs := listInvocation[3:]
|
|
||||||
buildArgs := buildInvocation[3:]
|
|
||||||
modfile := argumentValue(listArgs, "-modfile=")
|
|
||||||
if listArgs[0] != "list" || !slices.Contains(listArgs, "-mod=mod") || !slices.Contains(listArgs, "-m") || !slices.Contains(listArgs, "gitea.maximumdirect.net/eric/ReleaseKit") {
|
|
||||||
t.Fatalf("unexpected module-selection arguments: %q", listArgs)
|
|
||||||
}
|
|
||||||
if modfile == "" || argumentValue(buildArgs, "-modfile=") != modfile || !slices.Contains(buildArgs, "-mod=mod") {
|
|
||||||
t.Fatalf("list/build did not share alternate module metadata: list=%q build=%q", listArgs, buildArgs)
|
|
||||||
}
|
|
||||||
if buildArgs[0] != "build" || !slices.Contains(buildArgs, "gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit") {
|
|
||||||
t.Fatalf("unexpected build arguments: %q", buildArgs)
|
|
||||||
}
|
|
||||||
if relative, err := filepath.Rel(layout.repo, modfile); err != nil || relative == "." || (!strings.HasPrefix(relative, ".."+string(filepath.Separator)) && relative != "..") {
|
|
||||||
t.Fatalf("alternate module file %q is not outside repository %q: relative=%q error=%v", modfile, layout.repo, relative, err)
|
|
||||||
}
|
|
||||||
if module := readText(t, layout.moduleLog); !strings.Contains(module, "gitea.maximumdirect.net/eric/ReleaseKit v0.1.0") {
|
|
||||||
t.Fatalf("temporary module file does not retain selected ReleaseKit version: %q", module)
|
|
||||||
}
|
|
||||||
if sum := readText(t, layout.sumLog); !strings.Contains(sum, "fixture checksum") {
|
|
||||||
t.Fatalf("temporary sum file did not copy source checksums: %q", sum)
|
|
||||||
}
|
|
||||||
if sourceModule := readText(t, filepath.Join(layout.repo, "go.mod")); !strings.Contains(sourceModule, "gitea.maximumdirect.net/eric/ReleaseKit v0.1.0") {
|
|
||||||
t.Fatalf("source go.mod changed: %q", sourceModule)
|
|
||||||
}
|
|
||||||
if sourceSum := readText(t, filepath.Join(layout.repo, "go.sum")); sourceSum != "fixture checksum\n" {
|
|
||||||
t.Fatalf("source go.sum changed: %q", sourceSum)
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(modfile); !os.IsNotExist(err) {
|
|
||||||
t.Fatalf("temporary module file remains after wrapper: %v", err)
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(filepath.Join(filepath.Dir(modfile), "releasekit.sum")); !os.IsNotExist(err) {
|
|
||||||
t.Fatalf("temporary sum file remains after wrapper: %v", err)
|
|
||||||
}
|
|
||||||
if info, err := os.Stat(filepath.Join(layout.repo, "bin", "releasekit")); err != nil || !info.Mode().IsRegular() {
|
|
||||||
t.Fatalf("ReleaseKit executable was not built in bin: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
toolInvocation := readNULArguments(t, layout.argsLog)
|
|
||||||
wantToolInvocation := append([]string{layout.repo}, args...)
|
|
||||||
if !reflect.DeepEqual(toolInvocation, wantToolInvocation) {
|
|
||||||
t.Fatalf("tool invocation=%q, want %q", toolInvocation, wantToolInvocation)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -166,8 +84,22 @@ func TestDeliveryWorkflowUsesModuleSelectedReleaseKit(t *testing.T) {
|
|||||||
if err := yaml.Unmarshal(data, &workflow); err != nil {
|
if err := yaml.Unmarshal(data, &workflow); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if len(workflow.Matrix.Include) != 1 || workflow.Matrix.Include[0]["GO_IMAGE"] != "golang:1.25.5" {
|
goMod, err := modfile.Parse("go.mod", []byte(readText(t, "../go.mod")), nil)
|
||||||
t.Fatalf("workflow Go image = %v, want existing Go 1.25.5 image", workflow.Matrix.Include)
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if goMod.Go == nil {
|
||||||
|
t.Fatal("module does not declare its Go minimum")
|
||||||
|
}
|
||||||
|
if len(workflow.Matrix.Include) != 1 {
|
||||||
|
t.Fatalf("workflow Go matrix = %v", workflow.Matrix.Include)
|
||||||
|
}
|
||||||
|
image := workflow.Matrix.Include[0]["GO_IMAGE"]
|
||||||
|
_, tag, _ := strings.Cut(image, ":")
|
||||||
|
patch, _, _ := strings.Cut(tag, "-")
|
||||||
|
imageVersion := "go" + patch
|
||||||
|
if !version.IsValid(imageVersion) || version.Compare(imageVersion, "go"+goMod.Go.Version) < 0 {
|
||||||
|
t.Fatalf("workflow Go image %q cannot satisfy module minimum %s", image, goMod.Go.Version)
|
||||||
}
|
}
|
||||||
if len(workflow.When) != 1 || workflow.When[0].Event != "tag" || workflow.When[0].Ref != "refs/tags/v*" {
|
if len(workflow.When) != 1 || workflow.When[0].Event != "tag" || workflow.When[0].Ref != "refs/tags/v*" {
|
||||||
t.Fatalf("workflow trigger = %+v", workflow.When)
|
t.Fatalf("workflow trigger = %+v", workflow.When)
|
||||||
@@ -183,41 +115,30 @@ func TestDeliveryWorkflowUsesModuleSelectedReleaseKit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
command := workflow.Steps[0].Commands[0]
|
command := workflow.Steps[0].Commands[0]
|
||||||
for _, fragment := range []string{
|
for _, fragment := range []string{
|
||||||
"git fetch origin \"refs/tags/$${CI_COMMIT_TAG}:refs/tags/$${CI_COMMIT_TAG}\"",
|
"git fetch origin", "refs/tags/$${CI_COMMIT_TAG}",
|
||||||
"git checkout --detach \"$${tag_commit}\"",
|
"git checkout --detach", "git status --porcelain",
|
||||||
"git status --porcelain --untracked-files=all",
|
"go list", "-modfile=", "-m", "go build", "$${releasekit_module}/cmd/releasekit",
|
||||||
"mktemp -d \"$${CI_WORKSPACE%/*}/.releasekit-bootstrap.XXXXXX\"",
|
"ci-deliver", "--repo \"$${CI_WORKSPACE}\"", "--commit \"$${CI_COMMIT_SHA}\"",
|
||||||
"trap 'rm -rf \"$${bootstrap_dir}\"' EXIT",
|
|
||||||
"cp go.mod \"$${bootstrap_dir}/go.mod\"",
|
|
||||||
"cp go.sum \"$${bootstrap_dir}/go.sum\"",
|
|
||||||
"export GOWORK=off",
|
|
||||||
"export GOTOOLCHAIN=local",
|
|
||||||
"releasekit_module=gitea.maximumdirect.net/eric/ReleaseKit",
|
|
||||||
"go list -mod=mod -modfile=",
|
|
||||||
"-m \"$${releasekit_module}\"",
|
|
||||||
"go build -mod=mod -modfile=",
|
|
||||||
"-o \"$${bootstrap_dir}/releasekit\" \"$${releasekit_module}/cmd/releasekit\"",
|
|
||||||
"\"$${bootstrap_dir}/releasekit\" ci-deliver",
|
|
||||||
"--repo \"$${CI_WORKSPACE}\"",
|
|
||||||
"--commit \"$${CI_COMMIT_SHA}\"",
|
|
||||||
"\"$${CI_COMMIT_TAG}\"",
|
"\"$${CI_COMMIT_TAG}\"",
|
||||||
} {
|
} {
|
||||||
if !strings.Contains(command, fragment) {
|
if !strings.Contains(command, fragment) {
|
||||||
t.Fatalf("workflow command is missing %q: %s", fragment, command)
|
t.Fatalf("workflow command is missing %q: %s", fragment, command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.Index(command, "git checkout --detach") > strings.Index(command, "go list -mod=mod") || strings.Index(command, "git status --porcelain") > strings.Index(command, "go list -mod=mod") {
|
if strings.Index(command, "git checkout --detach") > strings.Index(command, "go list") || strings.Index(command, "git status --porcelain") > strings.Index(command, "go list") {
|
||||||
t.Fatalf("workflow resolves the tool before verifying the tagged source: %s", command)
|
t.Fatalf("workflow resolves the tool before verifying the tagged source: %s", command)
|
||||||
}
|
}
|
||||||
if strings.Contains(command, "RELEASEKIT_VERSION") || strings.Contains(command, "cmd/releasekit@") {
|
if strings.Contains(command, "RELEASEKIT_VERSION") || strings.Contains(command, "cmd/releasekit@") {
|
||||||
t.Fatalf("workflow retains a separate tool version: %s", command)
|
t.Fatalf("workflow retains a separate tool version: %s", command)
|
||||||
}
|
}
|
||||||
goMod, err := os.ReadFile("../go.mod")
|
toolSelected := false
|
||||||
if err != nil {
|
for _, tool := range goMod.Tool {
|
||||||
t.Fatal(err)
|
if tool.Path == "gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit" {
|
||||||
|
toolSelected = true
|
||||||
}
|
}
|
||||||
if !strings.Contains(string(goMod), "gitea.maximumdirect.net/eric/ReleaseKit v0.1.0") {
|
}
|
||||||
t.Fatalf("go.mod does not retain selected supported ReleaseKit version: %s", goMod)
|
if !toolSelected {
|
||||||
|
t.Fatal("module does not register the ReleaseKit CLI tool")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,10 +148,7 @@ func TestReleaseWrapperStopsWhenBootstrapFails(t *testing.T) {
|
|||||||
cmd.Dir = layout.caller
|
cmd.Dir = layout.caller
|
||||||
cmd.Env = layout.environment(map[string]string{
|
cmd.Env = layout.environment(map[string]string{
|
||||||
"RELEASEKIT_ARGS_LOG": layout.argsLog,
|
"RELEASEKIT_ARGS_LOG": layout.argsLog,
|
||||||
"RELEASEKIT_BUILD_LOG": layout.buildLog,
|
"RELEASEKIT_GO_LOG": layout.goLog,
|
||||||
"RELEASEKIT_LIST_LOG": layout.listLog,
|
|
||||||
"RELEASEKIT_MODULE_LOG": layout.moduleLog,
|
|
||||||
"RELEASEKIT_SUM_LOG": layout.sumLog,
|
|
||||||
"RELEASEKIT_BOOTSTRAP_STATUS": "42",
|
"RELEASEKIT_BOOTSTRAP_STATUS": "42",
|
||||||
})
|
})
|
||||||
output, err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
@@ -240,17 +158,6 @@ func TestReleaseWrapperStopsWhenBootstrapFails(t *testing.T) {
|
|||||||
if _, err := os.Stat(layout.argsLog); !os.IsNotExist(err) {
|
if _, err := os.Stat(layout.argsLog); !os.IsNotExist(err) {
|
||||||
t.Fatalf("ReleaseKit executed after failed bootstrap; stat error=%v", err)
|
t.Fatalf("ReleaseKit executed after failed bootstrap; stat error=%v", err)
|
||||||
}
|
}
|
||||||
if _, err := os.Stat(layout.buildLog); !os.IsNotExist(err) {
|
|
||||||
t.Fatalf("ReleaseKit build ran after module selection failed; stat error=%v", err)
|
|
||||||
}
|
|
||||||
listInvocation := readNULArguments(t, layout.listLog)
|
|
||||||
modfile := argumentValue(listInvocation[3:], "-modfile=")
|
|
||||||
if modfile == "" {
|
|
||||||
t.Fatalf("module selection did not use temporary metadata: %q", listInvocation)
|
|
||||||
}
|
|
||||||
if _, err := os.Stat(filepath.Dir(modfile)); !os.IsNotExist(err) {
|
|
||||||
t.Fatalf("temporary bootstrap directory remains after failed selection: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
|
func TestReleaseKitProfileDeclaresProductAndDeliverySettings(t *testing.T) {
|
||||||
@@ -331,10 +238,7 @@ type releaseTestLayout struct {
|
|||||||
caller string
|
caller string
|
||||||
wrapper string
|
wrapper string
|
||||||
argsLog string
|
argsLog string
|
||||||
buildLog string
|
goLog string
|
||||||
listLog string
|
|
||||||
moduleLog string
|
|
||||||
sumLog string
|
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,20 +249,13 @@ func newReleaseTestLayout(t *testing.T) releaseTestLayout {
|
|||||||
repo: filepath.Join(root, "repository"),
|
repo: filepath.Join(root, "repository"),
|
||||||
caller: filepath.Join(root, "caller"),
|
caller: filepath.Join(root, "caller"),
|
||||||
argsLog: filepath.Join(root, "tool-arguments"),
|
argsLog: filepath.Join(root, "tool-arguments"),
|
||||||
buildLog: filepath.Join(root, "build-arguments"),
|
goLog: filepath.Join(root, "go-arguments"),
|
||||||
listLog: filepath.Join(root, "list-arguments"),
|
|
||||||
moduleLog: filepath.Join(root, "temporary-go.mod"),
|
|
||||||
sumLog: filepath.Join(root, "temporary-go.sum"),
|
|
||||||
path: filepath.Join(root, "bin"),
|
path: filepath.Join(root, "bin"),
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(filepath.Join(layout.repo, "scripts"), 0755); err != nil {
|
for _, directory := range []string{filepath.Join(layout.repo, "scripts"), layout.caller, layout.path} {
|
||||||
|
if err := os.MkdirAll(directory, 0755); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(layout.caller, 0755); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := os.MkdirAll(layout.path, 0755); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
}
|
||||||
wrapper, err := os.ReadFile("release.sh")
|
wrapper, err := os.ReadFile("release.sh")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -367,8 +264,6 @@ func newReleaseTestLayout(t *testing.T) releaseTestLayout {
|
|||||||
layout.wrapper = filepath.Join(layout.repo, "scripts", "release.sh")
|
layout.wrapper = filepath.Join(layout.repo, "scripts", "release.sh")
|
||||||
writeReleaseTestFile(t, layout.wrapper, wrapper, 0755)
|
writeReleaseTestFile(t, layout.wrapper, wrapper, 0755)
|
||||||
writeReleaseTestFile(t, filepath.Join(layout.path, "go"), []byte(goStub), 0755)
|
writeReleaseTestFile(t, filepath.Join(layout.path, "go"), []byte(goStub), 0755)
|
||||||
writeReleaseTestFile(t, filepath.Join(layout.repo, "go.mod"), []byte("module example.com/audita-fixture\n\ngo 1.25.5\n\nrequire gitea.maximumdirect.net/eric/ReleaseKit v0.1.0\n"), 0644)
|
|
||||||
writeReleaseTestFile(t, filepath.Join(layout.repo, "go.sum"), []byte("fixture checksum\n"), 0644)
|
|
||||||
return layout
|
return layout
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,15 +276,6 @@ func readText(t *testing.T, path string) string {
|
|||||||
return string(data)
|
return string(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func argumentValue(arguments []string, prefix string) string {
|
|
||||||
for _, argument := range arguments {
|
|
||||||
if strings.HasPrefix(argument, prefix) {
|
|
||||||
return strings.TrimPrefix(argument, prefix)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (layout releaseTestLayout) environment(values map[string]string) []string {
|
func (layout releaseTestLayout) environment(values map[string]string) []string {
|
||||||
filtered := make([]string, 0, len(os.Environ())+len(values)+1)
|
filtered := make([]string, 0, len(os.Environ())+len(values)+1)
|
||||||
for _, value := range os.Environ() {
|
for _, value := range os.Environ() {
|
||||||
|
|||||||
Reference in New Issue
Block a user