Skip to content

Keep a board current on its own: check for releases, install, restart - #11

Merged
ralyodio merged 1 commit into
mainfrom
autoupdate
Sep 3, 2026
Merged

Keep a board current on its own: check for releases, install, restart#11
ralyodio merged 1 commit into
mainfrom
autoupdate

Conversation

@ralyodio

@ralyodio ralyodio commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What

A board keeps itself current. A minute after boot and every five minutes after that, it asks GitHub for the newest release; when one is newer and the board runs from a git checkout, it fetches the tag, installs, and restarts itself.

  • On by default. An administrator turns it off under Board settings → Updates.
  • Admin overview gets an Updates card: what is running, what is out (with a link to the release), when it last checked, a Check now button, and Update to X when there is something to install. Failed checks and failed installs are shown there, not just logged.
  • tsbb update [--check] does the same from a shell, for a stopped board or an operator who wants to watch.
  • Containers are never touched. The Docker image has no .git, so the panel shows the notice and says to redeploy. tsbb.dev and bbs.hqtui.com both run from the image, so nothing changes for them beyond the card.

Safety

  • Refuses a checkout with local changes rather than overwriting them.
  • Only acts on tags of the form vX.Y.Z; the tag is fetched by exact ref.
  • A failed pnpm install restores the previous checkout.
  • TSBB_UPDATES=off stops the check as well as the apply, for anyone who does not want the board phoning GitHub.

Restart

The process spawns a fresh copy of itself with the same command line and environment, then exits, so pnpm start in a terminal, nohup or tmux carries on with the new code. Under systemd, pm2 or anything that restarts on exit, set TSBB_RESTART=exit and Restart=always. Smoke-tested by hand: generation one announced the restart, generation two came up on the same port and answered /healthz with 200.

Tests

test/updates.test.ts: version ordering, tag validation, the check recording state for the panel (newer, equal, none, failed), the refusals, the exact command sequence of an apply with git and pnpm injected, the rollback on install failure, and the admin card and setting through the real app. 183 pass, 0 fail.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PY5Y9gpnQ9kevUFwXJakyn

Every self-hosted board has to be updated by hand — git fetch, checkout the
tag, pnpm install, restart — and a board nobody types that for drifts a
version further behind with each release. Now the board does it itself.

A minute after boot and every five minutes after that, the server asks
GitHub for the newest release. When one is newer than the running version
and the board runs from a git checkout, it fetches the tag, checks it out,
runs the install, and restarts itself. It is on by default; an
administrator turns it off under Board settings → Updates, and the overview
page always shows what is running, what is out, a Check now button, and an
Update now button when there is something to install.

What it refuses, deliberately:

- A checkout with local changes. That is somebody's work, and an update
  that discarded it would be the worst thing this code could do.
- A container. The image is built from a tree with no .git, so there is
  nothing to fetch into; the panel shows the new version and says to
  redeploy. Both house boards run this way, so they are unaffected.
- Anything that is not a release tag of the form vX.Y.Z.

An install that fails puts the previous checkout back, and every check and
apply records its outcome in settings, so a failure shows on the overview
where the button was rather than only in a log.

The restart spawns a fresh copy of the process with the same command line
and environment and then exits, so `pnpm start` in a terminal, nohup or
tmux carries on with the new code. Under a supervisor that restarts on
exit, TSBB_RESTART=exit skips the spawn. TSBB_UPDATES=off stops the check
as well as the apply. `tsbb update [--check]` does the same from a shell.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PY5Y9gpnQ9kevUFwXJakyn
@ralyodio
ralyodio merged commit ad37c80 into main Sep 3, 2026
3 checks passed
@ralyodio ralyodio mentioned this pull request Sep 3, 2026
ralyodio added a commit that referenced this pull request Sep 3, 2026
Boards now keep themselves current from GitHub releases (#11).


Claude-Session: https://claude.ai/code/session_01PY5Y9gpnQ9kevUFwXJakyn

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
ralyodio added a commit that referenced this pull request Sep 3, 2026
… volume (#13)

* Release 0.4.0

Boards now keep themselves current from GitHub releases (#11).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PY5Y9gpnQ9kevUFwXJakyn

* Let a container keep itself current by running from a checkout on its volume

The self-updater shipped in 0.4.0 can move a git checkout but not an image,
so a board on Railway — including bbs.hqtui.com — only ever saw the "new
version available" notice. This gives the image a way to be updated from
the inside.

With TSBB_CHECKOUT_DIR pointing into a volume, the container clones the
repository there on first boot, at the image's own commit, and installs its
dependencies from the image's pnpm store, so the first start takes about
three seconds and needs no download. It then runs the server from that
checkout in a loop: the updater fetches each release into the volume and
exits, and the loop starts the new code. A container restart comes back on
the release it had rather than the image it was built from, because the
checkout is on the volume.

Without TSBB_CHECKOUT_DIR the entrypoint runs the image's own code exactly
as before, so tsbb.dev is unchanged.

Copying the image's node_modules into the checkout instead of installing
does not work — pnpm sees a tree made for another path and stops to ask
whether it may rebuild it, and there is no TTY to say yes. Linking from the
store is what the install already does, and it is as fast.

Tried for real in Docker: a container seeded at the commit before the 0.4.0
bump found v0.4.0 a minute after boot, fetched, checked out, installed in
one second, restarted, and answered the healthcheck on the new commit. A
restart of that container came back on 0.4.0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PY5Y9gpnQ9kevUFwXJakyn

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@ralyodio
ralyodio deleted the autoupdate branch September 3, 2026 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant