name: Publish NeoForge mod

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

# Works with the conventional ModDevGradle and NeoGradle MDKs.
# Change these four values. The mod version comes from the tag.
env:
  MOD_NAME: example-mod
  MINECRAFT_VERSION: 1.21.1
  JAVA_VERSION: '21'
  MOD_SIDE: both # both, client, server or either

jobs:
  release:
    runs-on: ubuntu-latest

    steps:
      - name: Check out the tagged source
        uses: actions/checkout@v6

      - name: Set up Java
        uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: ${{ env.JAVA_VERSION }}

      - name: Set up Gradle
        uses: gradle/actions/setup-gradle@v6

      - name: Build with the NeoForge MDK
        run: |
          chmod +x ./gradlew
          ./gradlew build --no-daemon

      - name: Prepare the playable JAR and Modpacks.ch metadata
        shell: bash
        run: |
          set -euo pipefail

          MOD_VERSION="${GITHUB_REF_NAME#v}"
          OUTPUT="${MOD_NAME}-${MINECRAFT_VERSION}-${MOD_VERSION}.jar"

          if [[ ! "${MOD_NAME}" =~ ^[A-Za-z0-9][A-Za-z0-9._-]*$ ]] ||
             [[ ! "${MINECRAFT_VERSION}" =~ ^[A-Za-z0-9][A-Za-z0-9._+-]*$ ]] ||
             [[ ! "${MOD_VERSION}" =~ ^[A-Za-z0-9][A-Za-z0-9._+-]*$ ]]; then
            echo 'MOD_NAME, MINECRAFT_VERSION and the tag must be safe filename values'
            exit 1
          fi

          mapfile -t JARS < <(
            find build/libs -maxdepth 1 -type f -name '*.jar' \
              ! -name '*-sources.jar' \
              ! -name '*-dev.jar' \
              ! -name '*-dev-shadow.jar' \
              ! -name '*-javadoc.jar'
          )

          if [[ "${#JARS[@]}" -ne 1 ]]; then
            printf 'Expected one playable JAR in build/libs, found %s:\n' "${#JARS[@]}"
            printf '  %s\n' "${JARS[@]}"
            exit 1
          fi

          case "${MOD_SIDE}" in
            both) CLIENT=required; SERVER=required ;;
            client) CLIENT=required; SERVER=unsupported ;;
            server) CLIENT=unsupported; SERVER=required ;;
            either) CLIENT=optional; SERVER=optional ;;
            *) echo 'MOD_SIDE must be both, client, server or either'; exit 1 ;;
          esac

          mkdir -p release
          cp "${JARS[0]}" "release/${OUTPUT}"

          jq -n \
            --arg asset "${OUTPUT}" \
            --arg mc "${MINECRAFT_VERSION}" \
            --arg client "${CLIENT}" \
            --arg server "${SERVER}" \
            '{
              "$schema": "https://modpacks.ch/schemas/github-release-v1.json",
              "version": 1,
              "files": [{
                "name": ($asset | sub("\\.jar$"; "")),
                "asset": $asset,
                "targets": {
                  "gameVersions": [$mc],
                  "loaders": ["neoforge"]
                },
                "environment": {
                  "client": $client,
                  "server": $server
                },
                "dependencies": []
              }]
            }' > release/modpacksch-release.json

      - name: Publish the GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
        shell: bash
        run: |
          set -euo pipefail

          if gh release view "${GITHUB_REF_NAME}" >/dev/null 2>&1; then
            gh release upload "${GITHUB_REF_NAME}" \
              release/*.jar \
              release/modpacksch-release.json \
              --clobber
          else
            gh release create "${GITHUB_REF_NAME}" \
              release/*.jar \
              release/modpacksch-release.json \
              --verify-tag \
              --generate-notes \
              --title "${MOD_NAME} ${GITHUB_REF_NAME#v}"
          fi
