Gitfed
bastien-mrq/gitfed/ Commits/ e314b9c

Decouple deploy/update.sh from my own VPS; add a pure-redeploy mode

Two real problems this fixes, both found by thinking through Thomas's actual situation as someone who didn't author the release he's deploying: - GITFED_VPS_HOST/GITFED_VPS_SRC_DIR defaulted to my own VPS — anyone else running the script unmodified would silently target my infrastructure (harmlessly failing for lack of SSH access, but confusing and wrong regardless). Now required (hard error if unset), optionally sourced from deploy/update.env (gitignored, one per person/instance) instead of exported by hand every session. - The script only ever knew "bump the version and cut a release" — someone who just wants to redeploy a version they `git pull`ed (not authored) would hit `git commit` with nothing staged and the script would abort via set -e, never reaching the actual build/deploy. `deploy/update.sh current` is the new mode: builds and rolls out whatever VERSION/CHANGELOG.md/deployment.yaml already say, no git writes at all. Also fixed a real bash parser quirk hit while writing this: an apostrophe inside ${VAR:?message} breaks parsing even inside double quotes, unlike plain string interpolation — reworded the one message that had one. Tested both paths against the live instance: `current` mode did a full idempotent redeploy (confirmed no git activity, deployment unchanged, rollout clean); the bump path already covered by every release this session.

