feat(tpagectl): add self-update #622
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
thwap/thwap-pagesd!622
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/tpagectl-update"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implements Phase 9 auto-update (roadmap #306).
internal/tpagectl/updatepackage with atpagectl updatecommand:net/httpclient queries the public APIGET {host}/api/v1/repos/{owner}/{repo}/releases/latestand compares semantic versions.update --checkreports the latest release and whether an update is available.updatecommand — selects the platform-specific release asset (tpagectl_<ver>_<os>_<arch>.tar.gz/.zip) for the runtimeGOOS/GOARCH, and reports "already up to date" when current ≥ latest.tarballs.sha256, extracts the binary, backs up the current executable (.bak), stages and atomically renames the new binary (0755), restoring the backup on any failure.getExecutableis injectable for tests.--yes/-yto skip) and refuses to self-update a development build (non-semverversion).update.host/update.owner/update.repokeys (defaultsgit.lan.thwap.org/thwap/thwap-pagesd,TPAGECTL_UPDATE_*env) plus--host/--owner/--repoflags.docs/commands/tpagectl-update.*+ root-help golden regenerated.Why
Roadmap task #306, the last item in Phase 9.
Testing
.bakremoved on success)--checkreports latest; already-up-to-date; dev-build refusal onupdate+ note on--check; end-to-endupdate --yesreplaces the binary and removes the backup (via injected executable path + httptest fake Forgejo)TPAGECTL_UPDATE_*env mappedgo test -race ./...passes (31 packages);make coverage= 84.7% (≥80% gate)golangci-lint runclean; pre-commit hooks passBreaking Changes
None. Adds an
updatecommand and a newupdateconfig section.Notes
No
thwap-actionsaction exists for self-update (this is a CLI feature), so it's implemented in-repo, consuming the releases/tarballs.sha256that the release workflow publishes. Windows self-replace of a running.exemay be restricted by the OS; rollback restores the backup if the rename fails.Closes #303
Closes #304
Closes #305
Closes #306
Solid self-update implementation. The flow is correctly ordered (checksum verify → extract → atomic replace with backup+rollback), extraction writes to a fixed destination (no zip-slip),
getExecutableis injectable for tests, the semver/dev-build guards are right, and config/env/flag precedence is clean. Approving; one security finding filed.Suggestions
internal/tpagectl/update/update.go:317–verifyChecksumpullstarballs.sha256from the same releases API as the archive, so it provides integrity but not authenticity. A compromised host, a taken-over release account, or a maliciousupdate.host/owner/repoconfig ships matching checksums + binary → arbitrary code execution on update. Consider signing (minisign/cosign) or documenting the trust model. Filed as #623.Notes
golang-releasenaming Windows artifacts with.exeso the.zipbranch in #618 fires; otherwiseassetForfinds no.zipand update fails on Windows (the #619 coupling).updatestill runs the rootBeforehook (daemon client + keychain bootstrap) — a malformed config or genuine keychain error blocksupdate(same pattern as #611)._ = os.Rename(backup, execPath)); on Windows a locked running binary can orphan a.bak.Praise
tpagectl_<ver>_<os>_<arch>.tar.gz/.zip).--checkhandling are clean and user-friendly.