Files
chitai/.gitea/workflows/release.yml
T
patrick b70ed5cb51 feat: build and publish release images from version tags
Tagging v* builds both images on Gitea Actions and pushes them to the instance
registry, then smoke-tests the published stack. The frontend read its backend
URL through import.meta.env, which Vite resolves at build time, so an image
could only point at whatever the build host had; it now reads it at runtime.
2026-08-17 15:05:18 -04:00

107 lines
3.6 KiB
YAML

name: release
# Builds and publishes the two container images from a version tag.
#
# Tagging v1.2.3 publishes chitai-backend and chitai-frontend as 1.2.3, 1.2, 1 and latest.
# A prerelease tag (v1.2.3-rc.1) publishes only 1.2.3-rc.1 and leaves latest alone, which
# makes -rc tags a safe way to exercise this workflow.
#
# Note that `uses: docker/...` does not mean github.com here the way it would on GitHub. Gitea
# resolves a bare reference against the instance's DEFAULT_ACTIONS_URL, which defaults to
# gitea.com; all five actions below are mirrored there at these tags. If that setting is ever
# pointed somewhere without them, set it to `github` in app.ini rather than editing this file.
#
# Requires a runner with a working Docker daemon (a docker:dind sidecar, or host mode with
# the socket mounted) and, for the smoke job, the compose plugin.
on:
push:
tags:
- 'v*'
env:
REGISTRY: git.jaroszew.ski
jobs:
build:
runs-on: ubuntu-latest
strategy:
# The two images are independent artifacts; don't cancel a good build for a bad one.
fail-fast: false
matrix:
include:
- component: backend
context: ./backend
- component: frontend
context: ./frontend
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.REGISTRY_TOKEN || secrets.GITEA_TOKEN }}
- id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}-${{ matrix.component }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
labels: |
org.opencontainers.image.title=chitai-${{ matrix.component }}
org.opencontainers.image.source=https://git.jaroszew.ski/${{ github.repository }}
- uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
# Relies on the runner's cache server. If it is disabled, drop these two lines —
# a cold build of both images is only a few minutes.
cache-from: type=gha
cache-to: type=gha,mode=max
smoke:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.REGISTRY_TOKEN || secrets.GITEA_TOKEN }}
# Boots the stack from the images that were just pushed, rather than rebuilding them.
# This is what catches migrations failing from entrypoint.sh, the frontend being unable
# to reach the backend, and a missing runtime environment variable.
- name: Boot the published images
env:
TAG: ${{ github.ref_name }}
run: |
cp .env.prod-example .env
echo "CHITAI_VERSION=${TAG#v}" >> .env
mkdir -p libraries
docker compose pull backend frontend
docker compose up -d --wait --wait-timeout 180
curl -fsS http://localhost:8000/healthcheck
curl -fsS http://localhost:3000/login > /dev/null
- name: Tear down
if: always()
run: |
docker compose logs --no-color || true
docker compose down -v || true