6.0 KiB
Release automation and reproducible packaging. sshkeeper itself behaves exactly as in v0.3.1 — no functional changes to the TUI or the CLI.
This is also the first release published by GitHub Actions rather than by hand.
In this release
Archives are now reproducible. Rebuilding a tag on a different machine used to produce different checksums even when every packaged file was byte-identical, because three host properties leaked into the archives:
| Leak | Effect |
|---|---|
| File modes followed the builder's umask | umask 002 packaged 664/775, umask 022 packaged 644/755 |
sort orders entries by locale |
a ru_RU.UTF-8 host emitted docs/ before LICENSE, a C locale the reverse |
| zip stores DOS local time with no zone | the same commit embedded 19:06 at UTC+08 and 11:06 at UTC |
All three are pinned now. A build on ubuntu-latest and one on a workstation
with a different umask, locale and timezone produce identical checksums for all
five archives. The binaries were always reproducible; only the packaging varied.
CI. The repository previously had no automation. It now runs gofmt,
go vet and go test on Linux and macOS for every push and pull request,
plus a cross-build of all five release targets. macOS is a stated release
target that until now was only ever cross-compiled, never tested.
Releases are automated. Pushing a v* tag runs the release checks, builds
through the same release.sh used locally, and publishes. Nightly builds from
main are published as a separate nightly prerelease, so the Latest badge
always points at a real release.
Everything since v0.2.0
Breaking change: full help moved off F1
Ctrl+H opens full help. F1 no longer has any binding. ? still opens
contextual quick help outside text editors. This landed in v0.3.0.
Ctrl+H is the BS control character (0x08). xterm and most modern emulators
send DEL (0x7F) for Backspace, so help and text editing do not collide. A
terminal configured to send BS for Backspace cannot tell them apart; switch it
to DEL (in xterm, backarrowKey: false).
Nothing else requires action when upgrading. Vaults, server profiles and stored port forwards are unchanged, and no migration runs.
The TUI was rebuilt around one shell (v0.3.0)
In v0.2.0 only the server dashboard had a real layout. Other screens rendered free-form strings or the default Bubbles list frame, so they had no shared width budget, no borders, and footers that floated wherever the content ended.
Every full-screen state now shares one contract: a header with breadcrumb and truthful vault status, a separator, framed content panels, and a contextual footer anchored to the last terminal row.
- Actions, search, tag input, confirmations and both help screens render inside the shell.
- The port forward manager and editor use framed, width-budgeted layouts. Column widths derive from the panel's inner width, so no row consumes the terminal's last column.
- Tag, command template, template picker/mode/results and tunnel managers use
framed lists with a
>selection marker, so selection never depends on colour alone. - Server and template editors use a framed form panel with the title moved into the breadcrumb. Required markers, validation and dirty-state confirmation are unchanged.
Responsive layouts. The supported floor is 60x16. Wide (100+ columns)
shows two panels, medium (70–99) stacks them, narrow (60–69) keeps a single
compact panel. Below the floor only the minimum-size message renders. Long
ASCII, Cyrillic, CJK, combining and emoji content truncates by display cells
rather than byte count.
Safety. Destructive actions confirm with Cancel selected first and name the exact target and its consequence. Status and help context stay truthful to actual vault and connection state. Form validation prevents silent loss of edits.
forward add was completely broken (fixed in v0.3.1)
sshkeeper forward add could never succeed in v0.2.0 or v0.3.0. The command
read --local-port and marked it required, but the flag was never registered,
so cobra rejected it as unknown and the value fell back to 0:
$ sshkeeper forward add web --type local --local-port 15432 \
--remote-addr 127.0.0.1 --remote-port 5432
unknown flag: --local-port
No combination of arguments worked. Both documented forms work now:
$ sshkeeper forward add web --name "Local PostgreSQL" --type local \
--local-port 15432 --remote-addr db01.internal.example.com --remote-port 5432
✓ Forward added [1]
$ sshkeeper forward add web --name "SOCKS proxy" --type dynamic --local-port 1080
✓ Forward added [2]
Omitting the flag now reports required flag(s) "local-port" not set instead of
a misleading port-range error. The TUI (Ctrl+W) was never affected.
The command's tests had constructed their own throwaway cobra command and registered the flags by hand, so the real command's registration was never exercised and the suite passed against a broken command. Coverage now parses argv into the actual command. An audit of every other command found no further flag that is read but never registered.
Also fixed since v0.2.0
- Port forward fields accept digits correctly (
10bcc07). - Platform and repository status are stated accurately in the docs: Linux and macOS are primary release targets, Windows is experimental.
Release-by-release
| Version | Contents |
|---|---|
| v0.3.0 | Unified TUI shell, responsive layouts, F1 → Ctrl+H |
| v0.3.1 | forward add fix |
| v0.3.2 | Reproducible packaging, CI, automated releases |
Install
tar -xzf sshkeeper_v0.3.2_linux_amd64.tar.gz
sudo install -m 0755 sshkeeper_v0.3.2_linux_amd64/sshkeeper /usr/local/bin/sshkeeper
Verify downloads against checksums.txt. Linux and macOS are the primary
release targets; the Windows build is experimental and needs OpenSSH Client
available as ssh.exe on PATH.
To verify a build yourself, check out the tag and run ./release.sh v0.3.2 —
the checksums should match this release exactly, given the same Go version.