irongit

Git hosting and a container registry in one Rust binary (axum + Astro)

irongit/deploy.sh
67 lines2.6 KBBourne Again Shell (bash)
1#!/usr/bin/env bash
2# Deploy irongit to the rybbit server: build the image here, ship it over SSH,
3# and roll only the irongit service in /opt/hygo (behind Caddy, on the shared
4# Postgres). Publishes the bundled ig CLI to R2 when its version changed.
5#
6# ./deploy.sh
7#
8# Roll back to the previous image:
9# ssh rybbit 'cd /opt/hygo && docker tag irongit:$(cat .irongit.prev) irongit:latest && docker compose up -d --no-deps irongit'
10set -euo pipefail
11
12cd "$(dirname "$0")"
13REMOTE=${DEPLOY_HOST:-rybbit}
14TAG=$(git rev-parse --short HEAD)
15if ! git diff --quiet HEAD; then
16 TAG="$TAG-dirty-$(date +%Y%m%d%H%M%S)"
17fi
18PUBLIC_URL=${DEPLOY_PUBLIC_URL:-https://git.hygo.ai}
19# ig's version is major.minor from cli/Cargo.toml plus the number of commits
20# that touched the CLI, so any CLI change publishes a newer release that
21# `ig upgrade` (and its daily notice) picks up. No manual bumps.
22IG_BASE=$(sed -n 's/^version = "\([0-9]*\.[0-9]*\)\..*"/\1/p' cli/Cargo.toml | head -1)
23IG_VERSION="$IG_BASE.$(git rev-list --count HEAD -- cli shared)"
24
25echo "==> building irongit:$TAG (ig $IG_VERSION, default host $PUBLIC_URL)"
26docker build --build-arg "IG_BUILD_VERSION=$IG_VERSION" --build-arg "IG_DEFAULT_HOST=$PUBLIC_URL" -t "irongit:$TAG" .
27
28echo "==> shipping to $REMOTE"
29docker save "irongit:$TAG" | gzip -1 | ssh "$REMOTE" 'gunzip | docker load'
30
31echo "==> rolling"
32ssh "$REMOTE" bash -s -- "$TAG" "$IG_VERSION" <<'REMOTE_SCRIPT'
33set -euo pipefail
34cd /opt/hygo
35tag=$1
36ig_version=$2
37
38[ -f .irongit.tag ] && cp .irongit.tag .irongit.prev
39docker tag "irongit:$tag" irongit:latest
40echo "$tag" > .irongit.tag
41docker compose up -d --no-deps irongit
42
43ok=0
44for _ in $(seq 1 45); do
45 status=$(docker inspect irongit --format '{{.State.Health.Status}}' 2>/dev/null || echo none)
46 if [ "$status" = healthy ]; then ok=1; break; fi
47 sleep 2
48done
49if [ "$ok" != 1 ]; then
50 echo "irongit did not become healthy; last logs:" >&2
51 docker logs --tail 60 irongit >&2
52 exit 1
53fi
54echo "irongit:$tag healthy"
55
56published=$(docker exec irongit wget -qO- http://127.0.0.1:7878/api/v1/cli/latest 2>/dev/null | sed -n 's/.*"version":"\([^"]*\)".*/\1/p' || true)
57if [ "$published" != "$ig_version" ]; then
58 echo "publishing ig $ig_version (was ${published:-none})"
59 docker exec irongit irongit admin publish-cli /usr/local/share/irongit/ig --version "$ig_version"
60fi
61
62# Keep the three newest irongit images.
63docker images irongit --format '{{.Tag}} {{.CreatedAt}}' | grep -v '^latest ' | sort -k2 -r | tail -n +4 | cut -d' ' -f1 \
64 | while read -r old; do [ "$old" = "$tag" ] || docker rmi "irongit:$old" >/dev/null 2>&1 || true; done
65REMOTE_SCRIPT
66
67echo "==> done: $PUBLIC_URL"