Merge pull request 'ci: build & publish app + bot images to Gitea registry on merge' (#53) from ci/gitea-actions-image-build into main
All checks were successful
Build container images / build (push) Successful in 24s

Reviewed-on: UOM/website#53
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
This commit is contained in:
2026-07-11 23:01:04 +00:00

View File

@@ -0,0 +1,87 @@
# Build and publish the app + bot container images to Gitea's container registry
# on every merge to main. Production then pulls prebuilt images instead of
# building on the host.
#
# Prerequisites (one-time):
# • An always-on Gitea runner with label `ubuntu-latest` whose jobs have the
# host Docker socket mounted (/var/run/docker.sock), so `docker build` talks
# to the host daemon. This also gives free layer caching between runs.
# • Two repo secrets (Settings → Actions → Secrets):
# REGISTRY_USER — the Gitea username that owns the token below
# REGISTRY_TOKEN — a Gitea access token with `write:package` (+ read:package)
# See the PR description / README for step-by-step token creation.
#
# Produces, in gitea.whitlocktech.com/<owner>/ :
# website-app:latest + website-app:sha-<7>
# website-bot:latest + website-bot:sha-<7>
name: Build container images
on:
push:
branches: [main]
workflow_dispatch: {}
concurrency:
group: images-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: gitea.whitlocktech.com
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out the merged commit
uses: actions/checkout@v4
- name: Derive image refs (registry owner must be lowercase for Docker)
run: |
set -euo pipefail
OWNER="$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')"
SHORT_SHA="${GITHUB_SHA:0:7}"
echo "APP_IMAGE=${REGISTRY}/${OWNER}/website-app" >> "$GITHUB_ENV"
echo "BOT_IMAGE=${REGISTRY}/${OWNER}/website-bot" >> "$GITHUB_ENV"
echo "TAG=sha-${SHORT_SHA}" >> "$GITHUB_ENV"
- name: Verify the Docker daemon is reachable
# Fails fast with a clear message if the host socket isn't mounted into
# the job container (the one hard runner prerequisite).
run: |
set -euo pipefail
if ! docker info >/dev/null 2>&1; then
echo "::error::Docker daemon not reachable. Mount /var/run/docker.sock into the runner's job containers."
exit 1
fi
echo "Docker daemon OK"
- name: Log in to the Gitea container registry
run: |
set -euo pipefail
echo "${{ secrets.REGISTRY_TOKEN }}" \
| docker login "${REGISTRY}" -u "${{ secrets.REGISTRY_USER }}" --password-stdin
- name: Build & push the app image (server + client)
run: |
set -euo pipefail
docker build -f Dockerfile \
-t "${APP_IMAGE}:latest" \
-t "${APP_IMAGE}:${TAG}" \
.
docker push "${APP_IMAGE}:latest"
docker push "${APP_IMAGE}:${TAG}"
- name: Build & push the bot image
run: |
set -euo pipefail
docker build -f bot/Dockerfile \
-t "${BOT_IMAGE}:latest" \
-t "${BOT_IMAGE}:${TAG}" \
.
docker push "${BOT_IMAGE}:latest"
docker push "${BOT_IMAGE}:${TAG}"
- name: Log out (clear cached credentials from the runner)
if: always()
run: docker logout "${REGISTRY}" || true