name: CI

on:
#  create:
#  pull_request:
#    types: [ opened, synchronize, reopened ]
#    paths-ignore:
#      - '*.md'
#      - 'docs/**'
#  push:
#    branches:
#      - master
#    paths-ignore:
#      - '*.md'
#      - 'docs/**'
  workflow_dispatch:

defaults:
  run:
    shell: bash

jobs:
  workflow_config:
    runs-on: ubuntu-latest
    outputs:
      do_release: ${{ steps.config.outputs.do_release }}
      do_snapshot_release: ${{ steps.config.outputs.do_snapshot_release }}
      pom_version: ${{ steps.config.outputs.pom_version }}
    steps:
      - name: Configure workflow
        id: config
        env:
          ACTOR: ${{ github.actor }}
          EVENT_ACTION: ${{ github.event.action }}
          REF_TYPE: ${{ github.event.ref_type }}
          REF: ${{ github.event.ref }}
        run: |
          cat <<-EOF
            ::group::Debug Info
            GITHUB_EVENT_NAME       : '${GITHUB_EVENT_NAME}'
            EVENT_ACTION            : '${EVENT_ACTION}'
            REF_TYPE                : '${REF_TYPE}'
            REF                     : '${REF}'
            ACTOR                   : '${ACTOR}'
            GITHUB_REPOSITORY_OWNER : '${GITHUB_REPOSITORY_OWNER}'
            ::endgroup::
          EOF

          # Do a release when a git tag starting with 'v' has been created by a suitable user.
          # (We match against github.repository_owner as a kludge so that forked repos can release themselves when testing the workflow)

          if [[ "${GITHUB_EVENT_NAME}" == "create" && "${REF_TYPE}" == "tag" && "${REF}" == v* && \
                ( "${ACTOR}" == "arnaudroques" || "${ACTOR}" == "${GITHUB_REPOSITORY_OWNER}" ) \
             ]]; then
            echo "::notice title=::This run will release '${REF}'"
            echo "::set-output name=do_release::true"
            echo "::set-output name=pom_version::${REF#v}"  # pom_version is the tag without the 'v' prefix

          elif [[ "${GITHUB_EVENT_NAME}" =~ push|workflow_dispatch && "${REF}" == "refs/heads/master" ]]; then
            echo "::notice title=::This run will release a snapshot"
            echo "::set-output name=do_snapshot_release::true"

          else
            echo "This run will NOT make a release"
          fi

  # We run the tests on many OS / Java combinations but also the Compile step because some users build
  # their own jars from source, so it is good for CI to check that is working on all combinations.
  build:
    needs: workflow_config
    strategy:
      fail-fast: false
      matrix:
        java_version: [ 8, 11, 17 ]
        os: [ macos-10.15,  macos-11, ubuntu-18.04, ubuntu-20.04, windows-2019, windows-2022 ]
        include:
          - release_from_this_build: true
            os: ubuntu-20.04
            java_version: 8
    runs-on: ${{ matrix.os }}
    env:
      SIGN_ARTIFACTS: ${{ secrets.ARTIFACT_SIGNING_KEY != '' }}
    steps:
      - name: Checkout the repository
        uses: actions/checkout@v2

      - name: Set up java
        uses: actions/setup-java@v2.5.0
        with:
          java-version: ${{ matrix.java_version }}
          distribution: temurin
          cache: maven

      # Downloading all the dependencies is very log spammy, so we do this in its own step.
      - name: Prime maven cache
        run: mvn --batch-mode dependency:go-offline

      # POM version is usually a -SNAPSHOT at this point, if this is a release then we use the version derived from the tag
      - name: Set POM version
        if: needs.workflow_config.outputs.do_release == 'true'
        env:
          POM_VERSION: ${{ needs.workflow_config.outputs.pom_version }}
        run: mvn --batch-mode versions:set "-DnewVersion=${POM_VERSION}"

      # Compile / Test / Package are separate steps so the reason for any failure is more obvious in GitHub UI
      - name: Compile
        run: mvn --batch-mode compile

      - name: Test
        run: mvn --batch-mode test

      # The repeated "matrix.release_from_this_build" checks are messy, but I have not found a simple way to avoid them
      # See https://github.com/actions/runner/issues/662

      - name: Setup gpg
        if: matrix.release_from_this_build && env.ARTIFACT_SIGNING_KEY
        id: gpg
        env:
          ARTIFACT_SIGNING_KEY: ${{ secrets.ARTIFACT_SIGNING_KEY }}
        run: |
          echo "Importing key ..."
          echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --import --import-options import-show

          echo "Getting key id ..."
          key_id="$(echo "${ARTIFACT_SIGNING_KEY}" | gpg --batch --show-keys --with-colons | awk -F: '$1 == "sec" { print $5 }')"
          echo "::set-output name=key_id::${key_id}"

      - name: Create artifacts
        if: matrix.release_from_this_build
        env:
          GPG_KEYNAME: ${{ steps.gpg.outputs.key_id }}
          GPG_PASSPHRASE: ${{ secrets.ARTIFACT_SIGNING_PASSPHRASE }}
        run: |
          [[ "${SIGN_ARTIFACTS}" == "true" ]] || cp pom.xml target/plantuml.pom

          mvn --batch-mode \
            "-DfinalName=plantuml" \
            "-Dgpg.keyname=${GPG_KEYNAME}" \
            "-Dgpg.passphrase=${GPG_PASSPHRASE}" \
            "-Dmaven.test.skip=true" \
            verify

      - name: Upload artifacts
        if: matrix.release_from_this_build
        uses: actions/upload-artifact@v2
        with:
          # Using github.run_number here to reduce confusion when downloading & comparing artifacts from several builds
          name: ${{ github.run_number }}-artifacts
          path: |
            target/*.asc
            target/*.jar
            target/*.pom

  release:
    needs: [ workflow_config, build ]
    if: needs.workflow_config.outputs.do_release == 'true' || needs.workflow_config.outputs.do_snapshot_release == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the repository
        uses: actions/checkout@v2

      - name: Download artifacts
        uses: actions/download-artifact@v2
        with:
          name: ${{ github.run_number }}-artifacts
          path: target

      - name: Create snapshot release
        if: needs.workflow_config.outputs.do_snapshot_release == 'true'
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: .github/scripts/release_snapshot.sh

      - name: Create release in GitHub
        if: needs.workflow_config.outputs.do_release == 'true'
        env:
          GITHUB_TOKEN: ${{ github.token }}
          POM_VERSION: ${{ needs.workflow_config.outputs.pom_version }}
          TAG: ${{ github.event.ref }}
        run: .github/scripts/release.sh
