Files
Bastian de BylandClaude Opus 5 d0e76bd6cf feat(gitea-actions): build the CI job images in Gitea CI
The runner's job images were built by ansible into localhost/ only, so the
nightly CI prune deleted them and every idle stretch ended with CI failing in
under a second on `docker pull localhost/gitea-ci:latest` until someone re-ran
the role and waited out a rebuild. The previous commit moved them to the Gitea
registry; this moves the *build* off the deploy path entirely.

- .gitea/workflows/ci-images.yml builds files/Containerfile.* and pushes to
  git.debyl.io/gitbot/. Per-image change detection, so an ESP-IDF pin bump does
  not rebuild the other two; weekly schedule for base-image updates; a
  workflow_dispatch selector. PRs build under a throwaway :pr-<n> tag and drop
  it -- the build lands in the live runner's store, and act_runner will not
  re-pull a tag it already has, so a PR using the real tag would hand every
  later job on this host an unmerged image.
- The Containerfiles stop being ansible templates: their version vars are now
  --build-arg, read by the workflow out of the same defaults/main.yml the role
  interpolates, so CI and ansible build the same bytes from one set of pins.
- LABEL io.debyl.ci-base moves into each Containerfile so neither builder can
  forget the prune exemption; the workflow re-checks it before pushing.
- roles/gitea-actions pulls instead of building. gitea_ci_build_local=true
  restores the local build+push for seeding a cold registry or when CI is
  down -- the workflow that builds gitea-ci runs in gitea-ci.
- Lint .gitea/ alongside ansible/, and document the flow in the role README.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 11:10:43 -04:00

109 lines
4.2 KiB
Makefile

# __ ____ __
# __ _ ___ _/ /_____ / _(_) /__
# / ' \/ _ `/ '_/ -_) _/ / / -_)
# /_/_/_/\_,_/_/\_\\__/_//_/_/\__/
#
# Author: bdebyl (Bastian de Byl)
all: lint
PASS_SRC=./.pass.sh
# Setup Definitions
VENV=.venv
VENV_BIN=.venv/bin
PIP=${VENV_BIN}/pip
ANSIBLE=${VENV_BIN}/ansible-playbook
ANSIBLE_VAULT=${VENV_BIN}/ansible-vault
LINT_YAML=${VENV_BIN}/yamllint
VAULT_PASS_FILE=.ansible-vaultpass
VAULT_FILE=ansible/vars/vault.yml
# Variables
ANSIBLE_INVENTORY=ansible/inventories/home/hosts.yml
# The label print proxy is a separate inventory and playbook: it is Debian, not
# Fedora, and shares none of the roles home.debyl.io runs.
ANSIBLE_INVENTORY_LABELPRINT=ansible/inventories/labelprint/hosts.yml
#SSH_KEY=${HOME}/.ssh/id_rsa_home_ansible
# Default to all ansible tags to run (passed via 'make deploy TAGS=sometag')
TAGS?=all
SKIP_TAGS?=none
TARGET?=all
EXTRA_VARS?=
# Mounted boot partition of the label print proxy's SD card (see `make bootfs`)
BOOTFS?=/Volumes/bootfs
${VENV}:
python3 -m venv ${VENV}
${VENV_BIN}/python3 -m pip install --upgrade pip
${PIP}: ${VENV}
${ANSIBLE} ${ANSIBLE_VAULT} ${LINT_YAML}: ${VENV} requirements.txt
${PIP} install -r requirements.txt
touch $@
${VAULT_PASS_FILE}: ${ANSIBLE}
. ${PASS_SRC}; pass $$PASS_LOC > $@
${VAULT_FILE}: ${VAULT_PASS_FILE}
if [ ! -e "${VAULT_FILE}" ]; then \
${ANSIBLE_VAULT} create --vault-password-file ${VAULT_PASS_FILE} $@; \
fi
touch $@
# Linting
# .gitea/workflows is linted too: the CI-image workflow is as much part of the
# deployment as the roles it publishes for.
YAML_FILES=$(shell find ansible/ .gitea/ -name '*.yml' -not -name '*vault*')
SKIP_FILE=./.lint-vars.sh
# Targets
deploy: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --diff -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} $(if ${EXTRA_VARS},-e "${EXTRA_VARS}") ansible/deploy.yml
# Writes the Pi's cloud-init first-boot files onto a freshly imaged SD card.
bootfs: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --diff -i ${ANSIBLE_INVENTORY_LABELPRINT} --vault-password-file ${VAULT_PASS_FILE} -e "bootfs=${BOOTFS}" ansible/bootfs.yml
# Label print proxy (stickah.local). Override the address when the Pi has
# fallen back to its rescue AP:
# make deploy-labelprint EXTRA_VARS="ansible_host=192.168.4.1"
deploy-labelprint: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --diff -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY_LABELPRINT} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} $(if ${EXTRA_VARS},-e "${EXTRA_VARS}") ansible/deploy_labelprint.yml
check-labelprint: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --check --diff -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY_LABELPRINT} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} $(if ${EXTRA_VARS},-e "${EXTRA_VARS}") ansible/deploy_labelprint.yml
list-tags: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --list-tags -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml
list-tasks: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --list-tasks -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} ansible/deploy.yml
check: ${ANSIBLE} ${VAULT_FILE}
${ANSIBLE} --check --diff -t ${TAGS} --skip-tags ${SKIP_TAGS} -i ${ANSIBLE_INVENTORY} -l ${TARGET} --vault-password-file ${VAULT_PASS_FILE} $(if ${EXTRA_VARS},-e "${EXTRA_VARS}") ansible/deploy.yml
vault: ${ANSIBLE_VAULT} ${VAULT_FILE}
${ANSIBLE_VAULT} edit --vault-password-file ${VAULT_PASS_FILE} ${VAULT_FILE}
lint: ${LINT_YAML} ${SKIP_FILE}
@printf "Running yamllint...\n"
-@${LINT_YAML} ${YAML_FILES}
@printf "Done.\n"
# Git-crypt management
git-crypt-backup:
@printf "Backing up git-crypt symmetric key...\n"
@mkdir -p .git-crypt-backup
@gpg --batch --yes -e -r 70A4AA02555DBD559189B4E0F32BE05EADAA54FC -o .git-crypt-backup/symmetric-key.gpg .git/git-crypt/keys/default
@printf "Backup created at .git-crypt-backup/symmetric-key.gpg\n"
git-crypt-restore:
@printf "Restoring git-crypt symmetric key from backup...\n"
@mkdir -p .git/git-crypt/keys
@gpg --batch --yes -d .git-crypt-backup/symmetric-key.gpg > .git/git-crypt/keys/default
@chmod 600 .git/git-crypt/keys/default
@printf "Key restored. Run 'git-crypt unlock' or just checkout files.\n"