From eb6c37b4144fcb891b3109d895ae924b21a7fd95 Mon Sep 17 00:00:00 2001 From: Andy Augustin Date: Wed, 13 Mar 2024 21:37:27 +0100 Subject: [PATCH] feat(#482): :sparkles: add option to force push and pr Signed-off-by: Andy Augustin --- README.md | 14 +++++++++++ action.yml | 4 +++ src/sync_template.sh | 59 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index cf438697..11ba2cc1 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,7 @@ jobs: | is_dry_run | `[optional]` set to `true` if you do not want to push the changes and not want to create a PR | `false` | | | is_allow_hooks | `[optional]` set to `true` if you want to enable lifecycle hooks. Use this with caution! | `false` | `false` | | hooks | `[optional]` please check the lifecycle hooks section below | `false` | | +| is_force_push_pr | `[optional]` set to `true` if you want to force push and pr update. Needs further permissions (see below) | `false` | `false` | | is_pr_cleanup | `[optional]` set to `true` if you want to cleanup older PRs targeting the same branch. Use this with caution! | `false` | `false` | | is_not_source_github | `[optional]` set to `true` if the source git provider is not GitHub | `false` | `false` | | is_force_deletion | `[optional]` set to `true` if you want to force delete files which are deleted within the source repository even if they contain changes. You need to also adjust `git_remote_pull_params` (see below for details) | `false` | `false` | @@ -311,6 +312,18 @@ E.g. when you like to disable the sync for all files with exceptions, you need t * ``` +## Force Push and PR + +If you set the input `is_force_push_pr` to `true` you are able to react to e.g. metadata changes within the workflow definition file. +Please note that you need to add permissions for `repository-projects: read`. Compare the needed scope with [gh pr edit][github-gh-cli-pr-edit] + +```yaml + permissions: + contents: write + pull-requests: write + repository-projects: read +``` + ## Sign commits It is recommended to [sign your commits][devto-sign-commits]. This action is able to sign commits. @@ -645,3 +658,4 @@ specification. Contributions of any kind are welcome! [github-create-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token [github-create-secret]: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository [github-create-gpg-key]: https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key +[github-gh-cli-pr-edit]: https://cli.github.com/manual/gh_pr_edit diff --git a/action.yml b/action.yml index 41f8b6b5..9483449f 100644 --- a/action.yml +++ b/action.yml @@ -42,6 +42,9 @@ inputs: default: "false" hooks: description: "[optional] define the hooks as yaml string input" + is_force_push_pr: + description: "[optional] set to true if you want to force push and pr update" + default: "false" is_pr_cleanup: description: "[optional] set to true if you want to cleanup older PRs targeting the same branch." default: "false" @@ -79,6 +82,7 @@ runs: IS_DRY_RUN: ${{ inputs.is_dry_run }} IS_ALLOW_HOOKS: ${{ inputs.is_allow_hooks }} HOOKS: ${{ inputs.hooks }} + IS_FORCE_PUSH_PR: ${{ inputs.is_force_push_pr }} IS_PR_CLEANUP: ${{ inputs.is_pr_cleanup}} IS_NOT_SOURCE_GITHUB: ${{ inputs.is_not_source_github }} IS_FORCE_DELETION: ${{ inputs.is_force_deletion }} diff --git a/src/sync_template.sh b/src/sync_template.sh index e09309d4..36eee606 100644 --- a/src/sync_template.sh +++ b/src/sync_template.sh @@ -40,6 +40,7 @@ if [[ -n "${SRC_SSH_PRIVATEKEY_ABS_PATH}" ]]; then export GIT_SSH_COMMAND="ssh -i ${SRC_SSH_PRIVATEKEY_ABS_PATH}" fi +IS_FORCE_PUSH_PR="${IS_FORCE_PUSH_PR:-"false"}" GIT_REMOTE_PULL_PARAMS="${GIT_REMOTE_PULL_PARAMS:---allow-unrelated-histories --squash --strategy=recursive -X theirs}" cmd_from_yml "install" @@ -238,11 +239,19 @@ function eventual_create_labels () { # push the changes # Arguments: # branch +# is_force ############################## function push () { info "push changes" local branch=$1 - git push --set-upstream origin "${branch}" + local is_force=$2 + + if [ "$is_force" == true ] ; then + warn "forcing the push." + git push --force --set-upstream origin "${branch}" + else + git push --set-upstream origin "${branch}" + fi } #################################### @@ -254,7 +263,7 @@ function push () { # labels # reviewers ################################### -function create_pr () { +function create_pr() { info "create pr" local title=$1 local body=$2 @@ -267,7 +276,38 @@ function create_pr () { --body "${body}" \ --base "${branch}" \ --label "${labels}" \ - --reviewer "${reviewers}" + --reviewer "${reviewers}" || create_pr_has_issues=true + + if [ "$create_pr_has_issues" == true ] ; then + warn "Creating the PR failed." + warn "Eventually it is already existent." + return 1 + fi + return 0 +} + +#################################### +# creates or edits a pr if already existent +# Arguments: +# title +# body +# branch +# labels +# reviewers +################################### +function create_or_edit_pr() { + info "create pr or edit the pr" + local title=$1 + local body=$2 + local branch=$3 + local labels=$4 + local reviewers=$5 + + create_pr "${title}" "${body}" "${branch}" "${labels}" "${reviewers}" || gh pr edit \ + --title "${title}" \ + --body "${body}" \ + --add-label "${labels}" \ + --add-reviewer "${reviewers}" } ######################################### @@ -313,6 +353,10 @@ function handle_templatesyncignore() { function prechecks() { info "prechecks" echo "::group::prechecks" + if [ "${IS_FORCE_PUSH_PR}" == "true" ]; then + warn "skipping prechecks because we force push and pr" + return 0 + fi check_branch_remote_existing "${NEW_BRANCH}" check_if_commit_already_in_hist_graceful_exit "${TEMPLATE_REMOTE_GIT_HASH}" @@ -391,9 +435,14 @@ function push_prepare_pr_create_pr() { echo "::group::push changes and create PR" cmd_from_yml "prepush" - push "${NEW_BRANCH}" + push "${NEW_BRANCH}" "${IS_FORCE_PUSH_PR}" cmd_from_yml "prepr" - create_pr "${PR_TITLE}" "${PR_BODY}" "${UPSTREAM_BRANCH}" "${PR_LABELS}" "${PR_REVIEWERS}" + if [ "$IS_FORCE_PUSH_PR" == true ] ; then + create_or_edit_pr "${PR_TITLE}" "${PR_BODY}" "${UPSTREAM_BRANCH}" "${PR_LABELS}" "${PR_REVIEWERS}" + else + create_pr "${PR_TITLE}" "${PR_BODY}" "${UPSTREAM_BRANCH}" "${PR_LABELS}" "${PR_REVIEWERS}" + fi + echo "::endgroup::" }