fix: make the Hub backup scripts runnable on the Linux host

Found by running deploy/hub/backup.sh on the production VM:

- With core.autocrlf=true, `git archive` on the Windows release machine
  shipped the .sh files with CRLF and `sh` aborted on line 4
  ("set: Illegal option -"): backup, restore and seed never ran.
  .gitattributes now forces *.sh to LF.
- Docker creates the bind-mounted backups/ directory as root, so the
  host-side retention `rm` would fail once the 15th dump existed.
  Retention now runs inside the postgres container.

tests/test_deploy_scripts.py covers both.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
gti
2026-09-23 00:35:20 -03:00
co-authored by Claude Opus 5.5
parent a11209d123
commit b6b45c703b
3 changed files with 33 additions and 1 deletions
+26
View File
@@ -0,0 +1,26 @@
"""The Hub backup/restore scripts must actually run on the Linux host.
Both failures below were found by running the scripts on the production VM,
not by reading them.
"""
from pathlib import Path
ROOT = Path(__file__).parents[1]
HUB = ROOT / "deploy" / "hub"
def test_shell_scripts_are_forced_to_lf():
# With core.autocrlf=true on the Windows release machine, `git archive`
# shipped CRLF and `sh` failed on the first line ("set: Illegal option -").
rules = [line.split() for line in (ROOT / ".gitattributes").read_text(encoding="utf-8").splitlines() if line.strip() and not line.startswith("#")]
assert ["*.sh", "text", "eol=lf"] in rules
for script in HUB.glob("*.sh"):
assert b"\r" not in script.read_bytes(), script.name
def test_backup_retention_does_not_delete_on_the_host():
# Docker creates the bind-mounted backup directory as root, so a host-side
# rm by the deploy user fails once retention kicks in.
lines = [line.strip() for line in (HUB / "backup.sh").read_text(encoding="utf-8").splitlines() if not line.strip().startswith("#")]
retention = [line for line in lines if "rm -f" in line]
assert retention and all(line.startswith("$COMPOSE exec -T postgres") for line in retention)