# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
name: Build & Test

on:
  push:
  pull_request:

jobs:
  #############################################
  build-win:
    name: Build Windows
    secrets: inherit
    uses: ./.github/workflows/reusable-build.yml
    strategy:
      matrix:
        runtime: [win-x64, win-arm64]
    with:
      platform: windows-latest
      runtime: ${{ matrix.runtime }}

  #############################################
  build-linux:
    name: Build Linux
    secrets: inherit
    uses: ./.github/workflows/reusable-build.yml
    strategy:
      matrix:
        runtime: [linux-x64, linux-arm64, linux-arm]
    with:
      platform: ubuntu-latest
      runtime: ${{ matrix.runtime }}

  #############################################
  build-osx:
    name: Build Mac OS
    secrets: inherit
    uses: ./.github/workflows/reusable-build.yml
    strategy:
      matrix:
        runtime: [osx-x64, osx-arm64]
    with:
      platform: macos-latest
      runtime: ${{ matrix.runtime }}

  #############################################
  # Note: This builds the MUSL zip artifacts but isn't used in the actual docker image build
  build-musl:
    name: Build MUSL
    secrets: inherit
    uses: ./.github/workflows/reusable-build.yml
    strategy:
      matrix:
        runtime: [linux-musl-x64, linux-musl-arm, linux-musl-arm64]
    with:
      platform: ubuntu-latest
      runtime: ${{ matrix.runtime }}
      publish-args: -NoSingleFile
      skip-test: true

  #############################################
  codesign:
    name: Apple Signing
    runs-on: macos-latest
    # non-master branches
    if: |
      github.event_name == 'pull_request' ||
      github.ref == 'refs/heads/master' ||
      startsWith(github.ref, 'refs/tags/v')
    needs: [build-osx]
    strategy:
      matrix:
        runtime:
          - osx-x64
          - osx-arm64
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Download Artifacts
        uses: ./.github/actions/download-tar
        with:
          name: ${{ matrix.runtime }}
          path: publish

      - name: Add Cert to Keychain
        # todo: Switch back to upstream when this is merged:
        # https://github.com/Apple-Actions/import-codesign-certs/pull/58
        uses: recyclarr/import-codesign-certs@master
        with:
          p12-file-base64: ${{ secrets.MAC_CERT_BASE64 }}
          p12-password: ${{ secrets.MAC_CERT_PASSWORD }}

      - name: Code Sign
        env:
          CODESIGN_IDENTITY: ${{ secrets.MAC_CODESIGN_IDENTITY }}
        run: >
          codesign --timestamp --no-strict --force
          --options=runtime
          --entitlements ci/codesign/entitlements.plist
          --sign "$CODESIGN_IDENTITY"
          "publish/recyclarr"

      - name: Notarize
        run: >-
          ci/notarize.sh
          "${{ secrets.MAC_DEV_USERNAME }}"
          "${{ secrets.MAC_DEV_PASSWORD }}"
          AVLRN599D8
          publish/recyclarr

      # Cannot staple directly to a binary:
      # https://developer.apple.com/documentation/security/notarizing_macos_software_before_distribution/customizing_the_notarization_workflow?language=objc#3087720
      # - name: Staple
      #   run: xcrun stapler staple -v publish/recyclarr

      - name: Upload Artifacts
        uses: ./.github/actions/upload-tar
        with:
          name: ${{ matrix.runtime }}
          path: publish

  #############################################
  docker:
    name: Docker
    # Wait on builds only to verify tests pass
    needs: [build-win, build-linux, build-osx, build-musl]
    uses: ./.github/workflows/reusable-docker.yml
    secrets: inherit

  #############################################
  test-artifact-download:
    name: Test Artifact Download
    runs-on: ubuntu-latest
    if: "!startsWith(github.ref, 'refs/tags/v')"
    needs:
      - build-win
      - build-linux
      - codesign # Depends on build-osx
      - docker # Depends on build-musl
    env:
      XZ_OPT: "-T0 -9"
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Download Artifacts
        uses: ./.github/actions/download-tar
        with:
          path: publish

  #############################################
  release:
    name: Release
    runs-on: ubuntu-latest
    if: startsWith(github.ref, 'refs/tags/v')
    needs:
      - build-win
      - build-linux
      - build-musl
      - codesign # Depends on build-osx, and reuploads artifacts after signing
    env:
      XZ_OPT: "-T0 -9"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # avoid shallow clone for GitVersion

      - name: Install GitVersion
        uses: gittools/actions/gitversion/setup@v0
        with:
          versionSpec: 6.x
          includePrerelease: true # Remove this once v6 goes stable

      - name: Determine Version
        uses: gittools/actions/gitversion/execute@v0
        id: gitversion

      - name: Download Artifacts
        uses: ./.github/actions/download-tar
        with:
          path: publish

      - name: Create Archive
        shell: pwsh
        run: >
          ci/CreateArchive.ps1
          -PublishDir publish
          -OutputDir archive

      - name: Extract Changelog
        id: changelog
        uses: ffurrer2/extract-release-notes@v2

      - name: Create Release
        uses: softprops/action-gh-release@v2
        env:
          GITHUB_TOKEN: ${{ secrets.DEPLOY_PAT }}
        with:
          files: |
            archive/**/recyclarr-*.zip
            archive/**/recyclarr-*.tar.xz
          body: ${{ steps.changelog.outputs.release_notes }}
          tag_name: ${{ github.event.create.ref }}
          draft: false
          prerelease: ${{ steps.gitversion.outputs.preReleaseTag != '' }}

  #############################################
  # The main purpose of this job is to group all the other jobs together into one single job status
  # that can be set as a requirement to merge pull requests. This is easier than enumerating all
  # jobs in a workflow to ensure they all pass.
  check:
    if: always()
    name: Report Build Status
    needs:
      - build-win
      - build-linux
      - build-osx
      - build-musl
      - codesign
      - docker
      - release
      - test-artifact-download
    runs-on: ubuntu-latest
    steps:
      - name: Check if all jobs succeeded
        uses: re-actors/alls-green@release/v1
        with:
          allowed-skips: codesign, release, test-artifact-download
          jobs: ${{ toJSON(needs) }}