[OCaml] High Intensity Training Online
build Add push-to-deploy pipeline scripts
Bare-repo post-receive hook plus root setup, layout-fix, and reset scripts. The hook builds and tests a timestamped release on a shared opam switch, flips a current symlink, restarts via scoped sudo, health-checks the app, rolls back on failure, and records deploy metadata.
Changed files
deploy/fix-layout-root.sh
@@ -0,0 +1,119 @@
1
Added:
#!/usr/bin/env bash
2
Added:
# Corrective root script for the hito deploy layout.
3
Added:
#
4
Added:
# A manual seed nested shared/ and releases/ INSIDE the live release, so the
5
Added:
# unit's /srv/hito/shared/hito.sqlite path vanished and SQLite could not open
6
Added:
# the DB. This restores the intended sibling layout:
7
Added:
#
8
Added:
# /srv/hito/shared/{hito.sqlite,_opam} (never inside a release)
9
Added:
# /srv/hito/releases/<ts>/ (the app tree)
10
Added:
# /srv/hito/current -> releases/<ts>
11
Added:
#
12
Added:
# Run as root: sudo bash fix-layout-root.sh
13
Added:
# Idempotent and conservative: it moves, never deletes, the database.
14
Added:
set -euo pipefail
15
Added:
16
Added:
SRV=/srv/hito
17
Added:
DEPLOY_USER=mpeter
18
Added:
DEPLOY_GROUP=git
19
Added:
20
Added:
# The release that is currently live (resolve the symlink, strip trailing /).
21
Added:
LIVE=$(readlink -f "$SRV/current")
22
Added:
echo "live release: $LIVE"
23
Added:
[ -d "$LIVE" ] || { echo "current does not resolve to a directory"; exit 1; }
24
Added:
25
Added:
echo "== 1. restore top-level shared/ =="
26
Added:
mkdir -p "$SRV/shared"
27
Added:
# Move the DB back to the top-level shared dir if it drifted into the release.
28
Added:
if [ -f "$LIVE/shared/hito.sqlite" ] && [ ! -e "$SRV/shared/hito.sqlite" ]; then
29
Added:
mv "$LIVE/shared/hito.sqlite" "$SRV/shared/hito.sqlite"
30
Added:
echo " moved DB -> $SRV/shared/hito.sqlite"
31
Added:
fi
32
Added:
# Move the shared opam switch back up if it drifted into the release.
33
Added:
if [ -d "$LIVE/shared/_opam" ] && [ ! -e "$SRV/shared/_opam" ]; then
34
Added:
mv "$LIVE/shared/_opam" "$SRV/shared/_opam"
35
Added:
echo " moved shared switch -> $SRV/shared/_opam"
36
Added:
fi
37
Added:
38
Added:
echo "== 2. relocate the live release under releases/ =="
39
Added:
mkdir -p "$SRV/releases"
40
Added:
# Drop the nested shared/ and releases/ that the manual seed pulled in.
41
Added:
rm -rf "$LIVE/shared" "$LIVE/releases"
42
Added:
base=$(basename "$LIVE")
43
Added:
if [ "$(dirname "$LIVE")" != "$SRV/releases" ]; then
44
Added:
mv "$LIVE" "$SRV/releases/$base"
45
Added:
LIVE="$SRV/releases/$base"
46
Added:
echo " moved release -> $LIVE"
47
Added:
fi
48
Added:
49
Added:
echo "== 3. ownership and current symlink =="
50
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/shared" "$SRV/releases"
51
Added:
ln -sfn "$LIVE" "$SRV/current.tmp"
52
Added:
mv -T "$SRV/current.tmp" "$SRV/current"
53
Added:
chown -h "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/current"
54
Added:
echo " current -> $LIVE"
55
Added:
56
Added:
echo "== 4. wire DB into the release and reinstall the corrected hook =="
57
Added:
ln -sfn "$SRV/shared/hito.sqlite" "$LIVE/hito.sqlite"
58
Added:
install -o "$DEPLOY_USER" -g "$DEPLOY_GROUP" -m 0755 \
59
Added:
"$(dirname "$0")/post-receive" /srv/git/hito.git/hooks/post-receive
60
Added:
61
Added:
echo "== 5. remove the obsolete top-level working clone =="
62
Added:
# /srv/hito must contain only shared/, releases/, and current. A pre-pipeline
63
Added:
# in-place clone still lives at the top level and makes dune see the hito
64
Added:
# package twice (top-level dune-project AND current/dune-project). Its content
65
Added:
# is fully preserved in the bare repo and in every release, and the only unique
66
Added:
# runtime state (the DB) is already in shared/. Remove ONLY known clone
67
Added:
# entries; never touch shared/, releases/, or current.
68
Added:
for entry in ARCHITECTURE.org RAIL.org REQUESTS.org bin lib test site \
69
Added:
dune dune-project hito.opam hito.sqlite LICENSE \
70
Added:
_build .git .gitignore .ocamlformat .envrc .cache .kiro; do
71
Added:
target="$SRV/$entry"
72
Added:
if [ -e "$target" ] || [ -L "$target" ]; then
73
Added:
rm -rf "$target"
74
Added:
echo " removed $target"
75
Added:
fi
76
Added:
done
77
Added:
# Guard: the three managed entries must survive.
78
Added:
for keep in shared releases current; do
79
Added:
[ -e "$SRV/$keep" ] || { echo "FATAL: $SRV/$keep missing after cleanup"; exit 1; }
80
Added:
done
81
Added:
82
Added:
echo "== 6. deploy master as a fresh release, built on the shared switch =="
83
Added:
# Build in a staging dir OUTSIDE /srv/hito so dune's upward project-root search
84
Added:
# never sees the current symlink or any sibling release (which would make the
85
Added:
# hito package appear twice). Move the built tree into releases/ only after a
86
Added:
# clean build, then flip current.
87
Added:
NEW_TS=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
88
Added:
NEW_REL="$SRV/releases/$NEW_TS"
89
Added:
STAGE=$(sudo -u "$DEPLOY_USER" mktemp -d "/tmp/hito-stage.XXXXXX")
90
Added:
sha=$(git --git-dir=/srv/git/hito.git rev-parse refs/heads/master)
91
Added:
git --git-dir=/srv/git/hito.git archive "$sha" | tar -x -C "$STAGE"
92
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$STAGE"
93
Added:
sudo -u "$DEPLOY_USER" -H bash -lc "
94
Added:
set -euo pipefail
95
Added:
export OPAMROOT=/home/$DEPLOY_USER/.opam
96
Added:
cd '$STAGE'
97
Added:
eval \"\$(opam env --switch='$SRV/shared' --set-switch)\"
98
Added:
opam install . --deps-only --with-test -y
99
Added:
dune build @check
100
Added:
dune runtest
101
Added:
dune build
102
Added:
"
103
Added:
# Publish the built tree as the new release.
104
Added:
mkdir -p "$SRV/releases"
105
Added:
mv "$STAGE" "$NEW_REL"
106
Added:
ln -sfn "$SRV/shared/hito.sqlite" "$NEW_REL/hito.sqlite"
107
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$NEW_REL"
108
Added:
ln -sfn "$NEW_REL" "$SRV/current.tmp"
109
Added:
mv -T "$SRV/current.tmp" "$SRV/current"
110
Added:
chown -h "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/current"
111
Added:
echo " current -> $NEW_REL (master ${sha:0:12})"
112
Added:
113
Added:
echo "== 7. restart =="
114
Added:
systemctl restart hito
115
Added:
sleep 1
116
Added:
systemctl is-active hito && echo "hito is active" || {
117
Added:
echo "still failing; recent journal:"; journalctl -u hito -n 15 --no-pager; exit 1;
118
Added:
}
119
Added:
echo "Done. /srv/hito holds shared/, releases/, current; live release is master."
deploy/post-receive
@@ -0,0 +1,133 @@
1
Added:
#!/usr/bin/env bash
2
Added:
# hito post-receive hook. Runs on the VPS after every push.
3
Added:
#
4
Added:
# For a push to master: check out the pushed revision into a fresh timestamped
5
Added:
# release, build and test it against the shared opam switch, flip
6
Added:
# /srv/hito/current, restart the service, and confirm it answers HTTP. Any
7
Added:
# build/test failure leaves the live release untouched and fails the push. A
8
Added:
# failed health check rolls current back to the previous release and restarts.
9
Added:
set -euo pipefail
10
Added:
11
Added:
DEPLOY_BRANCH=master
12
Added:
SRV=/srv/hito
13
Added:
BARE=/srv/git/hito.git
14
Added:
SHARED="$SRV/shared"
15
Added:
RELEASES="$SRV/releases"
16
Added:
KEEP=5
17
Added:
HEALTH_URL="http://127.0.0.1:8080/login"
18
Added:
HEALTH_TRIES=10
19
Added:
HEALTH_DELAY=1
20
Added:
export OPAMROOT=/home/mpeter/.opam
21
Added:
export OPAMSWITCH="$SHARED"
22
Added:
23
Added:
log() { printf ' hito-deploy: %s\n' "$*" >&2; }
24
Added:
fail() { log "FAILED: $*"; exit 1; }
25
Added:
26
Added:
# Poll the app until it answers, or report failure after HEALTH_TRIES.
27
Added:
health_ok() {
28
Added:
local i
29
Added:
for i in $(seq 1 "$HEALTH_TRIES"); do
30
Added:
if curl -sf -o /dev/null --max-time 3 "$HEALTH_URL"; then
31
Added:
return 0
32
Added:
fi
33
Added:
sleep "$HEALTH_DELAY"
34
Added:
done
35
Added:
return 1
36
Added:
}
37
Added:
38
Added:
while read -r _old new ref; do
39
Added:
if [ "$ref" != "refs/heads/$DEPLOY_BRANCH" ]; then
40
Added:
log "skipping $ref (only $DEPLOY_BRANCH deploys)"
41
Added:
continue
42
Added:
fi
43
Added:
44
Added:
start=$SECONDS
45
Added:
ts=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
46
Added:
rel="$RELEASES/$ts"
47
Added:
buildlog="$rel/deploy.log"
48
Added:
prev=$(readlink -f "$SRV/current" 2>/dev/null || true)
49
Added:
log "deploying ${new:0:12} to $rel"
50
Added:
mkdir -p "$rel"
51
Added:
52
Added:
# Materialize the pushed revision from the bare repo. Use git archive so the
53
Added:
# release contains exactly the tracked tree and never a stray shared/ or
54
Added:
# releases/ directory. shared/ and releases/ are strict siblings of a release
55
Added:
# and must never appear inside one.
56
Added:
if ! git --git-dir="$BARE" archive "$new" | tar -x -C "$rel"; then
57
Added:
rm -rf "$rel"; fail "checkout"
58
Added:
fi
59
Added:
60
Added:
# Build and test against the shared switch. The full build log is kept inside
61
Added:
# the release ($buildlog) so a successful deploy leaves a record, not only a
62
Added:
# failed one. Install missing deps only when hito.opam changed.
63
Added:
eval "$(opam env --switch="$SHARED" --set-switch)"
64
Added:
cd "$rel"
65
Added:
66
Added:
log "syncing dependencies"
67
Added:
opam install . --deps-only --with-test -y >"$buildlog" 2>&1 \
68
Added:
|| { tail -30 "$buildlog" >&2; rm -rf "$rel"; fail "opam deps"; }
69
Added:
70
Added:
log "dune build @check"
71
Added:
dune build @check >>"$buildlog" 2>&1 \
72
Added:
|| { tail -40 "$buildlog" >&2; rm -rf "$rel"; fail "@check"; }
73
Added:
74
Added:
log "dune runtest"
75
Added:
dune runtest >>"$buildlog" 2>&1 \
76
Added:
|| { tail -40 "$buildlog" >&2; rm -rf "$rel"; fail "tests"; }
77
Added:
78
Added:
log "dune build (release)"
79
Added:
dune build >>"$buildlog" 2>&1 \
80
Added:
|| { tail -40 "$buildlog" >&2; rm -rf "$rel"; fail "build"; }
81
Added:
82
Added:
build_secs=$((SECONDS - start))
83
Added:
84
Added:
# Wire the shared database into this release.
85
Added:
ln -sfn "$SHARED/hito.sqlite" "$rel/hito.sqlite"
86
Added:
87
Added:
# Record deploy metadata: in the release for provenance, and appended to a
88
Added:
# durable log under shared/ so the deploy history outlives pruned releases.
89
Added:
subject=$(git --git-dir="$BARE" log -1 --format=%s "$new")
90
Added:
cat >"$rel/deploy-info.json" <<JSON
91
Added:
{
92
Added:
"commit": "$new",
93
Added:
"subject": $(printf '%s' "$subject" | sed 's/\\/\\\\/g; s/"/\\"/g; s/.*/"&"/'),
94
Added:
"branch": "$DEPLOY_BRANCH",
95
Added:
"deployed_at": "$ts",
96
Added:
"build_seconds": $build_secs,
97
Added:
"release": "$rel"
98
Added:
}
99
Added:
JSON
100
Added:
printf '%s\t%s\t%ss\t%s\t%s\n' \
101
Added:
"$ts" "${new:0:12}" "$build_secs" "$DEPLOY_BRANCH" "$subject" \
102
Added:
>>"$SHARED/deploy-history.tsv"
103
Added:
104
Added:
# Atomic flip: swap the symlink in one rename so no request sees a half state.
105
Added:
ln -sfn "$rel" "$SRV/current.tmp"
106
Added:
mv -T "$SRV/current.tmp" "$SRV/current"
107
Added:
log "current -> $rel"
108
Added:
109
Added:
# Restart via the single scoped sudoers rule.
110
Added:
sudo -n systemctl restart hito || fail "restart"
111
Added:
112
Added:
# Health check. systemd reports active as soon as the process starts, so poll
113
Added:
# the app itself. On failure, roll current back to the previous release and
114
Added:
# restart, so a broken build never stays live.
115
Added:
if health_ok; then
116
Added:
log "healthy: $HEALTH_URL"
117
Added:
elif [ -n "$prev" ] && [ -d "$prev" ]; then
118
Added:
log "health check failed; rolling back to $prev"
119
Added:
ln -sfn "$prev" "$SRV/current.tmp"
120
Added:
mv -T "$SRV/current.tmp" "$SRV/current"
121
Added:
sudo -n systemctl restart hito || true
122
Added:
fail "health check (rolled back to previous release)"
123
Added:
else
124
Added:
fail "health check (no previous release to roll back to)"
125
Added:
fi
126
Added:
127
Added:
log "deployed ${new:0:12} in ${build_secs}s"
128
Added:
129
Added:
# Prune all but the most recent $KEEP releases.
130
Added:
ls -1dt "$RELEASES"/*/ 2>/dev/null | tail -n +$((KEEP + 1)) \
131
Added:
| xargs -r rm -rf
132
Added:
log "done"
133
Added:
done
deploy/reset-srv-hito-root.sh
@@ -0,0 +1,114 @@
1
Added:
#!/usr/bin/env bash
2
Added:
# Full reset of /srv/hito to the clean release layout.
3
Added:
#
4
Added:
# Wipes everything under /srv/hito EXCEPT the database and the shared opam
5
Added:
# switch, which are preserved (the DB is the only unique runtime state; the
6
Added:
# switch is expensive to rebuild). Result:
7
Added:
#
8
Added:
# /srv/hito/shared/{hito.sqlite,_opam}
9
Added:
# /srv/hito/releases/<ts>/ (master, freshly built)
10
Added:
# /srv/hito/current -> releases/<ts>
11
Added:
#
12
Added:
# Run as root: sudo bash reset-srv-hito-root.sh
13
Added:
set -euo pipefail
14
Added:
15
Added:
SRV=/srv/hito
16
Added:
DEPLOY_USER=mpeter
17
Added:
DEPLOY_GROUP=git
18
Added:
BARE=/srv/git/hito.git
19
Added:
DB="$SRV/shared/hito.sqlite"
20
Added:
SWITCH="$SRV/shared/_opam"
21
Added:
22
Added:
[ -f "$DB" ] || { echo "FATAL: database not found at $DB; aborting before any wipe"; exit 1; }
23
Added:
24
Added:
echo "== 1. stop the service =="
25
Added:
systemctl stop hito || true
26
Added:
27
Added:
echo "== 2. back up and set aside the database and shared switch =="
28
Added:
STASH=$(mktemp -d /root/hito-reset-stash.XXXXXX)
29
Added:
cp -a "$DB" "$STASH/hito.sqlite" # safety copy
30
Added:
echo " DB backed up to $STASH/hito.sqlite"
31
Added:
mv "$DB" "$STASH/hito.sqlite.live"
32
Added:
[ -d "$SWITCH" ] && mv "$SWITCH" "$STASH/_opam" && echo " switch set aside"
33
Added:
34
Added:
echo "== 3. wipe everything under /srv/hito (contents only, keep the dir) =="
35
Added:
# Remove all entries, including dotfiles, without following into the stash.
36
Added:
find "$SRV" -mindepth 1 -maxdepth 1 -exec rm -rf {} +
37
Added:
echo " /srv/hito emptied"
38
Added:
39
Added:
echo "== 4. rebuild the clean skeleton =="
40
Added:
mkdir -p "$SRV/shared" "$SRV/releases"
41
Added:
mv "$STASH/hito.sqlite.live" "$DB"
42
Added:
[ -d "$STASH/_opam" ] && mv "$STASH/_opam" "$SWITCH"
43
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/shared" "$SRV/releases"
44
Added:
echo " restored shared/ (DB + switch) and empty releases/"
45
Added:
46
Added:
echo "== 5. deploy master as the first clean release =="
47
Added:
# Build in a staging dir OUTSIDE /srv/hito so dune's project-root search never
48
Added:
# sees current or a sibling release. Publish only after a clean build.
49
Added:
start=$SECONDS
50
Added:
TS=$(date -u +"%Y-%m-%dT%H-%M-%SZ")
51
Added:
REL="$SRV/releases/$TS"
52
Added:
STAGE=$(sudo -u "$DEPLOY_USER" mktemp -d /tmp/hito-stage.XXXXXX)
53
Added:
sha=$(git --git-dir="$BARE" rev-parse refs/heads/master)
54
Added:
git --git-dir="$BARE" archive "$sha" | tar -x -C "$STAGE"
55
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$STAGE"
56
Added:
sudo -u "$DEPLOY_USER" -H bash -lc "
57
Added:
set -euo pipefail
58
Added:
export OPAMROOT=/home/$DEPLOY_USER/.opam
59
Added:
cd '$STAGE'
60
Added:
eval \"\$(opam env --switch='$SRV/shared' --set-switch)\"
61
Added:
opam install . --deps-only --with-test -y 2>&1 | tee deploy.log
62
Added:
dune build @check 2>&1 | tee -a deploy.log
63
Added:
dune runtest 2>&1 | tee -a deploy.log
64
Added:
dune build 2>&1 | tee -a deploy.log
65
Added:
"
66
Added:
build_secs=$((SECONDS - start))
67
Added:
mv "$STAGE" "$REL"
68
Added:
ln -sfn "$SRV/shared/hito.sqlite" "$REL/hito.sqlite"
69
Added:
70
Added:
# Deploy metadata, matching the hook: provenance in the release and a durable
71
Added:
# history line under shared/.
72
Added:
subject=$(git --git-dir="$BARE" log -1 --format=%s "$sha")
73
Added:
cat >"$REL/deploy-info.json" <<JSON
74
Added:
{
75
Added:
"commit": "$sha",
76
Added:
"subject": $(printf '%s' "$subject" | sed 's/\\/\\\\/g; s/"/\\"/g; s/.*/"&"/'),
77
Added:
"branch": "master",
78
Added:
"deployed_at": "$TS",
79
Added:
"build_seconds": $build_secs,
80
Added:
"release": "$REL"
81
Added:
}
82
Added:
JSON
83
Added:
printf '%s\t%s\t%ss\t%s\t%s\n' \
84
Added:
"$TS" "${sha:0:12}" "$build_secs" "master" "$subject" \
85
Added:
>>"$SRV/shared/deploy-history.tsv"
86
Added:
87
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$REL"
88
Added:
chown "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/shared/deploy-history.tsv"
89
Added:
ln -sfn "$REL" "$SRV/current.tmp"
90
Added:
mv -T "$SRV/current.tmp" "$SRV/current"
91
Added:
chown -h "$DEPLOY_USER:$DEPLOY_GROUP" "$SRV/current"
92
Added:
echo " current -> $REL (master ${sha:0:12}, built in ${build_secs}s)"
93
Added:
94
Added:
echo "== 6. start the service and health-check =="
95
Added:
systemctl start hito
96
Added:
HEALTH_URL="http://127.0.0.1:8080/login"
97
Added:
healthy=false
98
Added:
for _ in $(seq 1 10); do
99
Added:
if curl -sf -o /dev/null --max-time 3 "$HEALTH_URL"; then healthy=true; break; fi
100
Added:
sleep 1
101
Added:
done
102
Added:
if $healthy; then
103
Added:
echo " hito is healthy at $HEALTH_URL"
104
Added:
else
105
Added:
echo " FAILED health check; recent journal:"
106
Added:
journalctl -u hito -n 15 --no-pager
107
Added:
exit 1
108
Added:
fi
109
Added:
110
Added:
echo
111
Added:
echo "Done. /srv/hito now holds only shared/, releases/, current."
112
Added:
echo "Safety backup of the DB remains at $STASH/hito.sqlite"
113
Added:
echo "Remove it once you have confirmed the app works: rm -rf $STASH"
114
Added:
ls -la "$SRV"
deploy/setup-root.sh
@@ -0,0 +1,69 @@
1
Added:
#!/usr/bin/env bash
2
Added:
# One-time root setup for the hito push-to-deploy pipeline on the VPS.
3
Added:
# Run as root: sudo bash setup-root.sh
4
Added:
#
5
Added:
# Idempotent: safe to re-run. It does not touch the live release or the
6
Added:
# database beyond moving the DB once into the shared directory.
7
Added:
set -euo pipefail
8
Added:
9
Added:
DEPLOY_USER=mpeter
10
Added:
DEPLOY_GROUP=git
11
Added:
SRV=/srv/hito
12
Added:
BARE=/srv/git/hito.git
13
Added:
UNIT=/etc/systemd/system/hito.service
14
Added:
SUDOERS=/etc/sudoers.d/hito-deploy
15
Added:
SHARED="$SRV/shared"
16
Added:
RELEASES="$SRV/releases"
17
Added:
18
Added:
echo "== 1. release and shared directories =="
19
Added:
mkdir -p "$RELEASES" "$SHARED"
20
Added:
# Move the live database under shared/ exactly once. The unit is edited below
21
Added:
# to read it from there, so a new release never orphans the data.
22
Added:
if [ -f "$SRV/hito.sqlite" ] && [ ! -e "$SHARED/hito.sqlite" ]; then
23
Added:
mv "$SRV/hito.sqlite" "$SHARED/hito.sqlite"
24
Added:
echo " moved hito.sqlite -> $SHARED/hito.sqlite"
25
Added:
fi
26
Added:
chown -R "$DEPLOY_USER:$DEPLOY_GROUP" "$RELEASES" "$SHARED"
27
Added:
28
Added:
echo "== 2. shared opam switch (matches existing 5.5.0) =="
29
Added:
# Built once as the deploy user, reused by every release unless hito.opam
30
Added:
# changes. Kept outside releases so pruning a release never deletes it.
31
Added:
if [ ! -d "$SHARED/_opam" ]; then
32
Added:
sudo -u "$DEPLOY_USER" -H bash -lc "
33
Added:
export OPAMROOT=/home/$DEPLOY_USER/.opam
34
Added:
opam switch create '$SHARED' ocaml-base-compiler.5.5.0 --no-install -y
35
Added:
"
36
Added:
echo " created shared switch at $SHARED/_opam"
37
Added:
else
38
Added:
echo " shared switch already present"
39
Added:
fi
40
Added:
41
Added:
echo "== 3. post-receive hook =="
42
Added:
install -o "$DEPLOY_USER" -g "$DEPLOY_GROUP" -m 0755 \
43
Added:
"$(dirname "$0")/post-receive" "$BARE/hooks/post-receive"
44
Added:
echo " installed $BARE/hooks/post-receive"
45
Added:
46
Added:
echo "== 4. scoped sudoers for restart =="
47
Added:
cat > "$SUDOERS" <<SUDO
48
Added:
$DEPLOY_USER ALL=(root) NOPASSWD: /usr/bin/systemctl restart hito
49
Added:
SUDO
50
Added:
chmod 0440 "$SUDOERS"
51
Added:
visudo -c -f "$SUDOERS"
52
Added:
53
Added:
echo "== 5. systemd unit -> current/ =="
54
Added:
# Point ExecStart and WorkingDirectory at the current symlink, read the DB
55
Added:
# from shared/, and keep the existing hardening (ReadWritePaths already /srv/hito).
56
Added:
cp -a "$UNIT" "$UNIT.bak.$(date +%s)"
57
Added:
sed -i \
58
Added:
-e 's#^ExecStart=.*#ExecStart=/srv/hito/current/_build/default/bin/main.exe#' \
59
Added:
-e 's#^WorkingDirectory=.*#WorkingDirectory=/srv/hito/current#' \
60
Added:
-e 's#^Environment=HITO_DB=.*#Environment=HITO_DB=sqlite3:/srv/hito/shared/hito.sqlite#' \
61
Added:
"$UNIT"
62
Added:
systemctl daemon-reload
63
Added:
echo " unit updated (backup kept alongside)."
64
Added:
65
Added:
echo
66
Added:
echo "Done. The service still runs the old in-place build until the first"
67
Added:
echo "successful push flips /srv/hito/current. To go live now without a push:"
68
Added:
echo " 1) su - $DEPLOY_USER and run deploy/first-release.sh (creates current/)"
69
Added:
echo " 2) sudo systemctl restart hito"