# Release build (ADR 0014, issue #89): pushing a semver tag `vX.Y.Z` builds # and pushes the immutable release images and publishes a Gitea release # whose notes list the changes since the previous release, with a call-out # when the release contains database migrations (the `migration` marker the # update guide promises). Deploying to Prod is a SEPARATE, manual step: # after reviewing the release, push a `prod-vX.Y.Z-` tag # (prod-deploy.yml) — that tag push is the manual approval gate, since # Gitea 1.22 has no environment approvals (revisit on 1.23+). name: Release on: push: tags: ['v*.*.*'] env: IMAGE_BASE: gitea.101010.cloud/stwaidele/dorfteich jobs: build-release: name: Build release images and notes runs-on: ubuntu-latest steps: - name: Check out repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Log in to the Gitea registry run: printf '%s' "${{ secrets.REGISTRY_TOKEN }}" | tr -d '[:space:]' | docker login gitea.101010.cloud -u fable-5 --password-stdin - name: Build and push semver images run: | TAG=${GITHUB_REF_NAME} for app in web api collab backup; do docker build -f apps/$app/Dockerfile --build-arg APP_VERSION=$TAG \ -t $IMAGE_BASE-$app:$TAG . docker push $IMAGE_BASE-$app:$TAG done - name: Generate release notes and publish the release run: | TAG=${GITHUB_REF_NAME} PREV=$(git tag --list 'v*.*.*' --sort=-v:refname | grep -vx "$TAG" | head -n1 || true) RANGE=${PREV:+$PREV..}$TAG { echo "## Changes since ${PREV:-the beginning}" echo git log --no-merges --pretty='- %s' $RANGE echo if git diff --name-only ${PREV:-$(git hash-object -t tree /dev/null)} $TAG -- apps/api/prisma/migrations/ | grep -q .; then echo '> ⚠️ **migration** — this release applies database migrations automatically at api start. Downgrade window: one minor release (docs/self-hosting).' else echo '_No database migrations in this release._' fi } > notes.md TAG=$TAG docker run --rm -i -e TAG node:22.15-alpine node -e \ 'const fs=require("fs");const body=fs.readFileSync(0,"utf8");process.stdout.write(JSON.stringify({tag_name:process.env.TAG,name:process.env.TAG,body}))' \ < notes.md > release.json curl -sf -X POST \ -H "Authorization: token ${{ github.token }}" \ -H 'Content-Type: application/json' \ --data @release.json \ "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \ > /dev/null && echo "release $TAG published"