Releases publish only two things per tool now: a current-stable
canonical symlink and an immutable per-version file. No more channel
mirrors (_stable/_beta/_alpha) and no more partial-version pins
(_v<X.Y>, _v<X>) — those were debt from a release model that never
matched the project's actual usage.
The `./build beta` verb stays, but narrowed: it's an internal SHA
snapshot for the BMC dev chart pipeline (chart's appVersion pins to
"<X.Y.Z>-beta-<sha>" and the chart Dockerfile fetches that SHA from
git). No public artifact on /srv/zddc/releases/. The embedded/* +
chore commit produced by `./build beta` is the actual snapshot.
`./build alpha` is removed entirely.
build/build-lib.sh:
- Drop alpha verb; narrow beta verb to embedded regen + chore commit
- promote_release: stable cut writes <tool>_v<X.Y.Z>.html + <tool>.html
symlink + <tool>.html.sig companion symlink; beta is a no-op
- promote_zddc_server: same shape — per-version binary +
per-platform canonical symlink (zddc-server_<plat>) + .sig symlink
- write_zddc_server_stub: singular; emits per-version stubs +
one canonical zddc-server.html for current stable
- Delete _promote_channel, verify_channel_links, _channel_is_active
- Seed-from-live now copies only per-version files + .sig + pubkey.pem
(the canonical symlinks get rewritten by this cut; old layout files
get cleaned by deploy's --delete-after)
- build_releases_index: dropdown simplified to "latest stable +
pinned versions"; channels-explainer section removed; tool cards +
CTA URLs point at canonical <tool>.html / zddc-server_<plat>;
composer emits "stable" sentinel for `apps:` entries
- Fix the acl:{allow:[...]} footgun in the apps_pubkey example
apps.go:
- isValidChannelOrVersion: accept only "stable" + exact X.Y.Z
(drop alpha/beta and partial pins v0.0/v0)
- normalizeChannel: same
- Resolve URL composition: stable → canonical <prefix>/<app>.html
(no _stable_ suffix), exact-version → <prefix>/<app>_v<X.Y.Z>.html
- Tests rewritten to match (beta/alpha replaced with v0.0.4 / stable;
a new TestParseSpec_RejectsLegacyChannelsAndPartialPins locks in
that the removed forms now error)
browse/build.sh: gate promote_release on $is_release like every other
tool's build.sh (longstanding inconsistency that errored under the new
promote_release case-statement).
freshen-channel: deleted (no channels to freshen).
Net: -254 lines, all green on full `go test ./...`. Dev build verified
via `./build` (no-arg) — new label format "v<next>-dev · <ts> · <sha>".
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
package apps
|
|
|
|
import (
|
|
"strings"
|
|
|
|
_ "embed"
|
|
)
|
|
|
|
// embeddedVersionsRaw is the manifest written by the top-level build.sh
|
|
// at compile time. Format is one `<app>=<build label>` line per app —
|
|
// e.g. `archive=v0.0.5-beta · 2026-05-01 14:00:00 · abc1234`. An empty
|
|
// or missing value indicates the embedded slot was not populated (a fresh
|
|
// clone where build.sh hasn't run yet).
|
|
//
|
|
//go:embed embedded/versions.txt
|
|
var embeddedVersionsRaw []byte
|
|
|
|
// EmbeddedVersions returns the build label of each tool baked into the
|
|
// binary, keyed by canonical app name. Apps with empty values are
|
|
// omitted. Caller copies the map if mutation is needed.
|
|
func EmbeddedVersions() map[string]string {
|
|
out := make(map[string]string, 5)
|
|
for _, line := range strings.Split(string(embeddedVersionsRaw), "\n") {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
eq := strings.IndexByte(line, '=')
|
|
if eq <= 0 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(line[:eq])
|
|
val := strings.TrimSpace(line[eq+1:])
|
|
if val != "" {
|
|
out[key] = val
|
|
}
|
|
}
|
|
return out
|
|
}
|