There were two near-identical update scripts and they drifted: the npm ci fix
from 1.114.1 only ever landed in update-app.sh, so the boot path kept running
npm install. my-weekly-todo-update.service now runs update-app.sh, and
boot-update.sh is a shim kept only so a not-yet-recopied unit still works.
To be usable at boot the script needed three things it did not have:
- Skip the rebuild when HEAD already matches origin/main and a standalone
build exists, so a reboot is not a full rebuild every time (--force
overrides).
- Do not restart PM2 when its daemon is not up yet. At boot this unit runs
before pm2-root.service, and probing with `pm2 describe` would spawn a
stray daemon that races the real service, so it checks the pid file.
- A flock single-instance lock, so a boot run and a manual run cannot install
into the same tree at once.
It also picks up prisma migrate deploy / generate and the .env copy that only
the boot script had. The log moved to /var/log/my-weekly-todo-update.log.
v1.115.2
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The "update on reboot" unit silently did nothing useful. boot-update.sh piped
every command into tee, so `set -e` only saw tee's exit status: a failed
npm install or build left a half-built tree and still logged "Boot update
finished". It also used npm install (rewrites package-lock.json, so the next
git pull aborts), had no GIT_TERMINAL_PROMPT=0, and was not wrapped in a
function even though git pull rewrites it mid-run.
The unit's TimeoutStartSec=300 was the other half: npm ci + prisma generate +
next build takes far longer than 5 minutes in the container, so systemd
SIGTERMed the oneshot mid-install and left a node_modules tree npm could no
longer remove (ENOTEMPTY on rmdir node_modules/date-fns/isEqual).
Also resyncs package-lock.json with package.json, missed in the 1.115.0 commit.
v1.115.1
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>