102 lines
4.7 KiB
Shell
Executable file
102 lines
4.7 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# ./sync.sh live edits down → merge with yours → push to forgejo + live
|
|
# ./sync.sh pull only bring live edits down (start of a work session)
|
|
# ./sync.sh unify one time: fold the werc/ and werc/sites/ repos into this one, adopt it on live
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")"
|
|
HOST=${SITE_HOST:-chillin@192.168.2.69}
|
|
BR=main
|
|
LIVE=refs/remotes/live/$BR
|
|
|
|
# Runs on home in the live checkout. git runs as werc's own user, so web edits and deploys share one owner.
|
|
live() {
|
|
set -euo pipefail
|
|
cd /opt/thirdculture.top/site
|
|
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
|
|
g() { docker compose --progress quiet run --rm --no-deps -T -u lighttpd -v "$PWD:/s" -w /s --entrypoint git werc \
|
|
-c safe.directory='*' -c user.name=werc -c user.email=werc@thirdculture.diy "$@"; }
|
|
case $1 in
|
|
head) g rev-parse -q --verify main || true ;;
|
|
commit) g add -A; g diff --cached --quiet || g commit -qm "users: live edits" ;;
|
|
bundle) g bundle create -q - main ${2:+"^$2"} ;;
|
|
deploy) cat > .incoming.bundle
|
|
g fetch -q .incoming.bundle +main:refs/heads/incoming; rm -f .incoming.bundle
|
|
[ -z "$(g status --porcelain)" ] || { echo "live changed during the sync, run it again" >&2; exit 1; }
|
|
old=$(g rev-parse main)
|
|
g merge -q --ff-only incoming
|
|
g log --oneline "$old..main"
|
|
if g diff --name-only "$old" main | grep -qE '^(Dockerfile|docker-compose.yml|init.sh|etc/)'; then
|
|
docker compose up -d --build
|
|
fi ;;
|
|
adopt) cat > .incoming.bundle
|
|
if [ -d werc/.git ]; then
|
|
mkdir -p ../site-oldgit; mv werc/.git ../site-oldgit/werc.git; mv werc/sites/.git ../site-oldgit/sites.git
|
|
fi
|
|
rm -f werc/.gitignore
|
|
docker compose --progress quiet run --rm --no-deps -T -u 0 -v "$PWD:/s" --entrypoint chown werc -R lighttpd /s
|
|
g init -q -b main
|
|
g fetch -q .incoming.bundle +refs/heads/unify-base:refs/heads/incoming; rm -f .incoming.bundle
|
|
g reset -q incoming
|
|
g checkout -- .gitignore
|
|
g status --short ;;
|
|
esac
|
|
}
|
|
on_live() { ssh "$HOST" "bash -c $(printf %q "$(declare -f live); live $*")"; }
|
|
|
|
need_clean() {
|
|
[ ! -d werc/.git ] || { echo "not one repo yet: run ./sync.sh unify first"; exit 1; }
|
|
[ -z "$(git status --porcelain)" ] || { echo "commit or stash your changes first:"; git status --short; exit 1; }
|
|
}
|
|
|
|
pull_live() {
|
|
on_live commit
|
|
head=$(on_live head)
|
|
[ -n "$head" ] || { echo "live isn't a git checkout yet: ./sync.sh unify"; exit 1; }
|
|
base=$(git rev-parse -q --verify $LIVE || true)
|
|
if [ "$head" != "$base" ]; then
|
|
tmp=$(mktemp); on_live bundle "$base" > "$tmp"
|
|
git fetch -q "$tmp" "+$BR:$LIVE"; rm -f "$tmp"
|
|
fi
|
|
git merge --no-edit $LIVE || { echo "conflict: fix the files, git commit, then ./sync.sh again"; exit 1; }
|
|
}
|
|
|
|
deploy() {
|
|
git push -q origin $BR
|
|
if git merge-base --is-ancestor HEAD $LIVE; then echo "live is up to date"; return; fi
|
|
tmp=$(mktemp); git bundle create -q "$tmp" $BR "^$LIVE"
|
|
on_live deploy < "$tmp"; rm -f "$tmp"
|
|
git update-ref $LIVE $BR
|
|
}
|
|
|
|
unify() {
|
|
[ -d werc/.git ] || { echo "already one repo"; return; }
|
|
[ "$(git branch --show-current)" = $BR ] || { echo "switch to $BR first"; exit 1; }
|
|
stage=$(mktemp -d); idx=$(mktemp -u)
|
|
echo "== snapshot live"
|
|
rsync -az --exclude=.git --exclude=/werc.tar.gz --exclude=/werc/etc/users/ --exclude=/werc/etc/misaki_sso.secret \
|
|
--exclude=.htpasswd --exclude=/scripts/.env/ "$HOST:/opt/thirdculture.top/site/" "$stage/"
|
|
cp .gitignore "$stage/.gitignore"; rm -f "$stage/werc/.gitignore"
|
|
GIT_INDEX_FILE=$idx git --work-tree="$stage" add -A
|
|
c1=$(git commit-tree "$(GIT_INDEX_FILE=$idx git write-tree)" -p HEAD -m "site: live as it was, werc + sites folded in")
|
|
rm -rf "$idx" "$stage"
|
|
echo "== your local changes on top"
|
|
mkdir -p ../site-oldgit; mv werc/.git ../site-oldgit/werc.git; mv werc/sites/.git ../site-oldgit/sites.git
|
|
rm -f werc/.gitignore
|
|
rm -rf werc/sites/default.cat-v.org werc/sites/tst.cat-v.org werc/sites/werc.cat-v.org werc/sites/CREATE-SITE-DIRECTORIES-HERE
|
|
git update-ref refs/heads/$BR "$c1"
|
|
git reset -q
|
|
git add -A; git commit -qm "site: one repo, local changes since live"
|
|
echo "== adopt on live"
|
|
git branch -f unify-base "$c1"
|
|
tmp=$(mktemp); git bundle create -q "$tmp" unify-base; on_live adopt < "$tmp"; rm -f "$tmp"
|
|
git branch -D -q unify-base; git update-ref $LIVE "$c1"
|
|
git remote set-url origin https://git.thirdculture.diy/q/thirdculture-docker.git
|
|
echo "== deploy"; deploy
|
|
}
|
|
|
|
case ${1:-sync} in
|
|
sync) need_clean; pull_live; deploy ;;
|
|
pull) need_clean; pull_live ;;
|
|
unify) unify ;;
|
|
*) sed -n '2,4p' "$0"; exit 2 ;;
|
|
esac
|