name: Docker on: push: branches: - "handmade" pull_request: branches: - "handmade" release: types: - published permissions: contents: read jobs: # Builds the shared base image: the whole Rust workspace compiled once. # Every service image (currently only pushd) is derived from this so the # workspace is built a single time per release. On non-release events this # still runs as a compile check, but nothing is pushed. base: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Resolve registry host and owner id: registry # Owner is lowercased: Docker repository names must be lowercase. run: | echo "host=${GITHUB_SERVER_URL#*://}" >> "$GITHUB_OUTPUT" echo "owner=$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" - name: Base image ref id: base run: echo "image=${{ steps.registry.outputs.host }}/${{ steps.registry.outputs.owner }}/handmade-revolt-base" >> "$GITHUB_OUTPUT" - name: Login to registry uses: docker/login-action@v3 if: github.event_name == 'release' with: registry: ${{ steps.registry.outputs.host }} username: ${{ secrets.PACKAGE_PUBLISH_USERNAME }} password: ${{ secrets.PACKAGE_PUBLISH_TOKEN }} - name: Build base image uses: docker/build-push-action@v6 with: context: . file: Dockerfile push: ${{ github.event_name == 'release' }} platforms: linux/amd64 # Pinned to the commit so the publish job below consumes this # exact base. tags: | ${{ steps.base.outputs.image }}:latest ${{ steps.base.outputs.image }}:${{ github.sha }} # Builds individual service images from the base. Only runs on release. publish: needs: [base] runs-on: ubuntu-latest if: github.event_name == 'release' strategy: matrix: # Only pushd is built. To add more services later, add # entries here (paths/images mirror the upstream revolt layout): # - { project: delta, path: crates/delta, image: handmade-revolt-server } # - { project: bonfire, path: crates/bonfire, image: handmade-revolt-bonfire } # - { project: autumn, path: crates/services/autumn, image: handmade-revolt-autumn } # - { project: january, path: crates/services/january, image: handmade-revolt-january } # - { project: crond, path: crates/daemons/crond, image: handmade-revolt-crond } include: - { project: pushd, path: crates/daemons/pushd, image: handmade-revolt-pushd } name: Build ${{ matrix.project }} image steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Resolve registry host and owner id: registry # Owner is lowercased: Docker repository names must be lowercase, # but the org (e.g. HMC) may be uppercase. run: | echo "host=${GITHUB_SERVER_URL#*://}" >> "$GITHUB_OUTPUT" echo "owner=$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" - name: Docker meta id: meta uses: docker/metadata-action@v5 with: images: ${{ steps.registry.outputs.host }}/${{ steps.registry.outputs.owner }}/${{ matrix.image }} tags: | type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=raw,value=latest env: DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - name: Login to registry uses: docker/login-action@v3 with: registry: ${{ steps.registry.outputs.host }} username: ${{ secrets.PACKAGE_PUBLISH_USERNAME }} password: ${{ secrets.PACKAGE_PUBLISH_TOKEN }} - name: Build and publish uses: docker/build-push-action@v6 with: context: . file: ${{ matrix.path }}/Dockerfile push: true platforms: linux/amd64 build-args: | BASE_IMAGE=${{ steps.registry.outputs.host }}/${{ steps.registry.outputs.owner }}/handmade-revolt-base:${{ github.sha }} tags: ${{ steps.meta.outputs.tags }} annotations: ${{ steps.meta.outputs.annotations }} labels: ${{ steps.meta.outputs.labels }}