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

name: Changelog

on:
  push:
    branches:
      - develop
    tags:
      - 'v*'

jobs:
  generate:
    if: >
      ! contains(github.event.head_commit.message, '[ci skip]') &&
      ! (
        startsWith(github.event.head_commit.message, 'Increment version to v') &&
        startsWith(github.ref, 'refs/heads/')
      )
    runs-on: ubuntu-latest

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

      - name: Check branch for new commits, and env vars
        run: |
          echo "::group::git fetch origin --tags --force"
          git fetch origin --tags --force
          echo "::endgroup::"

          TAG_REGEX='include-all'
          echo "::debug::GITHUB_REF: $GITHUB_REF"
          BRANCH="${GITHUB_REF##*/}"

          if [[ $GITHUB_REF =~ ^refs/tags/ ]]; then
            # This is a tag build (i.e. a release)
            echo '::debug::Release build'
            if [[ ! $BRANCH =~ ^v[0-9]+(\.[0-9]+){1,2}(-(alpha|beta)([0-9]+)?)?$ ]]; then
              echo "::error::Invalid tag format: ${BRANCH}"
              exit 1
            fi

            RELEASE=1
            BRANCH=develop
            git checkout $BRANCH

            # if actual release (not pre), then changelog should exclude prereleases on update
            prerelease_regex='(alpha|beta)'
            if [[ ! ${GITHUB_REF##*/} =~ $prerelease_regex ]]; then
              echo '::debug::Actual release (not a prerelease)'
              TAG_REGEX="$prerelease_regex"
              echo "FULL_RELEASE=true" >> "$GITHUB_ENV"
            fi
          fi
          echo "::debug::TAG_REGEX: $TAG_REGEX"

          if [[ "$(git rev-parse "origin/$BRANCH")" != "$GITHUB_SHA" ]]; then
            # Normal build on a branch (no tag)
            echo "::debug::BRANCH: $BRANCH $(git rev-parse "origin/$BRANCH")"
            echo "::debug::GITHUB_SHA: $GITHUB_SHA"
            echo "::error::$BRANCH has been updated since build started. Aborting changelog."
            exit 1
          fi

          SINCE_TAG=$(git tag --sort=-creatordate | grep -Ev "$TAG_REGEX" | awk "NR==$(( 1 + ${RELEASE:-0} ))")

          echo "::debug::BRANCH: $BRANCH"
          echo "::debug::TAG_REGEX: $TAG_REGEX"
          echo "::debug::FILENAME: CHANGELOG.md"
          echo "::debug::SINCE_TAG: $SINCE_TAG"

          {
          echo "BRANCH=$BRANCH"
          echo "TAG_REGEX=$TAG_REGEX"
          echo "FILENAME=CHANGELOG.md"
          echo "SINCE_TAG=$SINCE_TAG"
          } >> "$GITHUB_ENV"

      - name: Prep changelog file (clear out old lines)
        run: |
          # delete the top of the changelog up to the correct tag
          tagline=$(grep -n "^## \[${SINCE_TAG}\]" "$FILENAME" | awk '{print $1}' FS=':' | head -1)
          echo "tagline: ${tagline}"

          if [[ -z $tagline ]]; then
            echo "::error::Something is wrong. ${SINCE_TAG} isn't in the changelog."
            exit 1
          fi

          if [[ $tagline == 1 ]]; then
            echo "::error::Something is wrong."
            echo "::error::The latest release ${SINCE_TAG} is the first line in the changelog,"
            echo "::error::but the h1 '# Changelog' should always be the first line."
            exit 1
          fi

          sed -i "1,$(( tagline - 1 ))d" "$FILENAME"
          # delete generated line (or it will be added multiple times)
          sed -i '/This Changelog was automatically generated by/d' "$FILENAME"
          # delete trailing empty lines
          sed -i -e :a -e '/^\n*$/{$d;N;};/\n$/ba' "$FILENAME"

      - name: Generate changelog
        uses: heinrichreimer/action-github-changelog-generator@v2.1.1
        with:
          # see: https://github.com/heinrichreimer/action-github-changelog-generator
          repo: jrnl-org/jrnl
          token: ${{ secrets.JRNL_BOT_TOKEN }}
          base: CHANGELOG.md
          addSections: '{"build":{"prefix":"**Build:**","labels":["build"]},"docs":{"prefix":"**Documentation:**","labels":["documentation"]},"packaging":{"prefix":"**Packaging:**","labels":["packaging"]}}'
          issues: true
          pullRequests: true
          issuesWoLabels: false
          unreleased: true
          compareLink: true
          includeLabels: bug,enhancement,documentation,build,packaging,deprecated
          excludeLabels: stale,wontfix
          excludeTagsRegex: ${{ env.TAG_REGEX }}
          sinceTag: ${{ env.SINCE_TAG }}
          maxIssues: 150
          releaseUrl: https://pypi.org/project/jrnl/%s/
          releaseBranch: develop
          verbose: false
          author: true

      - name: Small fixes
        run: |
          # Change unreleased link to correct url
          sed -i 's!https://pypi.org/project/jrnl/HEAD/!https://github.com/jrnl-org/jrnl/!' "$FILENAME"

      - name: Diff and consistency check
        run: |
          git diff
          if [[ $(grep -c '^# Changelog$' "$FILENAME") != 1 ]]; then
            echo '::error::Something is wrong with the changelog.'
            exit 1
          fi
          SOMETHING_CHANGED=false
          git diff --exit-code || SOMETHING_CHANGED=true
          echo "::debug::SOMETHING_CHANGED: $SOMETHING_CHANGED"
          echo "SOMETHING_CHANGED=$SOMETHING_CHANGED" >> "$GITHUB_ENV"

      - name: Commit
        if: env.SOMETHING_CHANGED == 'true'
        run: |
          git config --global user.name "${{ secrets.JRNL_BOT_NAME }}"
          git config --global user.email "${{ secrets.JRNL_BOT_EMAIL }}"
          git add "$FILENAME"
          git commit -m "Update changelog [ci skip]"
          git push origin "$BRANCH"

      - name: Update tag to include changelog
        if: startsWith(env.GITHUB_REF, 'refs/tags/')
        run: |
          # This is a tag build (releases and prereleases)
          # update the tag to include the changelog
          git tag -fam "$GITHUB_REF_NAME" "$GITHUB_REF_NAME"
          git push --tags --force

      - name: Merge to Release branch
        if: env.FULL_RELEASE == 'true'
        run: |
          git fetch --unshallow origin
          git checkout release
          git merge --ff-only "$BRANCH"
          git push origin release

