name: Continuous Delivery

on:
  push:
    branches:
      - main

# default: least privileged permissions across all jobs
permissions:
  contents: read



jobs:
  release:
    runs-on: ubuntu-latest
    concurrency:
      group: ${{ github.workflow }}-release-${{ github.ref_name }}
      cancel-in-progress: false

    permissions:
      contents: write

    steps:
      # Note: We checkout the repository at the branch that triggered the workflow
      # with the entire history to ensure to match PSR's release branch detection
      # and history evaluation.
      # However, we forcefully reset the branch to the workflow sha because it is
      # possible that the branch was updated while the workflow was running. This
      # prevents accidentally releasing un-evaluated changes.
      - name: Setup | Checkout Repository on Release Branch
        uses: actions/checkout@v4
        with:
          ref: ${{ github.ref_name }}
          fetch-depth: 0
          ssh-key: ${{ secrets.CI_DEPLOY_SSH_KEY }}
          ssh-known-hosts: ${{ secrets.CI_DEPLOY_SSH_KNOWN_HOSTS }}

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

      - name: Setup | Force release branch to be at workflow sha
        run: |
          git reset --hard ${{ github.sha }}
      - name: Evaluate | Verify upstream has NOT changed
        # Last chance to abort before causing an error as another PR/push was applied to
        # the upstream branch while this workflow was running. This is important
        # because we are committing a version change (--commit). You may omit this step
        # if you have 'commit: false' in your configuration.
        #
        # You may consider moving this to a repo script and call it from this step instead
        # of writing it in-line.
        shell: bash
        run: |
          set +o pipefail

          UPSTREAM_BRANCH_NAME="$(git status -sb | head -n 1 | cut -d' ' -f2 | grep -E '\.{3}' | cut -d'.' -f4)"
          printf '%s\n' "Upstream branch name: $UPSTREAM_BRANCH_NAME"

          set -o pipefail

          if [ -z "$UPSTREAM_BRANCH_NAME" ]; then
              printf >&2 '%s\n' "::error::Unable to determine upstream branch name!"
              exit 1
          fi

          git fetch "${UPSTREAM_BRANCH_NAME%%/*}"

          if ! UPSTREAM_SHA="$(git rev-parse "$UPSTREAM_BRANCH_NAME")"; then
              printf >&2 '%s\n' "::error::Unable to determine upstream branch sha!"
              exit 1
          fi

          HEAD_SHA="$(git rev-parse HEAD)"

          if [ "$HEAD_SHA" != "$UPSTREAM_SHA" ]; then
              printf >&2 '%s\n' "[HEAD SHA] $HEAD_SHA != $UPSTREAM_SHA [UPSTREAM SHA]"
              printf >&2 '%s\n' "::error::Upstream has changed, aborting release..."
              exit 1
          fi

          printf '%s\n' "Verified upstream branch has not changed, continuing with release..."

      - name: Semantic Version Release
        id: release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          pip install python-semantic-release==9.* wheel build twine
          semantic-release -vv version
          if [ ! -d dist ]; then echo No release will be made; exit 0; fi
          twine upload dist/* -u __token__ -p ${{ secrets.CI_PYPI_TOKEN }} --skip-existing
          semantic-release publish
