git-command #242
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "/git command" | |
on: | |
repository_dispatch: | |
types: [ git-command ] | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event.client_payload.github.payload.issue.number }}-${{ github.event.client_payload.slash_command.command }}-${{ github.event.client_payload.slash_command.args.unnamed.arg1 || github.event.client_payload.slash_command.args.all }} | |
jobs: | |
merge: | |
if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'merge' }} | |
runs-on: ubuntu-latest | |
timeout-minutes: 5 | |
steps: | |
- uses: hmarr/[email protected] | |
- name: Add Workflow link to command comment | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
token: ${{ secrets.GIT_PAT }} | |
repository: ${{ github.event.client_payload.github.payload.repository.full_name }} | |
comment-id: ${{ github.event.client_payload.github.payload.comment.id }} | |
body: | | |
> [Workflow run](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) | |
- name: Configure git | |
shell: bash | |
run: | | |
set -xeuo pipefail | |
git config --global user.name '${{ github.event.client_payload.github.actor }}' | |
git config --global user.email '${{ github.event.client_payload.github.actor }}@users.noreply.github.com' | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
token: ${{ secrets.GIT_PAT }} | |
repository: ${{ github.event.client_payload.pull_request.head.repo.full_name }} | |
ref: ${{ github.event.client_payload.pull_request.head.ref }} | |
submodules: 'recursive' | |
fetch-depth: 0 | |
- name: Merge | |
id: merge | |
env: | |
BASE_BRANCH: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 || github.event.client_payload.pull_request.base.ref }} | |
HEAD_BRANCH: ${{ github.event.client_payload.pull_request.head.ref }} | |
OUR_FILES: "pyproject.toml poetry.lock web" | |
shell: bash | |
run: | | |
set -xeuo pipefail | |
commit_message="Merge branch '${BASE_BRANCH}' into '${HEAD_BRANCH}'" | |
commit_message_workflow_link='Workflow run: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}' | |
is-ours() { | |
local my_variable="$1" | |
for e in ${OUR_FILES}; do | |
if [[ "${my_variable}" =~ ^"${e}" ]]; then | |
return 0 | |
fi | |
done | |
return 1 | |
} | |
git-resolve-conflict() { | |
STRATEGY="$1" | |
FILE_PATH="$2" | |
tmp_1=$(mktemp) | |
tmp_2=$(mktemp) | |
tmp_3=$(mktemp) | |
git show :1:"${FILE_PATH}" > "${tmp_1}" | |
git show :2:"${FILE_PATH}" > "${tmp_2}" | |
git show :3:"${FILE_PATH}" > "${tmp_3}" | |
git merge-file "${STRATEGY}" -p "${tmp_2}" "${tmp_1}" "${tmp_3}" > "${FILE_PATH}" | |
rm "${tmp_1}" || true | |
rm "${tmp_2}" || true | |
rm "${tmp_3}" || true | |
return 0 | |
} | |
if output=$(git merge "origin/${BASE_BRANCH}" -m "${commit_message}" -m "${commit_message_workflow_link}"); then | |
echo "result=true" >> $GITHUB_OUTPUT | |
echo "reaction=+1" >> $GITHUB_OUTPUT | |
output_last_line=$(tail -n1 <<< "${output}") | |
echo "message=Successfully merged: ${output_last_line}" >> $GITHUB_OUTPUT | |
exit 0 | |
fi | |
conflict_files=$(git diff --name-only --diff-filter=U) | |
result='true' | |
while read -r conflict_file; do | |
if is-ours "${conflict_file}"; then | |
if git-resolve-conflict --ours "${conflict_file}"; then | |
echo "::notice file=${conflict_file}::Merge Conflict automatically resolved ${conflict_file}" | |
git add "${conflict_file}" | |
else | |
result='false' | |
echo "::error file=${conflict_file}::Failed to automatically resolve ${conflict_file}" | |
fi | |
else | |
result='false' | |
echo "::error file=${conflict_file}::Could not resolve ${conflict_file}" | |
fi | |
done <<< ${conflict_files} | |
conflict_files=$(git diff --name-only --diff-filter=U) | |
if [ -z "${conflict_files}" ]; then | |
git commit -m "${commit_message}" -m "${commit_message_workflow_link}" | |
echo "result=true" >> $GITHUB_OUTPUT | |
echo "reaction=+1" >> $GITHUB_OUTPUT | |
output_last_line=$(git show --shortstat HEAD | tail -n1) | |
echo "message=Successfully merged: ${output_last_line}" >> $GITHUB_OUTPUT | |
exit 0 | |
fi | |
echo "result=false" >> $GITHUB_OUTPUT | |
echo "reaction=-1" >> $GITHUB_OUTPUT | |
{ | |
echo "message<<EOF" | |
echo "Unresolvable merge conflict detected, please resolve it using the git command line: ${conflict_files}" | |
echo "EOF" | |
} >> $GITHUB_OUTPUT | |
exit 1 | |
- name: Push | |
if: steps.merge.outputs.result == 'true' | |
run: | | |
set -xeuo pipefail | |
git push origin HEAD | |
- name: Add reaction to command comment | |
uses: peter-evans/create-or-update-comment@v4 | |
if: always() | |
with: | |
token: ${{ secrets.GIT_PAT }} | |
repository: ${{ github.event.client_payload.github.payload.repository.full_name }} | |
comment-id: ${{ github.event.client_payload.github.payload.comment.id }} | |
body: | | |
> ${{ steps.merge.outputs.message || '**Error**: Workflow failed' }} | |
reactions: ${{ steps.merge.outputs.reaction || '-1' }} | |
help: | |
if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'help' || !contains(fromJson('["merge"]'), github.event.client_payload.slash_command.args.unnamed.arg1) }} | |
runs-on: ubuntu-latest | |
timeout-minutes: 1 | |
steps: | |
- name: Update comment | |
uses: peter-evans/create-or-update-comment@v4 | |
with: | |
token: ${{ secrets.GIT_PAT }} | |
repository: ${{ github.event.client_payload.github.payload.repository.full_name }} | |
comment-id: ${{ github.event.client_payload.github.payload.comment.id }} | |
body: | | |
> Command | Description | |
> --- | --- | |
> /git merge `branch` | Merge branch `branch` into current branch | |
reaction-type: hooray |