bastien-mrq 2026-07-29 12:29 commit e314b9c63996c9432f9ede3c951375524fdd3642 parent 15a0fcacc594fa795836da71565abfe67885d27a
3 files changed +99 −43
M .gitignore +1 −0
M INSTALL.md +21 −3
M deploy/update.sh +77 −40
.gitignore
diff --git a/.gitignore b/.gitignore index 49996a9..8dafdd8 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /demo/ /backups/ *.db +/deploy/update.env
INSTALL.md
diff --git a/INSTALL.md b/INSTALL.md index a86e4e6..787bbe5 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -260,9 +260,27 @@ Si ça fonctionne, l'installation est terminée. de travail** (il pousse le code sur le VPS via `rsync` puis construit là-bas par SSH, il ne dépend donc pas de son architecture) — il te faudra un clone de gitfed en local à ce moment-là, en plus de celui sur - le VPS créé à l'étape 4. Regarde l'en-tête de - [`deploy/update.sh`](deploy/update.sh) pour les variables à adapter - (`GITFED_VPS_HOST`, `GITFED_VPS_SRC_DIR`). + le VPS créé à l'étape 4. + + D'abord, indique-lui où déployer — obligatoire, rien n'est pré-rempli : + + ```sh + export GITFED_VPS_HOST=toi@ton-vps + ``` + + (ou mets cette ligne dans `deploy/update.env`, gitignoré, pour ne pas + avoir à l'exporter à chaque session.) + + Deux façons de l'utiliser ensuite, selon ta situation : + - **Tu modifies le code toi-même** (un fork, tes propres changements) : + `deploy/update.sh` / `deploy/update.sh minor` / `deploy/update.sh + X.Y.Z` — ajoute d'abord une entrée `## X.Y.Z` à `CHANGELOG.md` + décrivant le changement, le script refuse de continuer sans ça. + - **Tu suis juste les mises à jour de quelqu'un d'autre** (tu n'as rien + modifié, tu veux juste la dernière version) : `git pull` pour + récupérer le code, puis `deploy/update.sh current` — construit et + déploie exactement ce que tu viens de récupérer, sans toucher à + `VERSION` ni à git. - **Sauvegardes** : tout ce qui compte vit sur le volume `gitfed-data` (base, clé de CA, clé d'hôte SSH, dépôts). Voir la section « Backups » de [`deploy/k8s/README.md`](deploy/k8s/README.md#backups) pour
deploy/update.sh
diff --git a/deploy/update.sh b/deploy/update.sh index 951f5eb..427064a 100755 --- a/deploy/update.sh +++ b/deploy/update.sh @@ -1,28 +1,51 @@ #!/usr/bin/env bash -# One-command release: bump VERSION, build+import the image on the VPS -# tagged with that version (not just :latest, so `kubectl rollout history` -# and `get pods -o yaml` actually show what's running), point -# deploy/k8s/deployment.yaml at it, apply, and wait for the rollout. +# One-command release/redeploy — works the same whether you're cutting a +# new gitfed release or just redeploying a version someone else already +# released onto your own instance. # -# Usage: -# deploy/update.sh # bump patch (0.3.0 -> 0.3.1) -# deploy/update.sh minor # 0.3.0 -> 0.4.0 -# deploy/update.sh major # 0.3.0 -> 1.0.0 -# deploy/update.sh 0.5.0 # explicit version +# Two modes, same script: # -# Add the new version's entry to CHANGELOG.md yourself before running this -# — the script won't guess what changed. It commits the VERSION bump (and -# CHANGELOG.md, if you've staged it) as "Release vX.Y.Z", and tags the -# final "Deploy vX.Y.Z" commit "vX.Y.Z" — that tag is what makes -# `go install .../gitfed/cmd/<tool>@latest` resolve to something instead -# of erroring "no matching versions" (see FEDERATION.md). Nothing here -# pushes to the remote, including the tag — that's still a separate -# `git push vps main --tags` afterward, same as always. +# deploy/update.sh # bump patch and cut a new release +# deploy/update.sh minor # bump minor, same +# deploy/update.sh major # bump major, same +# deploy/update.sh X.Y.Z # set an explicit version, same +# deploy/update.sh current # build+deploy whatever VERSION already +# # says, no version bump, no git commit, +# # no CHANGELOG check — for redeploying a +# # release you just `git pull`ed rather +# # than authored yourself (see FEDERATION.md +# # / INSTALL.md's "mises à jour" section) +# +# Release mode (patch/minor/major/X.Y.Z): add the new version's entry to +# CHANGELOG.md yourself first — the script won't guess what changed. It +# commits the VERSION bump as "Release vX.Y.Z", and tags the final +# "Deploy vX.Y.Z" commit "vX.Y.Z" (that tag is what makes +# `go install .../gitfed/cmd/<tool>@latest` resolve to something, see +# FEDERATION.md). Nothing here pushes to your remote, including the tag — +# that's a separate `git push <remote> main --tags` afterward. +# +# "current" mode assumes VERSION, CHANGELOG.md and deploy/k8s/deployment.yaml +# are already correct (e.g. you just pulled someone else's release) — +# builds and rolls out without touching git at all. +# +# Where this deploys to is never hardcoded — set it before running: +# +# export GITFED_VPS_HOST=you@your-vps # required +# export GITFED_VPS_SRC_DIR=~/gitfed-src # optional, this is the default +# +# ...or put those two lines in deploy/update.env (gitignored, one per +# person/instance) — sourced automatically if present, so you don't have +# to export them in every shell. set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")/.." -VPS_HOST="${GITFED_VPS_HOST:-ubuntu@51.77.215.92}" +if [ -f deploy/update.env ]; then + # shellcheck source=/dev/null + source deploy/update.env +fi + +: "${GITFED_VPS_HOST:?GITFED_VPS_HOST is not set — export it, or put it in deploy/update.env (see the header comment above)}" VPS_SRC_DIR="${GITFED_VPS_SRC_DIR:-~/gitfed-src}" NAMESPACE="gitfed" @@ -32,46 +55,60 @@ bump_patch() { IFS=. read -r maj min pat <<<"$1"; echo "$maj.$min.$((pat + 1))"; bump_minor() { IFS=. read -r maj min _ <<<"$1"; echo "$maj.$((min + 1)).0"; } bump_major() { IFS=. read -r maj _ _ <<<"$1"; echo "$((maj + 1)).0.0"; } +redeploy_current=0 case "${1:-patch}" in - patch) new_version="$(bump_patch "$current")" ;; - minor) new_version="$(bump_minor "$current")" ;; - major) new_version="$(bump_major "$current")" ;; + current) redeploy_current=1; new_version="$current" ;; + patch) new_version="$(bump_patch "$current")" ;; + minor) new_version="$(bump_minor "$current")" ;; + major) new_version="$(bump_major "$current")" ;; [0-9]*.[0-9]*.[0-9]*) new_version="$1" ;; - *) echo "usage: $0 [patch|minor|major|X.Y.Z]" >&2; exit 1 ;; + *) echo "usage: $0 [patch|minor|major|X.Y.Z|current]" >&2; exit 1 ;; esac -if ! grep -q "^## $new_version\$" CHANGELOG.md; then - echo "error: CHANGELOG.md has no '## $new_version' entry yet — add one first." >&2 - exit 1 -fi +if [ "$redeploy_current" -eq 0 ]; then + if ! grep -q "^## $new_version\$" CHANGELOG.md; then + echo "error: CHANGELOG.md has no '## $new_version' entry yet — add one first." >&2 + exit 1 + fi -echo "==> $current -> $new_version" -echo "$new_version" > VERSION + echo "==> $current -> $new_version" + echo "$new_version" > VERSION -git add VERSION CHANGELOG.md -git commit -m "Release v$new_version" + git add VERSION CHANGELOG.md + git commit -m "Release v$new_version" +else + echo "==> redeploying v$new_version as-is (no version bump, no commit)" +fi -echo "==> syncing source to $VPS_HOST:$VPS_SRC_DIR" +echo "==> syncing source to $GITFED_VPS_HOST:$VPS_SRC_DIR" rsync -az --delete \ --exclude='.git' --exclude='bin' --exclude='demo' --exclude='.claude' --exclude='*.db' \ - ./ "$VPS_HOST:$VPS_SRC_DIR/" + ./ "$GITFED_VPS_HOST:$VPS_SRC_DIR/" echo "==> building gitfed:$new_version on the VPS" -ssh "$VPS_HOST" "cd $VPS_SRC_DIR && docker build -f deploy/docker/Dockerfile -t gitfed:$new_version -t gitfed:latest ." +ssh "$GITFED_VPS_HOST" "cd $VPS_SRC_DIR && docker build -f deploy/docker/Dockerfile -t gitfed:$new_version -t gitfed:latest ." echo "==> importing into k3s containerd" -ssh "$VPS_HOST" "docker save gitfed:$new_version | sudo k3s ctr images import -" +ssh "$GITFED_VPS_HOST" "docker save gitfed:$new_version | sudo k3s ctr images import -" echo "==> pointing deployment.yaml at gitfed:$new_version" sed -i.bak "s|image: gitfed:.*|image: gitfed:$new_version|" deploy/k8s/deployment.yaml rm -f deploy/k8s/deployment.yaml.bak -rsync -az deploy/k8s/deployment.yaml "$VPS_HOST:$VPS_SRC_DIR/deploy/k8s/deployment.yaml" +rsync -az deploy/k8s/deployment.yaml "$GITFED_VPS_HOST:$VPS_SRC_DIR/deploy/k8s/deployment.yaml" echo "==> applying and rolling out" -ssh "$VPS_HOST" "kubectl -n $NAMESPACE apply -f $VPS_SRC_DIR/deploy/k8s/deployment.yaml && kubectl -n $NAMESPACE rollout status deployment/gitfed --timeout=90s" +ssh "$GITFED_VPS_HOST" "kubectl -n $NAMESPACE apply -f $VPS_SRC_DIR/deploy/k8s/deployment.yaml && kubectl -n $NAMESPACE rollout status deployment/gitfed --timeout=90s" -git add deploy/k8s/deployment.yaml -git commit -m "Deploy v$new_version" -git tag "v$new_version" +if [ "$redeploy_current" -eq 1 ]; then + echo "==> done: v$new_version is live" + exit 0 +fi -echo "==> done: v$new_version is live (tagged v$new_version — push with: git push vps main --tags)" +git add deploy/k8s/deployment.yaml +if git diff --cached --quiet; then + echo "==> done: v$new_version is live (deployment.yaml was already up to date, nothing more to commit)" +else + git commit -m "Deploy v$new_version" + git tag "v$new_version" + echo "==> done: v$new_version is live (tagged v$new_version — push with: git push <remote> main --tags)" +fi