name: Build and Push on: push: branches: [main] # Don't rebuild on doc-only or CI-config-only changes paths-ignore: - 'README.md' - '.gitea/**' - 'deploy/**' workflow_dispatch: env: REGISTRY: registry.c5ai.ch IMAGE: pieced/pieced-portal jobs: build: # 'self-hosted' matches the label our act_runner registers with. # 'ubuntu-latest' would work too because we configure both labels in the # runner config, but self-hosted makes intent explicit. runs-on: ubuntu-latest env: DOCKER_HOST: tcp://172.17.0.1:2375 outputs: version: ${{ steps.version.outputs.version }} steps: - name: Checkout uses: actions/checkout@v4 - name: Determine next patch version id: version # Reads tags from the registry's OCI Distribution v2 API, filters to # strict semver (skips 'latest', 'dev', '-dirty', etc.), picks the # highest with version-sort, and bumps the patch component. If nothing # numeric exists yet (fresh registry), starts at 0.1.0. run: | set -euo pipefail tags_json=$(curl -sf -u "${{ secrets.REGISTRY_USERNAME }}:${{ secrets.REGISTRY_PASSWORD }}" \ "https://${REGISTRY}/v2/${IMAGE}/tags/list") highest=$(echo "$tags_json" \ | jq -r '.tags // [] | .[]' \ | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' \ | sort -V \ | tail -n1 || true) if [ -z "$highest" ]; then next="0.1.0" echo "No semver tags found — starting at $next" else major=$(echo "$highest" | cut -d. -f1) minor=$(echo "$highest" | cut -d. -f2) patch=$(echo "$highest" | cut -d. -f3) next="${major}.${minor}.$((patch + 1))" echo "Highest existing: $highest → next: $next" fi echo "version=${next}" >> "$GITHUB_OUTPUT" - name: Login to registry run: | echo "${{ secrets.REGISTRY_PASSWORD }}" \ | docker login "${REGISTRY}" -u "${{ secrets.REGISTRY_USERNAME }}" --password-stdin - name: Build and push image env: VERSION: ${{ steps.version.outputs.version }} run: | set -euo pipefail docker build \ --pull \ -t "${REGISTRY}/${IMAGE}:${VERSION}" \ -t "${REGISTRY}/${IMAGE}:latest" \ . docker push "${REGISTRY}/${IMAGE}:${VERSION}" docker push "${REGISTRY}/${IMAGE}:latest" - name: Tag git commit with version env: VERSION: ${{ steps.version.outputs.version }} run: | set -euo pipefail git config user.name "pieced-ci" git config user.email "ci@pieced.ch" git tag -a "v${VERSION}" -m "Release ${VERSION}" # Use CI_TOKEN explicitly so we can push a tag (the workflow's # default token may or may not have push scope depending on Gitea # actions config — explicit token avoids ambiguity). git push \ "https://oauth2:${{ secrets.CI_TOKEN }}@git.c5ai.ch/pieced/pieced-portal.git" \ "v${VERSION}" - name: Summary env: VERSION: ${{ steps.version.outputs.version }} run: | { echo "## Build complete: ${VERSION}" echo echo "**Image:** \`${REGISTRY}/${IMAGE}:${VERSION}\`" echo echo "Run the **Deploy to GitOps** workflow to roll this version out." } >> "$GITHUB_STEP_SUMMARY"