Skip to content

Releases: RootX22/deploy-forge

v1.1.0 — manual rollback + nginx/systemd examples

Choose a tag to compare

@RootX22 RootX22 released this 23 Aug 21:36

scripts/rollback.sh

deploy.sh already rolls back when a health check fails. This is for the other case: the deploy passed, and the problem surfaced ten minutes later.

APP_ROOT=/var/www/myapp ./rollback.sh --list
APP_ROOT=/var/www/myapp ./rollback.sh --dry-run
APP_ROOT=/var/www/myapp ./rollback.sh
APP_ROOT=/var/www/myapp ./rollback.sh --to 20260823T161500Z

It walks backwards from the live release rather than taking the second-newest, so rolling back twice in a row goes where you expect — taking [-2] would bounce you back to the broken release. Nothing is deleted, so rolling forward is just another rollback in the other direction.

If the rollback target is also unhealthy it reports and stops. Swapping again automatically would just flap between two broken releases.

examples/

  • nginx.conf — documents the two details that actually bite: disable_symlinks off, or nginx caches the resolved path and keeps serving the old release after a swap; and $realpath_root for SCRIPT_FILENAME, or PHP-FPM's OPcache keys every release to one shared entry and a deploy serves a mix of old and new bytecode.
  • deploy.service + myapp.env — systemd oneshot unit, for when the deploy user shouldn't have a login shell.

CI

Adds a rollback test job: dry-run inertness, sequential rollback, --to roll-forward, and rejection of an unknown release.

v1.0.0

Choose a tag to compare

@RootX22 RootX22 released this 23 Aug 21:36

First release.

Release-directory deployment with an atomic rename(2) symlink swap, health-checked with automatic rollback, plus a preflight that catches the failures that strand a deploy halfway.

Includes a reusable GitHub Actions workflow with deploy concurrency gating, and a multi-stage PHP-FPM Dockerfile that keeps Composer and Node out of the runtime image.

Bugs found and fixed by the test suite before release

  • mv -T is GNU-only, so the swap failed on BSD/macOS — replaced with a portable atomic_symlink().
  • An explicit die after the swap bypassed the ERR trap, so a failed health check left the broken release live — exactly the case rollback exists for.
  • (( pruned++ )) returns exit status 1 on the first increment; under set -e that aborted the script after a fully successful deploy.