Commit Graph

6 Commits (v0.3.2)

Author SHA1 Message Date
mirivlad a19b3deb24 docs: add v0.3.2 release notes and reproducibility results
Exercise the release workflow end to end. v0.3.1 was tagged and published by
hand before release.yml existed, so the tag-triggered path has never actually
run; this tag is the first to go through it.

Add docs/releases/v0.3.2.md, which release.yml picks up as the release body
instead of falling back to generated notes. The notes cover the whole v0.2.0
range rather than just this tag, since v0.3.0 through v0.3.2 landed in quick
succession and the F1 to Ctrl+H change is the one thing an upgrader must know.

Also record the measured reproducibility result: with modes, locale and
timezone pinned, ubuntu-latest and a workstation on a different umask, locale
and timezone now produce identical checksums for all five archives.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:13:50 +08:00
mirivlad 878f7b4472 fix: normalize file modes when packaging a release
release.sh normalized entry order, ownership and mtimes, but not permissions,
so the archives inherited the builder's umask. A host with umask 002 packaged
664/775 while ubuntu-latest packaged 644/755, and the two archives hashed
differently even though every file inside was byte-identical:

  CI     -rw-r--r--  README.md   local  -rw-rw-r--  README.md
  CI     -rwxr-xr-x  sshkeeper   local  -rwxrwxr-x  sshkeeper

Force 755 on directories and the program, 644 on everything else. Building the
same commit under umask 002 and umask 022 now yields identical checksums.

Also correct the reproducibility claim in the release docs. What is reproducible
is the binary, given the same commit and Go version; the archive hash still
depends on the host tar and gzip, so the documented verification step now
compares the extracted binary instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 19:06:12 +08:00
mirivlad 0a02f0fc60 ci: add test, release and nightly workflows
The repository had no automation at all: every release was packaged and
published by hand, and nothing ran tests on a pull request.

- ci.yml runs gofmt, go vet and go test on Linux and macOS, and cross-builds
  all five release targets. macOS is a stated release target but was never
  actually exercised, only cross-compiled.
- release.yml publishes on a v* tag. It gates on `make release-check` so a red
  suite cannot ship, and builds through release.sh rather than duplicating the
  packaging rules, so CI archives stay byte-identical to local ones. A
  hand-written docs/releases/<tag>.md becomes the release body when present,
  otherwise notes are generated from history.
- nightly.yml rebuilds the tip of main on every push and replaces a rolling
  `nightly` prerelease. Prerelease is deliberate: it keeps GitHub's `Latest`
  badge on the newest real release rather than on an untested build.

The rolling tag is why version discovery was pinned to v* in the previous
commit; nightly.yml depends on that filter already being in place.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 18:59:40 +08:00
mirivlad 19ffc4ba5e build: pin version discovery to v* tags
Nightly builds will move a rolling `nightly` tag across main. A plain
`git describe --tags` returns whichever tag is nearest, so once that tag exists
every build — including a real release build — would report its version as
"nightly" and lose the release lineage entirely.

Restrict discovery to `v*` so the rolling tag is invisible to versioning:

  with a nightly tag ahead of v0.3.1
    git describe --tags                → nightly
    git describe --tags --match 'v*'   → v0.3.1-1-gf940087

Land this before the nightly workflow exists, so no build is ever stamped from
the rolling tag.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 18:56:45 +08:00
mirivlad 604a4ecde2 docs: clarify platform and repository status 2026-06-06 11:14:15 +08:00
mirivlad 8e59c3052e feat: add cross-platform release packaging 2026-06-06 10:49:56 +08:00