Skip to content

Commit

Permalink
Merge pull request #14 from GuillaumeFalourd/test
Browse files Browse the repository at this point in the history
Update action YAML file
  • Loading branch information
GuillaumeFalourd authored Feb 7, 2024
2 parents d1a9410 + 8809323 commit 95450b5
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 60 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ _Inspired from [https://github.com/repo-sync/pull-request](https://github.com/re
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Can use PAT as secret
```
## 🧩 Outputs
Field | Observation
------------ | ------------
`pr_url` | Pull request URL
`pr_number` | Pull request number
`has_changed_files` | Boolean string indicating whether any file has been changed
`pr_created` | Boolean string indicating whether a PR was created

## 🤝 Contributing

☞ If you're interested in contributing to this repository, please follow the [guidelines](https://github.com/GuillaumeFalourd/pull-request-action/blob/main/CONTRIBUTING.md)
Expand Down
213 changes: 153 additions & 60 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ inputs:
description: Branch name to pull from, default is triggered branch
required: false
destination_branch:
description: Branch name to sync to in this repo, default is master
description: Branch name to sync to in this repo, default is main
required: false
default: master
default: main
pr_title:
description: Pull request title
required: false
Expand Down Expand Up @@ -38,34 +38,105 @@ inputs:
outputs:
pr_url:
description: 'Pull request URL'
value: ${{ steps.pr-creation.outputs.pr_url }}
pr_number:
description: 'Pull request number'
value: ${{ steps.pr-creation.outputs.pr_number }}
has_changed_files:
description: 'Boolean string indicating whether any file has been changed'
value: ${{ steps.pr-creation.outputs.has_changed_files }}
pr_created:
description: 'Boolean string indicating whether a PR was created'
value: ${{ steps.pr-creation.outputs.pr_created }}

runs:
using: "composite"
steps:
- name: Create Pull Request ⤵️
- name: Create Pull Request ⤵️
env:
INPUT_SOURCE_BRANCH: ${{ inputs.source_branch }}
INPUT_DESTINATION_BRANCH: ${{ inputs.destination_branch }}
INPUT_PR_TITLE: ${{ inputs.pr_title }}
INPUT_PR_BODY: ${{ inputs.pr_body }}
INPUT_PR_REVIEWER: ${{ inputs.pr_reviewer }}
INPUT_PR_ASSIGNEE: ${{ inputs.pr_assignee }}
INPUT_PR_LABEL: ${{ inputs.pr_label }}
INPUT_PR_MILESTONE: ${{ inputs.pr_milestone }}
INPUT_PR_DRAFT: ${{ inputs.pr_draft }}
INPUT_PR_ALLOW_EMPTY: ${{ inputs.pr_allow_empty }}
id: pr-creation
shell: bash
run: |
set -e
set -o pipefail
if [[ ! -z "${{ inputs.source_branch }}" ]]; then
SOURCE_BRANCH="${{ inputs.source_branch }}"
# HELPER SYNTAX:
# catch STDOUT_VARIABLE STDERR_VARIABLE COMMAND [ARG1[ ARG2[ ...[ ARGN]]]]
catch() {
{
IFS=$'\n' read -r -d '' "${1}";
IFS=$'\n' read -r -d '' "${2}";
(IFS=$'\n' read -r -d '' _ERRNO_; return ${_ERRNO_});
} < <((printf '\0%s\0%d\0' "$(((({ shift 2; "${@}"; echo "${?}" 1>&3-; } | tr -d '\0' 1>&4-) 4>&2- 2>&1- | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)
}
reset_color="\\e[0m"
color_red="\\e[31m"
color_green="\\e[32m"
color_yellow="\\e[33m"
color_blue="\\e[36m"
color_gray="\\e[37m"
echo_blue() { printf "%b\n" "${color_blue}$(printf "%s\n" "$*")${reset_color}"; }
echo_green() { printf "%b\n" "${color_green}$(printf "%s\n" "$*")${reset_color}"; }
echo_red() { printf "%b\n" "${color_red}$(printf "%s\n" "$*")${reset_color}"; }
echo_yellow() { printf "%b\n" "${color_yellow}$(printf "%s\n" "$*")${reset_color}"; }
echo_gray() { printf "%b\n" "${color_gray}$(printf "%s\n" "$*")${reset_color}"; }
echo_grey() { printf "%b\n" "${color_gray}$(printf "%s\n" "$*")${reset_color}"; }
echo_info() { printf "%b\n" "${color_blue}ℹ $(printf "%s\n" "$*")${reset_color}"; }
echo_error() { printf "%b\n" "${color_red}✖ $(printf "%s\n" "$*")${reset_color}"; }
echo_warning() { printf "%b\n" "${color_yellow}✔ $(printf "%s\n" "$*")${reset_color}"; }
echo_success() { printf "%b\n" "${color_green}✔ $(printf "%s\n" "$*")${reset_color}"; }
echo_fail() { printf "%b\n" "${color_red}✖ $(printf "%s\n" "$*")${reset_color}"; }
enable_debug() {
if [[ "${RUNNER_DEBUG}" == "1" ]]; then
echo_info "Enabling debug mode."
set -x
fi
}
disable_debug() {
if [[ "${RUNNER_DEBUG}" != "1" ]]; then
set +x
fi
}
enable_debug
if [[ $SHELLOPTS == *xtrace* ]]; then
env
fi
# init bool var to check if PR creation should be skipped
skip_pr_creation=false
pr_created=false
echo "::group::Gather Inputs"
if [[ ! -z "${INPUT_SOURCE_BRANCH}" ]]; then
SOURCE_BRANCH="${INPUT_SOURCE_BRANCH}"
elif [[ ! -z "$GITHUB_HEAD_REF" && "$GITHUB_EVENT_NAME" == "pull_request" ]]; then
SOURCE_BRANCH="$GITHUB_HEAD_REF"
elif [[ ! -z "$GITHUB_REF" ]]; then
SOURCE_BRANCH=${GITHUB_REF/refs\/heads\//} # Remove branch prefix
else
echo "Set the ${{ inputs.source_branch }} environment variable or trigger from a branch."
echo_fail "Set the inputs.source_branch parameter or trigger from a branch.
exit 1
fi
if [[ ! -z "${{ inputs.destination_branch }}" ]]; then
DESTINATION_BRANCH="${{ inputs.destination_branch }}"
echo_info "SOURCE_BRANCH=$SOURCE_BRANCH"
if [[ ! -z "${INPUT_DESTINATION_BRANCH}" ]]; then
DESTINATION_BRANCH="${INPUT_DESTINATION_BRANCH}"
else
DESTINATION_BRANCH="main"
fi
echo_info "DESTINATION_BRANCH=$DESTINATION_BRANCH"
echo "::endgroup::"
echo "::group::Configure git"
# Github actions no longer auto set the username and GITHUB_TOKEN
git remote set-url origin "https://$GITHUB_ACTOR:$GITHUB_TOKEN@${GITHUB_SERVER_URL#https://}/$GITHUB_REPOSITORY"
Expand All @@ -75,73 +146,95 @@ runs:
# Print out all branches
git --no-pager branch -a -vv
if [ "$(git rev-parse --revs-only "$SOURCE_BRANCH")" = "$(git rev-parse --revs-only "$DESTINATION_BRANCH")" ]; then
echo "Source and destination branches are the same."
exit 0
echo "::endgroup::"
echo "::group::Ensure pull-request contains differences"
SOURCE_REV=$(git rev-parse --revs-only "$SOURCE_BRANCH")
DESTINATION_REV=$(git rev-parse --revs-only "$DESTINATION_BRANCH")
if [ "$SOURCE_REV" = "$DESTINATION_REV" ]; then
echo_info "Source and destination branches are the same. Source rev: $SOURCE_REV, Destination rev: $DESTINATION_REV. Skipping PR creation."
skip_pr_creation=true
fi
# Do not proceed if there are no file differences, this avoids PRs with just a merge commit and no content
# skip pr creation if there are no file differences, this avoids PRs with just a merge commit and no content
LINES_CHANGED=$(git diff --name-only "$DESTINATION_BRANCH" "$SOURCE_BRANCH" -- | wc -l | awk '{print $1}')
if [[ "$LINES_CHANGED" = "0" ]] && [[ ! "${{ inputs.pr_allow_empty }}" == "true" ]]; then
echo "No file changes detected between source and destination branches."
exit 0
if [[ "$LINES_CHANGED" = "0" ]] && [[ ! "${INPUT_PR_ALLOW_EMPTY}" == "true" ]]; then
echo_info "No file changes detected between source and destination branches and pr_allow_empty is not set to true. Skipping PR creation."
skip_pr_creation=true
fi
if [[ "$LINES_CHANGED" = "0" ]]; then
has_changed_files=false
else
has_changed_files=true
fi
echo "::endgroup::"
echo "::group::Assemble gh pr parameters"
# Workaround for `hub` auth error https://github.com/github/hub/issues/2149#issuecomment-513214342
export GITHUB_USER="$GITHUB_ACTOR"
COMMAND="gh pr create --base $DESTINATION_BRANCH --head $SOURCE_BRANCH --no-maintainer-edit"
if [[ ! -z "${{ inputs.pr_title }}" ]]; then
COMMAND="$COMMAND --title \"${{ inputs.pr_title }}\""
declare -a COMMAND
COMMAND+=(gh pr create --base $DESTINATION_BRANCH --head $SOURCE_BRANCH --no-maintainer-edit)
if [[ ! -z "${INPUT_PR_TITLE}" ]]; then
COMMAND+=(--title "${INPUT_PR_TITLE}")
else
COMMAND="$COMMAND --fill"
COMMAND+=(--fill)
fi
if [[ ! -z "${{ inputs.pr_body }}" ]]; then
COMMAND="$COMMAND --body \"${{ inputs.pr_body }}\""
fi
if [[ ! -z "${{ inputs.pr_reviewer }}" ]]; then
COMMAND="$COMMAND --reviewer \"${{ inputs.pr_reviewer }}\""
if [[ ! -z "${INPUT_PR_BODY}" ]]; then
COMMAND+=(--body "${INPUT_PR_BODY}")
fi
if [[ ! -z "${{ inputs.pr_assignee }}" ]]; then
COMMAND="$COMMAND --assignee \"${{ inputs.pr_assignee }}\""
if [[ ! -z "${INPUT_PR_REVIEWER}" ]]; then
COMMAND+=(--reviewer "${INPUT_PR_REVIEWER}")
fi
if [[ ! -z "${{ inputs.pr_label }}" ]]; then
COMMAND="$COMMAND --label \"${{ inputs.pr_label }}\""
if [[ ! -z "${INPUT_PR_ASSIGNEE}" ]]; then
COMMAND+=(--assignee "${INPUT_PR_ASSIGNEE}")
fi
if [[ ! -z "${{ inputs.pr_milestone }}" ]]; then
COMMAND="$COMMAND --milestone \"${{ inputs.pr_milestone }}\""
if [[ ! -z "${INPUT_PR_LABEL}" ]]; then
COMMAND+=(--label "${INPUT_PR_LABEL}")
fi
if [[ "${{ inputs.pr_draft }}" == "true" ]]; then
COMMAND="$COMMAND --draft"
if [[ ! -z "${INPUT_PR_MILESTONE}" ]]; then
COMMAND+=(--milestone "${INPUT_PR_MILESTONE}")
fi
COMMAND="$COMMAND || true"
echo "Command that will be executed:"
echo "$COMMAND"
PR_URL=$(sh -c "$COMMAND")
if [[ "$?" != "0" ]]; then
exit 1
if [[ "${INPUT_PR_DRAFT}" == "true" ]]; then
COMMAND+=(--draft)
fi
echo ${PR_URL}
echo "::set-output name=pr_url::${PR_URL}"
echo "::set-output name=pr_number::${PR_URL##*/}"
if [[ "$LINES_CHANGED" = "0" ]]; then
echo "::set-output name=has_changed_files::false"
else
echo "::set-output name=has_changed_files::true"
echo "::endgroup::"
echo "::group::Create pull request $SOURCE_BRANCH -> $DESTINATION_BRANCH"
pr_command_exit_code=0
pr_already_exists=-1
if [[ "$skip_pr_creation" = "false" ]]; then
echo_info "Command that will be executed: ${COMMAND[@]}"
set +e
catch pr_command_output pr_command_error "${COMMAND[@]}"
pr_command_exit_code=$?
pr_already_exists=$(echo "${pr_command_error}" | grep -c "already exists:" || true)
set -e
echo_info "Output of github cli command: " ${pr_command_output} ${pr_command_error}
if [[ "$pr_command_exit_code" -eq 0 ]];
then
pr_url="${pr_command_output}"
pr_number="${pr_command_output##*/}"
elif [[ "$pr_already_exists" -eq 1 ]];
then
pr_url=$(echo "$pr_command_error" | grep -o 'https://github.com[^ ]*')
pr_number=${pr_url##*/}
fi
if [[ "$pr_command_exit_code" != "0" && "$pr_already_exists" -eq 0 ]]; then
echo_error "Failed to create pull request. Exit code: $pr_command_exit_code. Error: $pr_command_error"
else
# assume that if we got here, a PR was created or exists
echo_success "Pull request created or exists: $pr_url"
pr_created=true
fi
fi
shell: bash
echo "::endgroup::"
echo "::group::Set outputs"
echo "pr_created=${pr_created}" >> "$GITHUB_OUTPUT"
echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT"
echo "pr_number=$pr_number" >> "$GITHUB_OUTPUT"
echo "has_changed_files=${has_changed_files}" >> "$GITHUB_OUTPUT"
cat "$GITHUB_OUTPUT"
echo "::endgroup::"
branding:
icon: 'git-pull-request'
color: 'black'
color: 'black'

0 comments on commit 95450b5

Please sign in to comment.