name: Run Tests
on: [push, pull_request]

concurrency:
  group: build-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        version: [8.6.0-jdk17]
    runs-on: ubuntu-22.04
    container:
      image: gradle:${{ matrix.version }}
      options: --user root
    steps:
      - uses: actions/checkout@v4
      - uses: gradle/wrapper-validation-action@v2
      - run: gradle build check -x test --stacktrace --warning-mode fail
      - uses: Juuxel/publish-checkstyle-report@v1
        if: ${{ failure() }}
        with:
          reports: |
            build/reports/checkstyle/*.xml

  build_windows:
    runs-on: windows-2022
    steps:
      - uses: actions/checkout@v4
      - name: setup jdk
        uses: actions/setup-java@v4
        with:
          java-version: 17
          distribution: 'temurin'
      - uses: gradle/wrapper-validation-action@v2
      - run: ./gradlew build check -x test --stacktrace --warning-mode fail

  # This job is used to feed the test matrix of next job to allow the tests to run in parallel
  prepare_test_matrix:
    # Lets wait to ensure it builds before going running tests
    needs: build

    runs-on: ubuntu-22.04
    container:
      image: gradle:8.6.0-jdk17
      options: --user root

    steps:
      - uses: actions/checkout@v4
      - run: gradle writeActionsTestMatrix --stacktrace --warning-mode fail
      -
        id: set-matrix
        run: echo "matrix=$(cat build/test_matrix.json)" >> $GITHUB_OUTPUT

    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}

  run_tests:
    needs: prepare_test_matrix

    strategy:
      fail-fast: false
      matrix:
        version: [8.6.0-jdk17]
        test: ${{ fromJson(needs.prepare_test_matrix.outputs.matrix) }}

    runs-on: ubuntu-22.04
    container:
      image: gradle:${{ matrix.version }}
      options: --user root

    steps:
      - uses: actions/checkout@v4
      - run: gradle printActionsTestName --name="${{ matrix.test }}" test --tests ${{ matrix.test }} --stacktrace --warning-mode fail
        env:
          TEST_WARNING_MODE: fail
        id: test

      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: ${{ steps.test.outputs.test }} Results
          path: build/reports/
      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: ${{ steps.test.outputs.test }} Heap Dump
          path: "*.hprof"

  run_tests_windows:
    needs: prepare_test_matrix

    strategy:
      fail-fast: false
      matrix:
        java: [17]
        test: ${{ fromJson(needs.prepare_test_matrix.outputs.matrix) }}

    runs-on: windows-2022

    steps:
      - uses: actions/checkout@v4
      - name: setup jdk ${{ matrix.java }}
        uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'
      - run: ./gradlew printActionsTestName --name="${{ matrix.test }}" test --tests ${{ matrix.test }} --stacktrace --warning-mode fail
        env:
          TEST_WARNING_MODE: fail
        id: test

      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: ${{ steps.test.outputs.test }} (${{ matrix.java }}) Results (Windows)
          path: build/reports/
      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: ${{ steps.test.outputs.test }} Heap Dump (Windows)
          path: "*.hprof"

  # Special case this test to run across all os's
  reproducible_build_test:
    needs: build

    strategy:
      fail-fast: false
      matrix:
        java: [ 17, 21 ]
        os: [ windows-2022, ubuntu-22.04, macos-14 ]

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'

      - run: ./gradlew test --tests *ReproducibleBuildTest --stacktrace --warning-mode fail

      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: Reproducible Build ${{ matrix.os }} (${{ matrix.java }}) Results
          path: build/reports/

  # Special case this test to run on Java 21
  neoForge1206Test:
    needs: build

    strategy:
      fail-fast: false
      matrix:
        java: [ 21 ]
        os: [ ubuntu-22.04 ]

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'

      - run: ./gradlew test --tests *NeoForge1206Test --stacktrace --warning-mode fail

      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: NeoForge 1.20.6 Build Results
  # Special case this test to run on Java 21
  forge1206Test:
    needs: build

    strategy:
      fail-fast: false
      matrix:
        java: [ 21 ]
        os: [ ubuntu-22.04 ]

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-java@v4
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'

      - run: ./gradlew test --tests *Forge1206Test --stacktrace --warning-mode fail

      - uses: actions/upload-artifact@v4
        if: ${{ failure() }}
        with:
          name: Forge 1.20.6 Build Results
          path: build/reports/