Model the build on mozimo and target emily

- Makefile: PLATFORMS, tags :<commit> and :main, build-check with --pull.
- deploy.sh: push, guards, git pull --ff-only, optional --prune, image_tag.
- Replace .containerignore with .dockerignore.
- Add the opt-in image prune to the hops role.
- Tag the Caddyfile task so --skip-tags caddy works before DNS cutover.
- Trim comments and rewrite build and deploy text in plain prose.
This commit is contained in:
tanshu committed 2026-10-20 17:47:49 +05:30
1 parent 7366596a87
commit a7c9324170
14 files changed
+194 -357

No files matched your search

+19 -44
View File
@@ -1,72 +1,47 @@
#!/usr/bin/env bash
#
# Hops n Grains deploy — push the current commit, build it with podman, and
# install the Quadlet unit on emily with ansible.
#
# The image is built from the committed tree (`git archive HEAD`) and tagged
# with its commit id, so what runs on the host is exactly what git knows about.
#
# ./deploy.sh deploy HEAD (tracked tree must be clean and pushed)
# ./deploy.sh --force skip the guards (know what you are doing)
# ./deploy.sh --no-push skip the push, if you already pushed
#
# Log in to the registry once beforehand: podman login registry.tanshu.com
# Deploy HEAD with podman and ansible on emily. Flags: --prune keeps three old
# images, --force skips the guards. The tree must be clean and HEAD pushed.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
BRANCH="${BRANCH:-main}"
git push
FORCE=false
NO_PUSH=false
PRUNE=false
for arg in "$@"; do
case "$arg" in
--force) FORCE=true ;;
--no-push) NO_PUSH=true ;;
--prune) PRUNE=true ;;
*)
echo "Usage: $0 [--force] [--no-push]" >&2
echo "Usage: $0 [--force] [--prune]" >&2
exit 1
;;
esac
done
# The build takes HEAD, so push first: otherwise the registry collects an image
# for a commit that exists only on this machine.
if [ "$NO_PUSH" != true ]; then
echo "==> pushing"
git push
fi
# Guards. Only tracked-file state matters — untracked and ignored files never
# enter a `git archive HEAD` build. HEAD must match origin/$BRANCH so the commit
# the image is tagged with is one the remote actually has.
if [ "$FORCE" != true ]; then
if [ -n "$(git status --porcelain --untracked-files=no)" ]; then
echo "x tracked files modified - commit or stash first (or --force)" >&2
echo "x tracked files modified, commit or stash first (or --force)" >&2
exit 1
fi
git fetch origin --quiet
if [ "$(git rev-parse HEAD)" != "$(git rev-parse "origin/$BRANCH")" ]; then
echo "x HEAD != origin/$BRANCH - push or pull first (or --force)" >&2
if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then
echo "x HEAD != origin/main, push or pull first (or --force)" >&2
exit 1
fi
fi
git pull --ff-only
TAG=$(git rev-parse --short HEAD)
echo "==> deploying commit $TAG"
echo "========================================================"
echo " Building & Uploading Container Image (Podman)"
echo "========================================================"
make build-production COMMIT="$TAG"
echo ""
echo "========================================================"
echo " Executing Ansible Deployment"
echo "========================================================"
# The play configures rootless Podman Quadlet units that belong to the
# connecting user, so it must connect as that user and must NOT become root.
# `-u` is the account that owns ~/.config/containers/systemd on the target.
deploy_user="${ANSIBLE_USER:-tanshu}"
cd ansible || exit
# image_tag pins the exact commit; rollback is -e image_tag=<older-commit>.
ansible-playbook -u "$deploy_user" playbook.yml -e "image_tag=$TAG"
if [ "$PRUNE" = true ]; then
PRUNE_FLAG="-e hops_image_prune=true"
else
PRUNE_FLAG=""
fi
cd ansible
# shellcheck disable=SC2086
ansible-playbook playbook.yml -e "image_tag=$TAG" $PRUNE_FLAG