Add create_branch option to force create a new branch (#203)

* Add create_branch option

* Checkout new branch if create_branch input is true

* Add tests

* Update README
This commit is contained in:
Stefan Zweifel 2022-02-27 07:52:17 +01:00 committed by GitHub
parent dee58f4213
commit ebe77391c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 287 additions and 17 deletions

View File

@ -28,15 +28,16 @@ The following is an extended example with all possible options available for thi
```yaml
- uses: stefanzweifel/git-auto-commit-action@v4
with:
# Optional, but recommended
# Optional. Commit message for the created commit.
# Defaults to "Apply automatic changes"
commit_message: Automated Change
# Optional branch name where commit should be pushed to.
# Defaults to the current branch.
# Optional. Local and remote branch name where commit is going to be pushed
# to. Defaults to the current branch.
# You might need to set `create_branch: true` if the branch does not exist.
branch: feature-123
# Optional. Used by `git-commit`.
# Optional. Options used by `git-commit`.
# See https://git-scm.com/docs/git-commit#_options
commit_options: '--no-verify --signoff'
@ -47,8 +48,8 @@ The following is an extended example with all possible options available for thi
# - https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec
file_pattern: src/*.js tests/*.js *.php
# Optional local file path to the repository
# Defaults to the root of the repository
# Optional. Local file path to the repository.
# Defaults to the root of the repository.
repository: .
# Optional commit user and author settings
@ -56,19 +57,19 @@ The following is an extended example with all possible options available for thi
commit_user_email: my-github-actions-bot@example.org # defaults to "actions@github.com"
commit_author: Author <actions@github.com> # defaults to author of the commit that triggered the run
# Optional tag message
# Action will create and push a new tag to the remote repository and the defined branch
# Optional. Tag name being created in the local repository and
# pushed to remtoe repository and defined branch.
tagging_message: 'v1.0.0'
# Optional. Used by `git-status`
# See https://git-scm.com/docs/git-status#_options
# Optional. Option used by `git-status` to determine if the repository is
# dirty. See https://git-scm.com/docs/git-status#_options
status_options: '--untracked-files=no'
# Optional. Used by `git-add`
# Optional. Options used by `git-add`.
# See https://git-scm.com/docs/git-add#_options
add_options: '-u'
# Optional. Used by `git-push`
# Optional. Options used by `git-push`.
# See https://git-scm.com/docs/git-push#_options
push_options: '--force'
@ -84,6 +85,9 @@ The following is an extended example with all possible options available for thi
# Optional. Prevents the shell from expanding filenames.
# Details: https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
disable_globbing: true
# Optional. Create given branch name in local and remote repository.
create_branch: true
```
Please note that the Action depends on `bash`. If you're using the Action in a job in combination with a custom Docker container, make sure that `bash` is installed.

View File

@ -25,7 +25,7 @@ inputs:
required: false
default: ''
file_pattern:
description: File pattern used for `git add`. For example `src/\*.js`
description: File pattern used for `git add`. For example `src/*.js`
required: false
default: '.'
repository:
@ -67,6 +67,9 @@ inputs:
disable_globbing:
description: Stop the shell from expanding filenames (https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html)
default: false
create_branch:
description: Create new branch with the name of `branch`-input in local and remote repository, if it doesn't exist yet.
default: false
outputs:
changes_detected:

View File

@ -48,20 +48,26 @@ _switch_to_branch() {
echo "INPUT_BRANCH value: $INPUT_BRANCH";
# Fetch remote to make sure that repo can be switched to the right branch.
if "$INPUT_SKIP_FETCH"; then
echo "::debug::git-fetch has not been executed";
else
git fetch --depth=1;
fi
# If `skip_checkout`-input is true, skip the entire checkout step.
if "$INPUT_SKIP_CHECKOUT"; then
echo "::debug::git-checkout has not been executed";
else
# Create new local branch if `create_branch`-input is true
if "$INPUT_CREATE_BRANCH"; then
# shellcheck disable=SC2086
git checkout -B $INPUT_BRANCH --;
else
# Switch to branch from current Workflow run
# shellcheck disable=SC2086
git checkout $INPUT_BRANCH --;
fi
fi
}
_add_files() {

View File

@ -26,6 +26,7 @@ setup() {
export INPUT_SKIP_FETCH=false
export INPUT_SKIP_CHECKOUT=false
export INPUT_DISABLE_GLOBBING=false
export INPUT_CREATE_BRANCH=false
# Configure Git
if [[ -z $(git config user.name) ]]; then
@ -533,3 +534,259 @@ git_auto_commit() {
assert_line "::set-output name=changes_detected::true"
assert_line "::debug::Push commit to remote branch dev"
}
@test "script fails to push commit to new branch that does not exist yet" {
INPUT_BRANCH="not-existend-branch"
INPUT_CREATE_BRANCH=false
run git branch
refute_line --partial "not-existend-branch"
run git branch -r
refute_line --partial "origin/not-existend-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_failure
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
assert_line "::set-output name=changes_detected::true"
assert_line "INPUT_BRANCH value: not-existend-branch"
assert_line "fatal: invalid reference: not-existend-branch"
run git branch
refute_line --partial "not-existend-branch"
run git branch -r
refute_line --partial "origin/not-existend-branch"
}
@test "It creates new local branch and pushes the new branch to remote" {
INPUT_BRANCH="not-existend-branch"
INPUT_CREATE_BRANCH=true
run git branch
refute_line --partial "not-existend-branch"
run git branch -r
refute_line --partial "origin/not-existend-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_success
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
assert_line "::set-output name=changes_detected::true"
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
assert_line "INPUT_BRANCH value: not-existend-branch"
assert_line "INPUT_FILE_PATTERN: ."
assert_line "INPUT_COMMIT_OPTIONS: "
assert_line "::debug::Apply commit options "
assert_line "INPUT_TAGGING_MESSAGE: "
assert_line "No tagging message supplied. No tag will be added."
assert_line "INPUT_PUSH_OPTIONS: "
assert_line "::debug::Apply push options "
assert_line "::debug::Push commit to remote branch not-existend-branch"
run git branch
assert_line --partial "not-existend-branch"
run git branch -r
assert_line --partial "origin/not-existend-branch"
}
@test "it does not create new local branch if local branch already exists" {
git checkout -b not-existend-remote-branch
git checkout master
INPUT_BRANCH="not-existend-remote-branch"
INPUT_CREATE_BRANCH=true
run git branch
assert_line --partial "not-existend-remote-branch"
run git branch -r
refute_line --partial "origin/not-existend-remote-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_success
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
assert_line "::set-output name=changes_detected::true"
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
assert_line "INPUT_BRANCH value: not-existend-remote-branch"
assert_line "INPUT_FILE_PATTERN: ."
assert_line "INPUT_COMMIT_OPTIONS: "
assert_line "::debug::Apply commit options "
assert_line "INPUT_TAGGING_MESSAGE: "
assert_line "No tagging message supplied. No tag will be added."
assert_line "INPUT_PUSH_OPTIONS: "
assert_line "::debug::Apply push options "
assert_line "::debug::Push commit to remote branch not-existend-remote-branch"
run git branch
assert_line --partial "not-existend-remote-branch"
run git branch -r
assert_line --partial "origin/not-existend-remote-branch"
}
@test "it creates new local branch and pushes branch to remote even if the remote branch already exists" {
# Create `existing-remote-branch` on remote with changes the local repository does not yet have
cd $FAKE_TEMP_LOCAL_REPOSITORY;
git checkout -b "existing-remote-branch"
touch new-branch-file.txt
git add new-branch-file.txt
git commit -m "Add additional file";
git push origin existing-remote-branch;
run git branch;
assert_line --partial "existing-remote-branch"
# ---------
# Switch to our regular local repository and run `git-auto-commit`
cd $FAKE_LOCAL_REPOSITORY;
INPUT_BRANCH="existing-remote-branch"
INPUT_CREATE_BRANCH=true
run git branch
refute_line --partial "existing-remote-branch"
run git fetch --all;
run git pull origin existing-remote-branch;
run git branch -r;
assert_line --partial "origin/existing-remote-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_success
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
assert_line "::set-output name=changes_detected::true"
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
assert_line "INPUT_BRANCH value: existing-remote-branch"
assert_line "INPUT_FILE_PATTERN: ."
assert_line "INPUT_COMMIT_OPTIONS: "
assert_line "::debug::Apply commit options "
assert_line "INPUT_TAGGING_MESSAGE: "
assert_line "No tagging message supplied. No tag will be added."
assert_line "INPUT_PUSH_OPTIONS: "
assert_line "::debug::Apply push options "
assert_line "::debug::Push commit to remote branch existing-remote-branch"
run git branch
assert_line --partial "existing-remote-branch"
run git branch -r
assert_line --partial "origin/existing-remote-branch"
# Assert that branch "existing-remote-branch" was updated on remote
current_sha="$(git rev-parse --verify --short existing-remote-branch)"
remote_sha="$(git rev-parse --verify --short origin/existing-remote-branch)"
assert_equal $current_sha $remote_sha;
}
@test "script fails if new local branch is checked out and push fails as remote has newer commits than local" {
# Create `existing-remote-branch` on remote with changes the local repository does not yet have
cd $FAKE_TEMP_LOCAL_REPOSITORY;
git checkout -b "existing-remote-branch"
touch new-branch-file.txt
git add new-branch-file.txt
git commit -m "Add additional file";
git push origin existing-remote-branch;
run git branch;
assert_line --partial "existing-remote-branch"
# ---------
# Switch to our regular local repository and run `git-auto-commit`
cd $FAKE_LOCAL_REPOSITORY;
INPUT_BRANCH="existing-remote-branch"
INPUT_CREATE_BRANCH=true
run git branch
refute_line --partial "existing-remote-branch"
run git fetch --all;
run git branch -r;
assert_line --partial "origin/existing-remote-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_failure
assert_line "hint: Updates were rejected because the tip of your current branch is behind"
# Assert that branch exists locally and on remote
run git branch
assert_line --partial "existing-remote-branch"
run git branch -r
assert_line --partial "origin/existing-remote-branch"
# Assert that branch "existing-remote-branch" was not updated on remote
current_sha="$(git rev-parse --verify --short existing-remote-branch)"
remote_sha="$(git rev-parse --verify --short origin/existing-remote-branch)"
refute [assert_equal $current_sha $remote_sha];
}
@test "It pushes commit to remote if branch already exists and local repo is behind its remote counterpart" {
# Create `new-branch` on remote with changes the local repository does not yet have
cd $FAKE_TEMP_LOCAL_REPOSITORY;
git checkout -b "new-branch"
touch new-branch-file.txt
git add new-branch-file.txt
git commit --quiet -m "Add additional file";
git push origin new-branch;
run git branch -r
assert_line --partial "origin/new-branch"
# ---------
# Switch to our regular local repository and run `git-auto-commit`
cd $FAKE_LOCAL_REPOSITORY;
INPUT_BRANCH="new-branch"
# Assert that local remote does not know have "new-branch" locally nor does
# know about the remote branch.
run git branch
refute_line --partial "new-branch"
run git branch -r
refute_line --partial "origin/new-branch"
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
run git_auto_commit
assert_success
assert_line "INPUT_BRANCH value: new-branch"
assert_line --partial "::debug::Push commit to remote branch new-branch"
# Assert that branch "new-branch" was updated on remote
current_sha="$(git rev-parse --verify --short new-branch)"
remote_sha="$(git rev-parse --verify --short origin/new-branch)"
assert_equal $current_sha $remote_sha;
}