# Adapted from ripgrep
#
# The way this works is the following:
#
# The create-release job runs purely to initialize the GitHub release itself
# and to output upload_url for the following job.
#
# The build-release job runs only once create-release is finished. It gets the
# release upload URL from create-release job outputs, then builds the release
# executables for each supported platform and attaches them as release assets
# to the previously created release.
#
# The key here is that we create the release only once.
#
# Reference:
# https://eugene-babichenko.github.io/blog/2020/05/09/github-actions-cross-platform-auto-releases/

name: release
on:
  push:
    branches:
    - canary
    tags:
    - "v[0-9]+.[0-9]+.[0-9]+"

permissions:
  contents: write

jobs:
  create-release:
    name: create-release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Get the release version from the tag
        if: env.VERSION == ''
        run: |
          echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
      - name: Show the version
        run: |
          echo "version is: $VERSION"
      - name: Check that tag version and Cargo.toml version are the same
        shell: bash
        if: env.VERSION != 'canary'
        run: |
          if ! grep -q "version = \"${VERSION#v}\"" Cargo.toml; then
            echo "version does not match Cargo.toml" >&2
            exit 1
          fi
      - name: Create GitHub canary release
        if: env.VERSION == 'canary'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release create $VERSION --draft --prerelease --title $VERSION

      - name: Create GitHub release
        if: env.VERSION != 'canary'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release create $VERSION --draft --verify-tag --title $VERSION
    outputs:
      version: ${{ env.VERSION }}

  build-release:
    name: build-release
    needs: ['create-release']
    runs-on: ${{ matrix.os }}
    env:
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
    strategy:
      fail-fast: false
      matrix:
        build: [linux, linux-musl, macos, win-msvc]
        include:
        - build: linux
          os: ubuntu-latest
          target: x86_64-unknown-linux-gnu
        - build: linux-musl
          os: ubuntu-latest
          target: x86_64-unknown-linux-musl
        - build: macos
          os: macos-latest
          target: x86_64-apple-darwin
        - build: macos-aarch
          os: macos-latest
          target: aarch64-apple-darwin
        - build: win-msvc
          os: windows-latest
          target: x86_64-pc-windows-msvc

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
      with:
        fetch-depth: 1
        ref: ${{ env.RELEASE_VERSION }}

    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: stable
        target: ${{ matrix.target }}

    - name: Build release binary
      shell: bash
      run: |
        cargo build --verbose --release --target ${{ matrix.target }}
        if [ "${{ matrix.os }}" = "windows-latest" ]; then
          bin="target/${{ matrix.target }}/release/prose.exe"
        else
          bin="target/${{ matrix.target }}/release/prose"
        fi
        [ -e "$bin" ] || echo "Uh oh, $bin does not exist" >&2
        echo "BIN=$bin" >> $GITHUB_ENV

    - name: Strip release binary (linux and macos)
      if: matrix.build == 'linux' || matrix.build == 'linux-musl' || matrix.build == 'macos'
      run: strip "$BIN"

    - name: Determine archive name
      shell: bash
      run: |
        version="${{ needs.create-release.outputs.version }}"
        echo "ARCHIVE=prose-$version-${{ matrix.target }}" >> $GITHUB_ENV

    - name: Creating directory for archive
      shell: bash
      run: |
        mkdir -p "$ARCHIVE"
        cp {README.md,CODE_OF_CONDUCT.md,LICENSE-APACHE,LICENSE-MIT} "$ARCHIVE/"
        cp "$BIN" "$ARCHIVE"/

    - name: Build archive (Windows)
      shell: bash
      if: matrix.os == 'windows-latest'
      run: |
        7z a "$ARCHIVE.zip" "$ARCHIVE"
        certutil -hashfile "$ARCHIVE.zip" SHA256 > "$ARCHIVE.zip.sha256"
        echo "ASSET=$ARCHIVE.zip" >> $GITHUB_ENV
        echo "ASSET_SUM=$ARCHIVE.zip.sha256" >> $GITHUB_ENV

    - name: Build archive (Unix)
      shell: bash
      if: matrix.os != 'windows-latest'
      run: |
        tar czf "$ARCHIVE.tar.gz" "$ARCHIVE"
        shasum -a 256 "$ARCHIVE.tar.gz" > "$ARCHIVE.tar.gz.sha256"
        echo "ASSET=$ARCHIVE.tar.gz" >> $GITHUB_ENV
        echo "ASSET_SUM=$ARCHIVE.tar.gz.sha256" >> $GITHUB_ENV

    - name: Upload release archive
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        version="${{ needs.create-release.outputs.version }}"
        gh release upload "$version" ${{ env.ASSET }} ${{ env.ASSET_SUM }}
