diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..f172ba6 --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,105 @@ +name: docker publish + +# Builds + pushes the api and worker images to Docker Hub on every git +# tag of the form v* (eg v0.4.0, v0.4.1-rc.0). Tags are derived from +# the git tag so consumers can pin precisely: +# +# docker pull sentriscloud/indexer-api:0.4.0 +# docker pull sentriscloud/indexer-worker:0.4.0 +# +# `latest` is also pushed when the tag is a non-prerelease semver (no +# hyphen suffix), so `:latest` always points at a stable release. +# +# Manual workflow_dispatch is allowed for ad-hoc rebuilds (eg after a +# base-image security bump that doesn't ship a code change). The +# operator picks which tag to rebuild via the input. + +on: + push: + tags: + - 'v*' + workflow_dispatch: + inputs: + tag: + description: 'git tag to rebuild (eg v0.4.0)' + required: true + type: string + +permissions: + contents: read + +jobs: + build: + name: build + push (${{ matrix.image }}) + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + include: + - image: indexer-api + dockerfile: apps/api/Dockerfile + - image: indexer-worker + dockerfile: apps/indexer/Dockerfile + steps: + - uses: actions/checkout@v5 + with: + ref: ${{ inputs.tag || github.ref }} + + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Resolve version tag + id: ver + run: | + REF="${{ inputs.tag || github.ref_name }}" + # Strip leading 'v' so the docker tag matches semver convention. + VERSION="${REF#v}" + echo "version=$VERSION" >> $GITHUB_OUTPUT + # Push :latest only on non-prerelease (no '-' suffix). + if [[ "$VERSION" != *-* ]]; then + echo "latest=true" >> $GITHUB_OUTPUT + else + echo "latest=false" >> $GITHUB_OUTPUT + fi + + - name: Compose docker tags + id: tags + run: | + TAGS="sentriscloud/${{ matrix.image }}:${{ steps.ver.outputs.version }}" + if [ "${{ steps.ver.outputs.latest }}" = "true" ]; then + TAGS="$TAGS,sentriscloud/${{ matrix.image }}:latest" + fi + # Multi-line for buildx --tag flag. + { + echo 'tags<> $GITHUB_OUTPUT + + - name: Build + push + uses: docker/build-push-action@v6 + with: + context: . + file: ${{ matrix.dockerfile }} + push: true + # linux/amd64 only for now — arm64 build infrastructure + # (qemu emulation on x86 runners) takes ~5x longer; opt in + # via a follow-up workflow when arm64 demand surfaces. + platforms: linux/amd64 + tags: ${{ steps.tags.outputs.tags }} + labels: | + org.opencontainers.image.source=https://github.com/${{ github.repository }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=${{ steps.ver.outputs.version }} + org.opencontainers.image.licenses=MIT + cache-from: type=gha,scope=${{ matrix.image }} + cache-to: type=gha,mode=max,scope=${{ matrix.image }} + + - name: Image digest + run: echo "${{ matrix.image }}:${{ steps.ver.outputs.version }} → built + pushed"