Skip to content

Automerge

Automerge #1879

Workflow file for this run

name: Automerge
on:
workflow_run:
workflows:
- Check
types:
- completed
jobs:
test:
name: Renovate
if: github.event.workflow_run.conclusion == 'success'
permissions:
issues: write
pull-requests: write
contents: write
actions: write
runs-on: ubuntu-22.04
steps:
- name: Install uniget
uses: uniget-org/uniget-action@v1
with:
prefix: helper
tools: gojq
- name: Test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REF: ${{ github.event.workflow_run.head_branch }}
run: |
set -o errexit -o pipefail
echo "Running on branch: ${REF}"
PR_JSON="$(
curl --silent --show-error --fail --header "Authorization: token ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls?state=open&head=uniget-org:${REF}" \
| jq '.[]'
)"
PR="$( jq --raw-output '.number' <<<"${PR_JSON}" )"
if test -z "${PR}"; then
echo "ERROR: Failed to retrieve PR number from event payload"
exit 1
fi
echo "PR ${PR} uses branch ${REF}"
if ! jq --raw-output '.labels[].name' <<<"${PR_JSON}" | grep -q "^type/renovate$"; then
echo "PR ${PR} does not have label type/renovate. Canceling"
curl --silent --show-error --fail --header "Authorization: token ${GITHUB_TOKEN}" \
--request POST \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}/cancel"
fi
RUN_URL="$(
curl --silent --show-error --location --fail \
--url "${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" \
| jq --raw-output '.html_url'
)"
echo "Extracted HTML URL for this run: ${RUN_URL}."
curl --silent --show-error --fail \
--request POST \
--header "Authorization: Bearer ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--data '{"body": "Attempting automerge. See '"${RUN_URL}"'."}'
MERGEABLE_STATE="$( jq --raw-output '.mergeable_state' <<<"${PR_JSON}" )"
while test "${MERGEABLE_STATE}" == "unknown" || test "${MERGEABLE_STATE}" == "null"; do
echo "Got mergeable state: ${MERGEABLE_STATE}"
PR_JSON="$(
curl --silent --show-error --fail \
--header "Authorization: token ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls/${PR}" \
| jq --compact-output '.'
)"
MERGEABLE_STATE="$( jq --raw-output '.mergeable_state' <<<"${PR_JSON}" )"
done
case "${MERGEABLE_STATE}" in
blocked)
echo "PR ${PR} is blocked and can not be merged"
curl --silent --show-error --fail \
--request POST \
--header "Authorization: Bearer ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--data '{"body": "PR is blocked and can not be merged. See '"${RUN_URL}"'."}'
echo "Aborting workflow"
exit 1
;;
clean)
echo "PR ${PR} is clean and can be merged"
curl --silent --show-error --fail \
--request POST \
--header "Authorization: Bearer ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--data '{"body": "PR is clean and can be merged. See '"${RUN_URL}"'."}'
;;
*)
echo "ERROR: Unknown mergeable_state ${MERGEABLE_STATE} for PR ${PR}"
curl --silent --show-error --fail \
--request POST \
--header "Authorization: Bearer ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--data '{"body": "PR has unknown mergeable_state ('"${MERGEABLE_STATE}"') and can not be merged. See '"${RUN_URL}"'."}'
echo "Aborting workflow"
exit 1
;;
esac
echo "PR ${PR} is ready for auto-merge"
echo "Merging PR ${PR}..."
http_code="405"
merged=false
max_attempts=3
attempt=1
while true; do
echo " Attempt ${attempt}"
http_code="$(
curl --silent --request PUT --header "Authorization: token ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/pulls/${PR}/merge" \
--data '{"merge_method": "rebase"}' \
--output merge.json \
--write-out "${http_code}"
)"
if jq --exit-status 'select(.merged != null) | select(.merged == true)' merge.json >/dev/null; then
echo " Merged"
merged=true
break
fi
echo " Got HTTP code ${http_code}"
if test "${attempt}" -eq "${max_attempts}"; then
echo " Max attempt reached"
break
elif test "${http_code}" -eq 405; then
echo " Sleeping"
cat merge.json
sleep 5
else
echo " Non-405 code"
break
fi
attempt=$(( attempt + 1 ))
done
if ! ${merged}; then
echo "ERROR: Unable to merge PR ${PR}"
exit 1
fi
echo "PR ${PR} has been merged"
echo "Deleting branch ${REF}..."
if ! curl --silent --show-error --fail --request DELETE --header "Authorization: token ${GITHUB_TOKEN}" \
--url "https://api.github.com/repos/${GITHUB_REPOSITORY}/git/refs/heads/${REF}"; then
echo "ERROR: Unable to delete branch ${REF} from PR ${PR}"
exit 1
fi
echo "Branch ${REF} has been deleted"