# Copyright © 2012-2023 jrnl contributors
# License: https://www.gnu.org/licenses/gpl-3.0.html

name: Release
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version (e.g. v2.5, v2.5.1-beta, v2.6-beta2)'
        type: string
        required: true
      include_repo_version:
        description: 'Update version in repo?'
        type: boolean
        required: true
        default: true
      include_pypi:
        description: 'Publish to PyPI?'
        type: boolean
        required: true
        default: true
      include_brew:
        description: 'Publish to Homebrew?'
        type: boolean
        required: true
        default: true

jobs:
  validate:
    name: "Validate version string"
    runs-on: ubuntu-latest
    steps:
    - name: Validate version
      run: |
        JRNL_VERSION="${{ github.event.inputs.version }}"
        echo "::debug::version: $JRNL_VERSION"
        if [[ ! $JRNL_VERSION =~ ^v[0-9]+(\.[0-9]+){1,2}(-(alpha|beta)([0-9]+)?)?$ ]]; then
          echo
          echo "::error::Bad version"
          echo
          echo "Version string should match pattern above."
          echo "Here are some examples of valid version numbers:"
          echo
          echo "  v2.5"
          echo "  v2.5-alpha"
          echo "  v2.5-beta"
          echo "  v2.5.1"
          echo "  v2.5.1-alpha"
          echo "  v2.5.1-beta"
          exit 1
        fi

  release_pypi:
    needs: validate
    name: "Release to PyPI"
    runs-on: ubuntu-latest
    outputs:
      pypi_version: ${{ steps.pypi-version-getter.outputs.pypi_version }}
    env:
      HOME_REPO: ${{ secrets.HOME_REPO }}
    steps:
    - name: Get version
      run: |
        JRNL_VERSION="${{ github.event.inputs.version }}"
        echo "::debug::version: $JRNL_VERSION"
        echo "JRNL_VERSION=$JRNL_VERSION" >> "$GITHUB_ENV"

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: '3.12'

    - name: Checkout repo
      uses: actions/checkout@v4
      with:
        token: ${{ secrets.JRNL_BOT_TOKEN }}

    - name: Config git user
      run: |
        git config --global user.name "${{ secrets.JRNL_BOT_NAME }}"
        git config --global user.email "${{ secrets.JRNL_BOT_EMAIL }}"

    - name: Install dependencies
      run: pip install poetry

    - name: Update version in files
      if: ${{ github.event.inputs.include_repo_version == 'true' }}
      run: |
        poetry version "$JRNL_VERSION"
        echo "__version__ = \"$JRNL_VERSION\"" > jrnl/__version__.py

    - name: Commit updated files
      if: ${{ github.event.inputs.include_repo_version == 'true' && github.repository == env.HOME_REPO }}
      run: |
        git add pyproject.toml jrnl/__version__.py
        git commit -m "Increment version to ${JRNL_VERSION}"
        git tag -a -m "$JRNL_VERSION" "$JRNL_VERSION"
        git push
        git push --tags

    - name: Build
      run: poetry build

    - name: Deploy to PyPI
      if: ${{ github.event.inputs.include_pypi == 'true' && github.repository == env.HOME_REPO }}
      env:
        POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
      run: poetry publish

    - name: Get PyPI version
      id: pypi-version-getter
      run: |
        pypi_version="$(find dist/jrnl-*.tar.gz | sed -r 's!dist/jrnl-(.*)\.tar\.gz!\1!')"
        echo "pypi_version=$pypi_version" >> "$GITHUB_OUTPUT"

  release_homebrew:
    if: ${{ github.event.inputs.include_brew == 'true' }}
    needs: release_pypi
    name: "Release to Homebrew"
    runs-on: macos-latest
    env:
      HOMEBREW_NO_AUTO_UPDATE: 1
      HOMEBREW_NO_INSTALL_CLEANUP: 1
      HOME_REPO: ${{ secrets.HOME_REPO }}
    steps:
    - name: Get version
      run: |
        JRNL_VERSION="${{ github.event.inputs.version }}"
        PYPI_VERSION="${{ needs.release_pypi.outputs.pypi_version }}"

        echo "::debug::jrnl version: $JRNL_VERSION"
        echo "::debug::pypi version: $PYPI_VERSION"

        echo "JRNL_VERSION=$JRNL_VERSION" >> "$GITHUB_ENV"
        echo "PYPI_VERSION=$PYPI_VERSION" >> "$GITHUB_ENV"

    - name: Set env variables
      env:
        REPO_OWNER: ${{ github.repository_owner }}
      run: |
        if [[ $JRNL_VERSION =~ (alpha|beta) ]]; then
          echo '::debug::Prerelease (not a full release)'
          {
            echo "RELEASE_TYPE=pre"
            echo "FORMULA_REPO=${REPO_OWNER}/homebrew-prerelease"
            echo "BOT_REPO=jrnl-bot/homebrew-prerelease"
            echo "FORMULA_NAME=jrnl-beta"
          } >> "$GITHUB_ENV"
        else
          echo '::debug::Full release (not a prerelease)'
          if [[ "${{ github.repository }}" == "${HOME_REPO}" ]]; then
            REPO_OWNER="homebrew"
          fi
          {
            echo "RELEASE_TYPE=full"
            echo "FORMULA_REPO=${REPO_OWNER}/homebrew-core"
            echo "BOT_REPO=jrnl-bot/homebrew-core"
            echo "FORMULA_NAME=jrnl"
          } >> "$GITHUB_ENV"
        fi

    - name: Tap formula
      run: |
        brew tap "${FORMULA_REPO}"
        echo '::debug::Set tap directory'
        echo "BREW_TAP_DIRECTORY=$(brew --repo "${FORMULA_REPO}")" >> "$GITHUB_ENV"
    - name: Install dependencies
      run: brew install pipgrip

    - name: Query PyPI API
      uses: nick-invision/retry@v3
      with:
        timeout_seconds: 10
        max_attempts: 30
        retry_wait_seconds: 10
        command: |
          curl -Ls https://pypi.org/pypi/jrnl/json > api_response.json
          # if query doesn't have our version yet, give it some time before trying again
          if [[ "null" == "$(jq ".releases[\"${PYPI_VERSION}\"][1].url" -r api_response.json)" ]]; then
            echo "::debug::PYPI_VERSION: $PYPI_VERSION"
            echo "::debug::JQ VALUE: $(jq ".releases[\"${PYPI_VERSION}\"][1].url" -r api_response.json)"
            echo "::group::cat api_response.json"
            cat api_response.json
            echo "::endgroup::"
            exit 1
          fi

    - name: Update Homebrew Formula
      uses: nick-invision/retry@v3
      with:
        timeout_minutes: 8
        max_attempts: 6
        retry_wait_seconds: 30
        command: >
          brew bump-formula-pr "${FORMULA_NAME}"
          --url $(jq ".releases[\"${PYPI_VERSION}\"][1].url" -r api_response.json)
          --sha256 $(jq ".releases[\"${PYPI_VERSION}\"][1].digests.sha256" -r api_response.json)
          --no-audit
          --write-only
          --force

    - name: Create Pull Request
      uses: peter-evans/create-pull-request@v6
      with:
        path: ${{ env.BREW_TAP_DIRECTORY }}
        token: ${{ secrets.JRNL_BOT_TOKEN }}
        push-to-fork: ${{ env.BOT_REPO }}

        committer: ${{ secrets.JRNL_BOT_NAME }} <${{ secrets.JRNL_BOT_EMAIL }}>
        author: ${{ secrets.JRNL_BOT_NAME }} <${{ secrets.JRNL_BOT_EMAIL }}>

        title: jrnl ${{ env.JRNL_VERSION }}
        body: Created with `brew bump-formula-pr`

        branch: jrnl-${{ env.JRNL_VERSION }}--
        branch-suffix: random
        commit-message: |
          jrnl ${{ env.JRNL_VERSION }}

          Update jrnl to ${{ env.JRNL_VERSION }}

          ${{ secrets.RELEASE_COAUTHORS }}
