# This file incorporates work covered by the following copyright and
# permission notice
#
#     Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors
#
#     Permission is hereby granted, free of charge, to any person obtaining
#     a copy of this software and associated documentation files (the
#     "Software"), to deal in the Software without restriction, including
#     without limitation the rights to use, copy, modify, merge, publish,
#     distribute, sublicense, and/or sell copies of the Software, and to
#     permit persons to whom the Software is furnished to do so, subject to
#     the following conditions:
#
#     The above copyright notice and this permission notice shall be
#     included in all copies or substantial portions of the Software.
#
#     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
#     LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
#     OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
#     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

name: Get merge commit
description: Get a merge commit of a given pull request

inputs:
  repository:
    description: Repository containing the pull request
    required: false
  pull-request-id:
    description: ID of a pull request
    required: true

outputs:
  merge-commit-sha:
    description: Git SHA of a merge commit
    value: ${{ steps.query.outputs.merge-commit-sha }}

runs:
  using: composite

  steps:
    - name: Wait for GitHub to report merge commit
      id: query
      shell: bash
      env:
        GITHUB_REPO: ${{ inputs.repository || github.repository }}
        PR_ID: ${{ inputs.pull-request-id }}
      # https://github.com/NixOS/nixpkgs/blob/8f77f3600f1ee775b85dc2c72fd842768e486ec9/ci/get-merge-commit.sh
      run: |
        set -euo pipefail
        
        log() {
        	echo "$@" >&2
        }
        
        # Retry the API query this many times
        retryCount=5
        # Start with 5 seconds, but double every retry
        retryInterval=5
        
        while true; do
        	log "Checking whether the pull request can be merged"
        	prInfo=$(gh api \
        		-H "Accept: application/vnd.github+json" \
        		-H "X-GitHub-Api-Version: 2022-11-28" \
        		"/repos/$GITHUB_REPO/pulls/$PR_ID")
        
        	# Non-open PRs won't have their mergeability computed no matter what
        	state=$(jq -r .state <<<"$prInfo")
        	if [[ "$state" != open ]]; then
        		log "PR is not open anymore"
        		exit 1
        	fi
        
        	mergeable=$(jq -r .mergeable <<<"$prInfo")
        	if [[ "$mergeable" == "null" ]]; then
        		if ((retryCount == 0)); then
        			log "Not retrying anymore. It's likely that GitHub is having internal issues: check https://www.githubstatus.com/"
        			exit 3
        		else
        			((retryCount -= 1)) || true
        
        			# null indicates that GitHub is still computing whether it's mergeable
        			# Wait a couple seconds before trying again
        			log "GitHub is still computing whether this PR can be merged, waiting $retryInterval seconds before trying again ($retryCount retries left)"
        			sleep "$retryInterval"
        
        			((retryInterval *= 2)) || true
        		fi
        	else
        		break
        	fi
        done
        
        if [[ "$mergeable" == "true" ]]; then
          echo "merge-commit-sha=$(jq -r .merge_commit_sha <<<"$prInfo")" >> "$GITHUB_OUTPUT"
        else
        	echo "# 🚨 The PR has a merge conflict!" >> "$GITHUB_STEP_SUMMARY"
        	exit 2
        fi
