name: CI
on:
  pull_request:
    branches: ['**']
  push:
    branches: ['**']
    tags: [v*]
env:
  # .sbtopts specifies 8g, which is needed to import into IntelliJ, but on GH that exceeds the maximum available memory
  SBT_JAVA_OPTS: -J-Xms4g -J-Xmx4g
jobs:
  ci:
    # run on external PRs, but not on internal PRs since those will be run by push to branch
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: false
      matrix:
        scala-version: [ "2.12", "2.13", "3" ]
        target-platform: [ "JVM", "JS", "Native" ]
        java: [ "11", "21" ]
        exclude:
          - java: "21"
          - scala-version: "2.12"
            target-platform: "Native"
          - scala-version: "2.13"
            target-platform: "Native"
        include: # Restricted to build only specific Loom-based modules
          - scala-version: "2.13"
            target-platform: "JVM"
            java: "21"
          - scala-version: "3"
            target-platform: "JVM"
            java: "21"
    steps:
    - name: Checkout
      uses: actions/checkout@v3
    - name: Set up JDK 
      uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        cache: 'sbt'
        java-version: ${{ matrix.java }}
    - name: Install sam cli
      if: matrix.java == '11'
      run: |
        wget -q https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip
        unzip -q aws-sam-cli-linux-x86_64.zip -d sam-installation
        sudo ./sam-installation/install --update
        sam --version
    - name: Install NPM
      if: matrix.java == '11'
      uses: actions/setup-node@v4
      with:
        node-version: 18
    - run: npm --version
    - name: Install AWS CDK
      if: matrix.java == '11'
      run: |
        npm install -g aws-cdk
        cdk --version
    - name: Install libidn2-dev libcurl3-dev
      if: matrix.target-platform == 'Native'
      run: |
        sudo apt-get update
        sudo apt-get install libidn2-dev libcurl3-dev
        echo "STTP_NATIVE=1" >> $GITHUB_ENV
    - name: Enable Loom-specific modules
      if: matrix.java == '21'
      run: echo "ONLY_LOOM=1" >> $GITHUB_ENV
    - name: Compile
      run: sbt $SBT_JAVA_OPTS -v "compileScoped ${{ matrix.scala-version }} ${{ matrix.target-platform }}"
    - name: Compile documentation
      if: matrix.target-platform == 'JVM' && matrix.java == '11'
      run: sbt $SBT_JAVA_OPTS -v compileDocumentation
    - name: Test
      if: matrix.target-platform != 'JS'
      uses: nick-fields/retry@v2
      with:
        timeout_minutes: 45
        max_attempts: 3
        command: sbt $SBT_JAVA_OPTS -v "testScoped ${{ matrix.scala-version }} ${{ matrix.target-platform }}"
    # The finatra tests take a really long time (1/3 of the build duration); hence, they are disabled and need to be run separately
    #- name: Test finatra
    #  if: matrix.target-platform != 'JS'
    #  run: sbt $SBT_JAVA_OPTS -v testFinatra
    # Temporarily call JS tests for each subproject explicitly as a workaround until
    # https://github.com/scala-js/scala-js/issues/4317 has a solution
    - name: Test
      if: matrix.target-platform == 'JS' && matrix.scala-version == '2.12'
      run: sbt $SBT_JAVA_OPTS catsJS2_12/test circeJsonJS2_12/test clientCoreJS2_12/test clientTestsJS2_12/test coreJS2_12/test enumeratumJS2_12/test jsoniterScalaJS2_12/test newtypeJS2_12/test openapiDocsJS2_12/test playJsonJS2_12/test redocJS2_12/test serverCoreJS2_12/test sttpClientJS2_12/test testingJS2_12/test testsJS2_12/test uPickleJsonJS2_12/test zio1JsonJS2_12/test zioJsonJS2_12/test
    - name: Test
      if: matrix.target-platform == 'JS' && matrix.scala-version == '2.13'
      run: sbt $SBT_JAVA_OPTS catsJS/test circeJsonJS/test clientCoreJS/test clientTestsJS/test coreJS/test enumeratumJS/test jsoniterScalaJS/test newtypeJS/test openapiDocsJS/test playJsonJS/test redocJS/test serverCoreJS/test sttpClientJS/test testingJS/test testsJS/test uPickleJsonJS/test zio1JsonJS/test zioJsonJS/test
    - name: Test
      if: matrix.target-platform == 'JS' && matrix.scala-version == '3'
      run: sbt $SBT_JAVA_OPTS catsJS3/test circeJsonJS3/test clientCoreJS3/test clientTestsJS3/test coreJS3/test jsoniterScalaJS3/test openapiDocsJS3/test redocJS3/test serverCoreJS3/test sttpClientJS3/test testingJS3/test testsJS3/test uPickleJsonJS3/test zioJsonJS3/test
    - name: Prepare release notes
      uses: release-drafter/release-drafter@v5
      with:
        config-name: release-drafter.yml
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  mima:
    # run on external PRs, but not on internal PRs since those will be run by push to branch
    if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
    runs-on: ubuntu-22.04
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0 # checkout tags so that dynver works properly (we need the version for MiMa)
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: 11
          cache: 'sbt'
      - name: Check MiMa
        run: sbt $SBT_JAVA_OPTS -v mimaReportBinaryIssues

  publish:
    name: Publish release
    needs: [ci]
    if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v'))
    runs-on: ubuntu-22.04
    strategy:
      matrix: 
        java: [ "11", "21" ]
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up JDK
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: ${{ matrix.java }}
          cache: 'sbt'
      - name: Install libidn2-dev libcurl3-dev
        if: matrix.java == '11'
        run: |
          sudo apt-get update
          sudo apt-get install libidn2-dev libcurl3-dev
      - name: Enable Native-specific modules
        if: matrix.java == '11'
        run: echo "STTP_NATIVE=1" >> $GITHUB_ENV
      - name: Enable Loom-specific modules
        if: matrix.java == '21'
        run: echo "ONLY_LOOM=1" >> $GITHUB_ENV
      - name: Compile
        run: sbt $SBT_JAVA_OPTS compile
      - name: Publish artifacts
        run: sbt $SBT_JAVA_OPTS ci-release
        env:
          PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }}
          PGP_SECRET: ${{ secrets.PGP_SECRET }}
          SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
          SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
      - name: Extract version from commit message
        if: matrix.java == '11'
        run: |
          version=${GITHUB_REF/refs\/tags\/v/}
          echo "VERSION=$version" >> $GITHUB_ENV
        env:
          COMMIT_MSG: ${{ github.event.head_commit.message }}
      - name: Publish release notes
        if: matrix.java == '11'
        uses: release-drafter/release-drafter@v5
        with:
          config-name: release-drafter.yml
          publish: true
          name: "v${{ env.VERSION }}"
          tag: "v${{ env.VERSION }}"
          version: "v${{ env.VERSION }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}