# Release - runs on semver tags (vMAJOR.MINOR.BUGFIX, cut on main after a # fast-forward from dev): the gates, the image built and checked like in CI, # pushed to the registry, and a Gitea release with the CHANGELOG section. # Required: secrets REGISTRY_USERNAME, REGISTRY_PASSWORD (instance-wide). name: Release on: push: tags: ['v[0-9]+.[0-9]+.[0-9]+'] env: REGISTRY: ${{ vars.REGISTRY || 'hub.bundespruefstelle.ch' }} IMAGE: bau-pm/pdf-tools jobs: release: runs-on: ubuntu-latest timeout-minutes: 150 steps: # Full history, or the ancestry gate cannot answer and would pass. - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 with: fetch-depth: 0 - name: derive version from tag run: echo "VERSION=${GITHUB_REF_NAME#v}" >> "$GITHUB_ENV" - name: gate - CHANGELOG has a section for this version run: | if ! grep -q "^## \[$VERSION\]" CHANGELOG.md; then echo "no '## [$VERSION]' section in CHANGELOG.md - cut it from [Unreleased] first" >&2 exit 1 fi - name: gate - the tag is on main run: | git fetch --no-tags origin +refs/heads/main:refs/remotes/origin/main if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then echo "$GITHUB_SHA is not an ancestor of main - fast-forward main before tagging" >&2 exit 1 fi - name: build the image timeout-minutes: 60 run: | docker build --build-arg VERSION="v$VERSION" \ -t "$REGISTRY/$IMAGE:$VERSION" -t "$REGISTRY/$IMAGE:latest" . - name: gate - nothing leaves the origin timeout-minutes: 50 run: | docker build -f test/Dockerfile -t bau-pm-pdf-tools-gate:release . net="bau-pm-pdf-tools-release-${GITHUB_RUN_ID}" docker network create "$net" >/dev/null trap 'docker rm -f -v "$net-app" >/dev/null 2>&1; docker network rm "$net" >/dev/null 2>&1' EXIT docker run -d --name "$net-app" --network "$net" --network-alias pdf-tools "$REGISTRY/$IMAGE:$VERSION" >/dev/null for i in $(seq 1 30); do docker run --rm --network "$net" bau-pm-pdf-tools-gate:release wget -q --spider http://pdf-tools:8080/ && break [ "$i" -eq 30 ] && { echo "the image never answered" >&2; exit 1; } sleep 2 done docker run --rm --network "$net" bau-pm-pdf-tools-gate:release node test/zero-hosts.mjs http://pdf-tools:8080 - name: push run: | echo "${{ secrets.REGISTRY_PASSWORD }}" \ | docker login "$REGISTRY" -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin docker push "$REGISTRY/$IMAGE:$VERSION" docker push "$REGISTRY/$IMAGE:latest" echo "digest: $(docker inspect --format '{{index .RepoDigests 0}}' "$REGISTRY/$IMAGE:$VERSION")" # Below 1.0.0 a release is a prerelease, derived from the tag. - name: create Gitea release with changelog notes run: | notes="$(awk -v ver="$VERSION" '$0 ~ "^## \\[" ver "\\]" {f=1; next} /^## \[/ {f=0} f' CHANGELOG.md)" payload="$(printf '%s' "$notes" | python3 -c 'import json,os,sys; v=os.environ["VERSION"]; print(json.dumps({"tag_name": "v" + v, "name": "bau-pm-pdf-tools v" + v, "body": sys.stdin.read().strip(), "prerelease": v.split(".")[0] == "0"}))')" curl -sf -X POST \ -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -H "Content-Type: application/json" \ -d "$payload" \ "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/releases" >/dev/null \ && echo "Gitea release v$VERSION created" \ || echo "release creation skipped (may already exist)"