133 lines
4.7 KiB
YAML
133 lines
4.7 KiB
YAML
name: Build and publish container
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: write
|
|
packages: write
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
with:
|
|
# Full history and tags are required to derive the next version
|
|
# from the conventional-commit messages since the last release.
|
|
fetch-depth: 0
|
|
|
|
- name: Determine registry host
|
|
run: echo "REGISTRY=${GITHUB_SERVER_URL#*://}" >> "$GITHUB_ENV"
|
|
|
|
# Derive the release version from conventional commits since the last
|
|
# v* tag: feat -> minor, fix/perf -> patch, ! or BREAKING CHANGE -> major.
|
|
# Anything else (chore, ci, docs, build) produces no release; those builds
|
|
# are published under a sha-<short> tag only.
|
|
- name: Compute version and image tags
|
|
id: version
|
|
run: |
|
|
set -euo pipefail
|
|
image="${REGISTRY}/${GITHUB_REPOSITORY,,}"
|
|
|
|
last_tag="$(git tag --list 'v*' --sort=-v:refname | head -n1 || true)"
|
|
if [ -n "$last_tag" ]; then
|
|
range="${last_tag}..HEAD"
|
|
base="${last_tag#v}"
|
|
else
|
|
range=""
|
|
base="0.0.0"
|
|
fi
|
|
|
|
subjects="$(git log ${range} --format='%s')"
|
|
bodies="$(git log ${range} --format='%B')"
|
|
|
|
bump="none"
|
|
if printf '%s\n' "$bodies" | grep -qiE 'BREAKING[ -]CHANGE' \
|
|
|| printf '%s\n' "$subjects" | grep -qE '^[a-z]+([(][^)]*[)])?!:'; then
|
|
bump="major"
|
|
elif printf '%s\n' "$subjects" | grep -qE '^feat([(][^)]*[)])?:'; then
|
|
bump="minor"
|
|
elif printf '%s\n' "$subjects" | grep -qE '^(fix|perf)([(][^)]*[)])?:'; then
|
|
bump="patch"
|
|
fi
|
|
|
|
major="${base%%.*}"
|
|
rest="${base#*.}"
|
|
minor="${rest%%.*}"
|
|
patch="${rest##*.}"
|
|
|
|
release="false"
|
|
if [ "${GITHUB_EVENT_NAME}" = "push" ] && [ "$bump" != "none" ]; then
|
|
release="true"
|
|
case "$bump" in
|
|
major) major=$((major + 1)); minor=0; patch=0 ;;
|
|
minor) minor=$((minor + 1)); patch=0 ;;
|
|
patch) patch=$((patch + 1)) ;;
|
|
esac
|
|
version="${major}.${minor}.${patch}"
|
|
{
|
|
echo "tags<<__EOT__"
|
|
echo "${image}:${version}"
|
|
echo "${image}:${major}.${minor}"
|
|
echo "${image}:${major}"
|
|
echo "${image}:latest"
|
|
echo "__EOT__"
|
|
} >> "$GITHUB_OUTPUT"
|
|
echo "version=${version}" >> "$GITHUB_OUTPUT"
|
|
else
|
|
short="$(git rev-parse --short HEAD)"
|
|
{
|
|
echo "tags<<__EOT__"
|
|
echo "${image}:sha-${short}"
|
|
echo "__EOT__"
|
|
} >> "$GITHUB_OUTPUT"
|
|
fi
|
|
echo "release=${release}" >> "$GITHUB_OUTPUT"
|
|
echo "Computed bump=${bump}, release=${release}, base=${base}"
|
|
|
|
- name: Set up QEMU
|
|
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
|
|
|
|
- name: Set up Buildx
|
|
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
|
|
|
- name: Log in to the Gitea container registry
|
|
if: github.event_name != 'pull_request'
|
|
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.repository_owner }}
|
|
password: ${{ secrets.PACKAGES_TOKEN }}
|
|
|
|
- name: Build and push
|
|
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
|
with:
|
|
context: .
|
|
platforms: linux/amd64,linux/arm64
|
|
push: ${{ github.event_name != 'pull_request' }}
|
|
tags: ${{ steps.version.outputs.tags }}
|
|
labels: |
|
|
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
|
org.opencontainers.image.revision=${{ github.sha }}
|
|
|
|
# Record the release as an annotated git tag so the next run computes the
|
|
# following version from it. This push does not re-trigger the workflow,
|
|
# which only listens on the main branch and pull requests.
|
|
- name: Tag the release
|
|
if: steps.version.outputs.release == 'true'
|
|
run: |
|
|
set -euo pipefail
|
|
v="v${{ steps.version.outputs.version }}"
|
|
git config user.name "${{ github.actor }}"
|
|
git config user.email "${{ github.actor }}@users.noreply.${REGISTRY}"
|
|
git tag -a "$v" -m "$v"
|
|
git push origin "$v"
|