# Deploying hsa-app The app runs as a **user systemd service** (no sudo). Deployment is driven by git tags: - **Release tags `X.Y.Z`** (e.g. `1.2.0`) — CI builds + tests, stages the binary into `~/hsa-app/releases/hsa-app-V/hsa`, then **activates** it: points the `~/hsa-app/hsa` symlink at that release and restarts the service. - **Pre-release tags** (anything else, e.g. `0.0.0a2`) — built, tested, and staged into `releases/`, but **not** activated. Nothing goes live. The symlink decouples "what's on disk" from "what's running," so activating a staged pre-release or rolling back is just a symlink repoint + restart (see below). ## Layout on the host Mutable state (DB, env, config) lives at the top of `~/hsa-app/` and survives every deploy. Only the binaries live under `releases/`. ``` ~/hsa-app/ hsa_app.sh # launcher: sources env file, exec's the binary hsa_app.env # environment (KEY=VALUE) config.json hsa.db, hsa.db-shm, hsa.db-wal # SQLite state releases/ hsa-app-V0.0.0a0/hsa hsa-app-V0.0.1/hsa hsa -> releases/hsa-app-V0.0.1/hsa # current symlink, swapped on deploy ``` ## The current symlink Create/repoint it **from inside `~/hsa-app`** so the relative target resolves against the link's own directory (running `ln -s` from `~` produces a broken link that points at `~/hsa-app/hsa-app/...`): ```bash cd ~/hsa-app chmod +x releases/hsa-app-V/hsa ln -sfn releases/hsa-app-V/hsa hsa # -f replace, -n don't follow existing link ls -l hsa # target must resolve (not broken) ``` This same `ln -sfn` + `chmod +x` is what the CI deploy step runs on each tag. ## Install the service (once) Save [hsa_app.service](hsa_app.service) to `~/.config/systemd/user/hsa_app.service`, then: ```bash loginctl enable-linger "$USER" # run the service without an active login session systemctl --user daemon-reload systemctl --user enable --now hsa_app systemctl --user status hsa_app journalctl --user -u hsa_app -f # follow logs ``` ### Why these choices - **User service** (`systemctl --user`) — no sudo, matches the home-dir deploy. `enable-linger` lets it start at boot / stay up without an interactive login. - **`Type=exec`** — `hsa_app.sh` ends in `exec "$BIN"`, so the binary becomes the unit's main process; signals and exit codes propagate correctly. - **`WorkingDirectory=%h/hsa-app`** — relative paths in the env file resolve here. The launcher's comment recommends absolute paths for `DB_PATH` / `STORAGE_DIR` / `BACKUP_DIR` / `CONFIG_PATH`; either works. - **ExecStart passes the env file as `$1`** — matches `hsa_app.sh`'s first-arg precedence, so no `/etc/hsa-app/...` file is needed. `%h` expands to the home dir. - The launcher defaults its binary to `./hsa` next to itself (`~/hsa-app/hsa`, the symlink), so a restart after a symlink swap runs the new release automatically. ## Deploy a tagged release Push a release tag `X.Y.Z` — CI builds, stages, and activates it automatically. To manually activate a staged pre-release (or any release) from the host: ```bash cd ~/hsa-app chmod +x releases/hsa-app-V/hsa ln -sfn releases/hsa-app-V/hsa hsa systemctl --user restart hsa_app ``` ## Roll back Every release stays under `releases/`, so rollback is a symlink repoint: ```bash cd ~/hsa-app ln -sfn releases/hsa-app-V/hsa hsa systemctl --user restart hsa_app ```