name: Build and Publish
on:
  push:
    branches:
      - master
      - test/**
    tags:
      - "[0-9]+.[0-9]+.[0-9]+"
    paths-ignore:
      - "*.md"
      - "docs/**"
      - "examples/**"
      - "notes/**"
      - "kustomize/**"
      - "docker-compose.yml"
      - "images.json"
      - "compose-docs.yml"
      - "zensical.toml"
      - ".readthedocs.yaml"
      - "renovate.json5"

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        # NOTE: the "latest" variant is identified in the Docker meta step's 'latest' config
        variant:
          - java25
          - java25-alpine
          - java25-jdk
          - java21
          - java21-alpine
          - java21-jdk
          - java17
          - java16
          - java11
          - java8
          - java8-jdk
        include:
        # JAVA 25
          - variant: java25
            baseImage: eclipse-temurin:25-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java25-alpine
            baseImage: eclipse-temurin:25-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
          - variant: java25-jdk
            baseImage: eclipse-temurin:25
            platforms: linux/amd64,linux/arm64
            mcVersion: latest
        # JAVA 21:
          - variant: java21
            baseImage: eclipse-temurin:21-jre
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.21.11
          - variant: java21-jdk
            baseImage: eclipse-temurin:21
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.21.11
          - variant: java21-alpine
            baseImage: eclipse-temurin:21-jre-alpine
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.21.11
        # 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
        # JAVA 16
          - variant: java16
            baseImage: adoptopenjdk:16-jre-hotspot
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.16.5
        # JAVA 11
          - variant: java11
            baseImage: adoptopenjdk:11-jre-hotspot
            platforms: linux/amd64,linux/arm/v7,linux/arm64
            mcVersion: 1.16.4
        # 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
            # Pin version for Java 8
            mcHelperVersion: 1.51.2
          - variant: java8-jdk
            baseImage: eclipse-temurin:8u312-b07-jdk-focal
            platforms: linux/amd64,linux/arm64
            mcVersion: 1.12.2
            # Pin version for Java 8
            mcHelperVersion: 1.51.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: java25
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v6.0.2
        with:
          # for build-files step
          fetch-depth: 0

      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v6.0.0
        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: |
            # 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 the "main" variant, it gets the tag as-is
            type=pep440,pattern={{version}},enable=${{ matrix.variant == env.MAIN_VARIANT }}
            # ...and all variants (including main one) get the tag with the variant suffix, such as 2023.1.1-java17
            type=pep440,pattern={{version}},suffix=-${{ matrix.variant }}
            # latest tag gets a moving 'stable' image tag applied to the main variant
            type=pep440,pattern=stable,enable=${{ matrix.variant == env.MAIN_VARIANT }}
            # ...and qualified stable for all variants
            type=pep440,pattern=stable,suffix=-${{ matrix.variant }}
            # for building test/* branch images
            type=ref,event=branch,suffix=-${{ 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@v4.0.0

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v4.0.0

      - name: Build for test
        uses: docker/build-push-action@v7.1.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 }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          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 }}
          GH_TOKEN: ${{ github.token }}
        run: |
          tests/test.sh

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

      - name: Login to GHCR
        uses: docker/login-action@v4.1.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@v7.1.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 }}
            BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
            VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
            REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
            ${{ matrix.mcHelperVersion && format('MC_HELPER_VERSION={0}', matrix.mcHelperVersion) }}
          cache-from: type=gha,scope=${{ matrix.variant }}
          cache-to: type=gha,mode=max,scope=${{ matrix.variant }}
