fix: prepare Tend preview 2
Publish the reviewed version identity fix and mark preview 1 withdrawn.\n\nPrivate-Source-Commit: 9907afdfa18099ac488fe4011291ea454036435a\nPrivate-Source-Tree: 3a5e666dd6a0c69a07f7804612c8e3dc3474966a\nHimesan-Output-Permission: v1.0\nAI-Assistance: OpenAI Codex assisted implementation and review. Signed-off-by: Cole Speelman <crspeelman@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@ shell hooks. Application-specific data activation remains application-specific.
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
tend check --config tend.json
|
tend check --config tend.json
|
||||||
tend package --config tend.json --version v0.1.0-preview.1 --out dist
|
tend package --config tend.json --version v0.1.0-preview.2 --out dist
|
||||||
tend deploy --config /etc/example/tend.json --artifact FILE --sha256 HEX --approve-sha256 HEX
|
tend deploy --config /etc/example/tend.json --artifact FILE --sha256 HEX --approve-sha256 HEX
|
||||||
tend status --config /etc/example/tend.json
|
tend status --config /etc/example/tend.json
|
||||||
tend rollback --config /etc/example/tend.json
|
tend rollback --config /etc/example/tend.json
|
||||||
|
|||||||
+7
-1
@@ -1,6 +1,6 @@
|
|||||||
# Preview release policy
|
# Preview release policy
|
||||||
|
|
||||||
`v0.1.0-preview.1` may be published only after one identical candidate Tend
|
`v0.1.0-preview.2` may be published only after one identical candidate Tend
|
||||||
binary has successfully completed maintenance releases for Gamertan and the
|
binary has successfully completed maintenance releases for Gamertan and the
|
||||||
Sandwich Hime website, including injected-failure restoration and explicit
|
Sandwich Hime website, including injected-failure restoration and explicit
|
||||||
rollback proof. The August 14, 2026 campaign met that gate; the scoped,
|
rollback proof. The August 14, 2026 campaign met that gate; the scoped,
|
||||||
@@ -19,6 +19,12 @@ The release tag and attached candidate must be built from the final reviewed
|
|||||||
source commit. Documentation-only changes after the recorded campaign require
|
source commit. Documentation-only changes after the recorded campaign require
|
||||||
one final identical-candidate maintenance pass before tagging.
|
one final identical-candidate maintenance pass before tagging.
|
||||||
|
|
||||||
|
`v0.1.0-preview.1` is immutable but withdrawn: its source and module checksums
|
||||||
|
are valid, while a fresh `go install` reports the development identity because
|
||||||
|
the CLI did not yet adopt the tagged module version from Go build information.
|
||||||
|
Preview 2 adds that identity path and its regression tests; preview 1 is never
|
||||||
|
retagged or rewritten.
|
||||||
|
|
||||||
The canonical public origin is `ssh://git@gitea.speelman.ca:2222/gamertan/tend.git`.
|
The canonical public origin is `ssh://git@gitea.speelman.ca:2222/gamertan/tend.git`.
|
||||||
GitHub is a read-only discovery snapshot. Private development history is not
|
GitHub is a read-only discovery snapshot. Private development history is not
|
||||||
published or merged into either public history.
|
published or merged into either public history.
|
||||||
|
|||||||
@@ -22,6 +22,13 @@ The release tag and attached assets must still identify their own exact source
|
|||||||
commit and digests. Any code change after this campaign requires the dogfood
|
commit and digests. Any code change after this campaign requires the dogfood
|
||||||
sequence to be repeated.
|
sequence to be repeated.
|
||||||
|
|
||||||
|
A fresh-install check after the first immutable source tag found that the CLI
|
||||||
|
reported its development identity instead of the tagged module version. No
|
||||||
|
deployment logic or artifact content was ambiguous, but the distribution
|
||||||
|
identity was not acceptable. Preview 1 remains immutable and withdrawn;
|
||||||
|
Preview 2 adds Go build-information version selection and repeats the release
|
||||||
|
gates rather than retagging old content.
|
||||||
|
|
||||||
## Sandwich Hime website
|
## Sandwich Hime website
|
||||||
|
|
||||||
The singleton-candidate strategy packaged and activated website preview 25:
|
The singleton-candidate strategy packaged and activated website preview 25:
|
||||||
|
|||||||
@@ -2,8 +2,81 @@
|
|||||||
|
|
||||||
package version
|
package version
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"runtime/debug"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const developmentVersion = "v0.1.0-dev"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Version = "v0.1.0-dev"
|
Version = developmentVersion
|
||||||
Commit = "unknown"
|
Commit = "unknown"
|
||||||
Date = "unknown"
|
Date = "unknown"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
taggedVersionPattern = regexp.MustCompile(`^v(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$`)
|
||||||
|
pseudoVersionSuffixPattern = regexp.MustCompile(`(?:^|[.-])(?:0\.)?[0-9]{14}-[0-9a-f]{12,}$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
information, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Version = selectVersion(Version, information.Main.Version)
|
||||||
|
for _, setting := range information.Settings {
|
||||||
|
switch setting.Key {
|
||||||
|
case "vcs.revision":
|
||||||
|
if Commit == "unknown" && setting.Value != "" {
|
||||||
|
Commit = setting.Value
|
||||||
|
}
|
||||||
|
case "vcs.time":
|
||||||
|
if Date == "unknown" && setting.Value != "" {
|
||||||
|
Date = setting.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func selectVersion(linkerValue, moduleVersion string) string {
|
||||||
|
if linkerValue != developmentVersion {
|
||||||
|
return linkerValue
|
||||||
|
}
|
||||||
|
moduleVersion = strings.TrimSpace(moduleVersion)
|
||||||
|
if !isTaggedVersion(moduleVersion) {
|
||||||
|
return linkerValue
|
||||||
|
}
|
||||||
|
return moduleVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTaggedVersion(value string) bool {
|
||||||
|
matches := taggedVersionPattern.FindStringSubmatch(value)
|
||||||
|
if matches == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
prerelease := matches[1]
|
||||||
|
if pseudoVersionSuffixPattern.MatchString(prerelease) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, identifier := range strings.Split(prerelease, ".") {
|
||||||
|
if len(identifier) > 1 && identifier[0] == '0' && allDecimal(identifier) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func allDecimal(value string) bool {
|
||||||
|
if value == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, character := range value {
|
||||||
|
if character < '0' || character > '9' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
package version
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestSelectVersion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
tests := []struct {
|
||||||
|
name, linker, module, want string
|
||||||
|
}{
|
||||||
|
{"local build", developmentVersion, "(devel)", developmentVersion},
|
||||||
|
{"missing build info", developmentVersion, "", developmentVersion},
|
||||||
|
{"preview one install", developmentVersion, "v0.1.0-preview.1", "v0.1.0-preview.1"},
|
||||||
|
{"preview two install", developmentVersion, "v0.1.0-preview.2", "v0.1.0-preview.2"},
|
||||||
|
{"release install", developmentVersion, "v1.0.0", "v1.0.0"},
|
||||||
|
{"linker override", "v0.1.0-preview.2", "(devel)", "v0.1.0-preview.2"},
|
||||||
|
{"pseudo version", developmentVersion, "v0.0.0-20260814120000-0123456789ab", developmentVersion},
|
||||||
|
{"pseudo after release", developmentVersion, "v0.1.1-0.20260814120000-0123456789ab", developmentVersion},
|
||||||
|
{"build metadata", developmentVersion, "v0.1.0+dirty", developmentVersion},
|
||||||
|
{"leading zero release", developmentVersion, "v00.1.0", developmentVersion},
|
||||||
|
{"leading zero prerelease", developmentVersion, "v0.1.0-preview.02", developmentVersion},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
if got := selectVersion(test.linker, test.module); got != test.want {
|
||||||
|
t.Fatalf("selectVersion(%q, %q)=%q want %q", test.linker, test.module, got, test.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,6 +36,7 @@ internal/provenance/git.go
|
|||||||
internal/state/state.go
|
internal/state/state.go
|
||||||
internal/state/state_test.go
|
internal/state/state_test.go
|
||||||
internal/version/version.go
|
internal/version/version.go
|
||||||
|
internal/version/version_test.go
|
||||||
release/tend.json
|
release/tend.json
|
||||||
scripts/check-licenses.sh
|
scripts/check-licenses.sh
|
||||||
scripts/export-public.sh
|
scripts/export-public.sh
|
||||||
|
|||||||
Reference in New Issue
Block a user