name: Build and Publish
on:
  push:
    branches:
      - master
      - test/**
    tags:
      - "[0-9]+.[0-9]+.[0-9]+"
    paths-ignore:
      - "*.md"
      - "docs/**"
      - "examples/**"
      - "notes/**"
      - "kustomize/**"

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        # NOTE: the "latest" variant is identified in the Docker meta step's 'latest' config
        variant:
          - java21-graalvm
          - java21
          - java21-jdk
          - java21-alpine
          - java17
          - java17-graalvm
          - java17-alpine
          - java8
          - java8-graalvm-ce
          - java8-openj9
          - java8-jdk
          - java11
        include:
        # JAVA 21:
          - variant: java21-graalvm
            baseImage: container-registry.oracle.com/graalvm/jdk:21-ol8
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java21
            baseImage: eclipse-temurin:21-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java21-jdk
            baseImage: eclipse-temurin:21
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java21-alpine
            baseImage: eclipse-temurin:21-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
        # JAVA 17:
          - variant: java17
            # jammy doesn't work until minecraft updates to https://github.com/netty/netty/issues/12343
            baseImage: eclipse-temurin:17-jre-focal
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.20.4
          - variant: java17-graalvm
            baseImage: container-registry.oracle.com/graalvm/jdk:17-ol8
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.20.4
          - variant: java17-alpine
            baseImage: eclipse-temurin:17-jre-alpine
            platforms: linux/amd64
            mcVersion: 1.20.4
        # JAVA 11:
          - variant: java11
            baseImage: adoptopenjdk:11-jre-hotspot
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.16.5
        # JAVA 8: NOTE: Unable to go past 8u312 because of Forge dependencies
          - variant: java8
            baseImage: eclipse-temurin:8u312-b07-jre-focal
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.12.2
          - variant: java8-graalvm-ce
            baseImage: ghcr.io/graalvm/graalvm-ce:java8
            platforms: linux/amd64
            mcVersion: 1.12.2
          - variant: java8-jdk
            baseImage: eclipse-temurin:8u312-b07-jdk-focal
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.12.2
          - variant: java8-openj9
            baseImage: ibm-semeru-runtimes:open-8u312-b07-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.12.2
    env:
      IMAGE_TO_TEST: "${{ github.repository_owner }}/minecraft-server:test-${{ matrix.variant }}-${{ github.run_id }}"
      HAS_IMAGE_REPO_ACCESS: ${{ secrets.DOCKER_USER != '' && secrets.DOCKER_PASSWORD != '' }}
      MAIN_VARIANT: java21
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v4.2.2
        with:
          # for build-files step
          fetch-depth: 0

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5.6.1
        with:
          # NOTE for forks: if your Docker Hub organization doesn't match your Github repo's,
          # then the use of ${{ github.repository_owner }} will need to be replaced.
          images: |
            ${{ github.repository_owner }}/minecraft-server
            ghcr.io/${{ github.repository_owner }}/minecraft-server
          tags: |
            # For the "main" variant, it gets the tag as-is, without suffix
            type=ref,event=tag,enable=${{ matrix.variant == env.MAIN_VARIANT }}
            # and each variant (including main one) gets the tag with the variant suffix, such as 2023.1.1-java17
            type=ref,event=tag,suffix=-${{ matrix.variant }}
            # for building test/* branch images
            type=ref,event=branch,suffix=-${{ matrix.variant }},enable=${{ github.ref_name != github.event.repository.default_branch }}
            # latest repo tag gets a moving 'stable' image tag applied to the main variant
            type=raw,value=stable,enable=${{ github.ref_type == 'tag' && matrix.variant == env.MAIN_VARIANT }}            
            # apply the variant as a moving tag for most recent commit per variant
            type=raw,value=${{ matrix.variant }},enable=${{ github.ref_name == github.event.repository.default_branch }}
            # for backward compatibility with users referencing java8-multiarch, this will set an extra label on java8
            type=raw,value=java8-multiarch,enable=${{ matrix.variant == 'java8' && github.ref_name == github.event.repository.default_branch }}
          # NOTE this identifies which variant will be published as "latest", which isn't
          # necessarily the newest version of Java
          flavor: |
            latest=${{ matrix.variant == env.MAIN_VARIANT && github.ref_name == github.event.repository.default_branch }}
          labels: |
            org.opencontainers.image.authors=Geoff Bourne <itzgeoff@gmail.com>

      - name: Setup Docker Buildx
        uses: docker/setup-buildx-action@v3.8.0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3.3.0

      - name: Build for test
        uses: docker/build-push-action@v6.12.0
        with:
          platforms: linux/amd64
          tags: ${{ env.IMAGE_TO_TEST }}
          # ensure latest base image is used
          pull: true
          # load into daemon for test usage in next step
          load: true
          push: false
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
          cache-from: type=gha,scope=${{ matrix.variant }}
          # no cache-to to avoid cross-cache update from next build step

      - name: Run tests
        env:
          MINECRAFT_VERSION: ${{ matrix.mcVersion }}
          VARIANT: ${{ matrix.variant }}
          CF_API_KEY: ${{ secrets.CF_API_KEY }}
        run: |
          tests/test.sh

      - name: Login to DockerHub
        uses: docker/login-action@v3.3.0
        if: env.HAS_IMAGE_REPO_ACCESS
        with:
          username: ${{ secrets.DOCKER_USER }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Login to GHCR
        uses: docker/login-action@v3.3.0
        if: env.HAS_IMAGE_REPO_ACCESS
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ github.token }}

      - name: Build and push
        uses: docker/build-push-action@v6.12.0
        if: github.actor == github.repository_owner
        with:
          platforms: ${{ matrix.platforms }}
          push: >
            ${{ 
            github.ref_type == 'tag' 
            || github.ref_name == github.event.repository.default_branch
            || startsWith(github.ref_name, 'test/')
            || ( github.event_name == 'pull_request' 
                 && env.HAS_IMAGE_REPO_ACCESS 
                 && contains(github.event.pull_request.labels.*.name, 'ci/push-image') 
               )
            }}
          tags: ${{ steps.meta.outputs.tags }}
          # ensure latest base image is used
          pull: true
          labels: ${{ steps.meta.outputs.labels }}
          # Since some consumers, like Watchtower are broken https://github.com/containrrr/watchtower/discussions/1529
          # Also refer to https://github.com/docker/build-push-action/releases/tag/v3.3.0
          provenance: false
          build-args: |
            BASE_IMAGE=${{ matrix.baseImage }}
            BUILD_FILES_REV=${{ steps.build-files-rev.outputs.REV }}
          cache-from: type=gha,scope=${{ matrix.variant }}
          cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
