Skip to content

Commit ebe7739

Browse files
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
1 parent dee58f4 commit ebe7739

4 files changed

Lines changed: 287 additions & 17 deletions

File tree

README.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ The following is an extended example with all possible options available for thi
2828
```yaml
2929
- uses: stefanzweifel/git-auto-commit-action@v4
3030
with:
31-
# Optional, but recommended
31+
# Optional. Commit message for the created commit.
3232
# Defaults to "Apply automatic changes"
3333
commit_message: Automated Change
3434
35-
# Optional branch name where commit should be pushed to.
36-
# Defaults to the current branch.
35+
# Optional. Local and remote branch name where commit is going to be pushed
36+
# to. Defaults to the current branch.
37+
# You might need to set `create_branch: true` if the branch does not exist.
3738
branch: feature-123
3839

39-
# Optional. Used by `git-commit`.
40+
# Optional. Options used by `git-commit`.
4041
# See https://git-scm.com/docs/git-commit#_options
4142
commit_options: '--no-verify --signoff'
4243

@@ -47,28 +48,28 @@ The following is an extended example with all possible options available for thi
4748
# - https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefpathspecapathspec
4849
file_pattern: src/*.js tests/*.js *.php
4950

50-
# Optional local file path to the repository
51-
# Defaults to the root of the repository
51+
# Optional. Local file path to the repository.
52+
# Defaults to the root of the repository.
5253
repository: .
5354

5455
# Optional commit user and author settings
5556
commit_user_name: My GitHub Actions Bot # defaults to "GitHub Actions"
5657
commit_user_email: my-github-actions-bot@example.org # defaults to "actions@github.com"
5758
commit_author: Author <actions@github.com> # defaults to author of the commit that triggered the run
5859

59-
# Optional tag message
60-
# Action will create and push a new tag to the remote repository and the defined branch
60+
# Optional. Tag name being created in the local repository and
61+
# pushed to remtoe repository and defined branch.
6162
tagging_message: 'v1.0.0'
6263

63-
# Optional. Used by `git-status`
64-
# See https://git-scm.com/docs/git-status#_options
64+
# Optional. Option used by `git-status` to determine if the repository is
65+
# dirty. See https://git-scm.com/docs/git-status#_options
6566
status_options: '--untracked-files=no'
6667

67-
# Optional. Used by `git-add`
68+
# Optional. Options used by `git-add`.
6869
# See https://git-scm.com/docs/git-add#_options
6970
add_options: '-u'
7071

71-
# Optional. Used by `git-push`
72+
# Optional. Options used by `git-push`.
7273
# See https://git-scm.com/docs/git-push#_options
7374
push_options: '--force'
7475

@@ -84,6 +85,9 @@ The following is an extended example with all possible options available for thi
8485
# Optional. Prevents the shell from expanding filenames.
8586
# Details: https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html
8687
disable_globbing: true
88+
89+
# Optional. Create given branch name in local and remote repository.
90+
create_branch: true
8791
```
8892
8993
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.

action.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ inputs:
2525
required: false
2626
default: ''
2727
file_pattern:
28-
description: File pattern used for `git add`. For example `src/\*.js`
28+
description: File pattern used for `git add`. For example `src/*.js`
2929
required: false
3030
default: '.'
3131
repository:
@@ -67,6 +67,9 @@ inputs:
6767
disable_globbing:
6868
description: Stop the shell from expanding filenames (https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html)
6969
default: false
70+
create_branch:
71+
description: Create new branch with the name of `branch`-input in local and remote repository, if it doesn't exist yet.
72+
default: false
7073

7174
outputs:
7275
changes_detected:

entrypoint.sh

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,25 @@ _switch_to_branch() {
4848
echo "INPUT_BRANCH value: $INPUT_BRANCH";
4949

5050
# Fetch remote to make sure that repo can be switched to the right branch.
51-
5251
if "$INPUT_SKIP_FETCH"; then
5352
echo "::debug::git-fetch has not been executed";
5453
else
5554
git fetch --depth=1;
5655
fi
5756

57+
# If `skip_checkout`-input is true, skip the entire checkout step.
5858
if "$INPUT_SKIP_CHECKOUT"; then
5959
echo "::debug::git-checkout has not been executed";
6060
else
61-
# Switch to branch from current Workflow run
62-
# shellcheck disable=SC2086
63-
git checkout $INPUT_BRANCH --;
61+
# Create new local branch if `create_branch`-input is true
62+
if "$INPUT_CREATE_BRANCH"; then
63+
# shellcheck disable=SC2086
64+
git checkout -B $INPUT_BRANCH --;
65+
else
66+
# Switch to branch from current Workflow run
67+
# shellcheck disable=SC2086
68+
git checkout $INPUT_BRANCH --;
69+
fi
6470
fi
6571
}
6672

tests/git-auto-commit.bats

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ setup() {
2626
export INPUT_SKIP_FETCH=false
2727
export INPUT_SKIP_CHECKOUT=false
2828
export INPUT_DISABLE_GLOBBING=false
29+
export INPUT_CREATE_BRANCH=false
2930

3031
# Configure Git
3132
if [[ -z $(git config user.name) ]]; then
@@ -533,3 +534,259 @@ git_auto_commit() {
533534
assert_line "::set-output name=changes_detected::true"
534535
assert_line "::debug::Push commit to remote branch dev"
535536
}
537+
538+
@test "script fails to push commit to new branch that does not exist yet" {
539+
INPUT_BRANCH="not-existend-branch"
540+
INPUT_CREATE_BRANCH=false
541+
542+
run git branch
543+
refute_line --partial "not-existend-branch"
544+
545+
run git branch -r
546+
refute_line --partial "origin/not-existend-branch"
547+
548+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
549+
550+
run git_auto_commit
551+
552+
assert_failure
553+
554+
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
555+
assert_line "::set-output name=changes_detected::true"
556+
assert_line "INPUT_BRANCH value: not-existend-branch"
557+
assert_line "fatal: invalid reference: not-existend-branch"
558+
559+
run git branch
560+
refute_line --partial "not-existend-branch"
561+
562+
run git branch -r
563+
refute_line --partial "origin/not-existend-branch"
564+
}
565+
566+
@test "It creates new local branch and pushes the new branch to remote" {
567+
INPUT_BRANCH="not-existend-branch"
568+
INPUT_CREATE_BRANCH=true
569+
570+
run git branch
571+
refute_line --partial "not-existend-branch"
572+
573+
run git branch -r
574+
refute_line --partial "origin/not-existend-branch"
575+
576+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
577+
578+
run git_auto_commit
579+
580+
assert_success
581+
582+
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
583+
assert_line "::set-output name=changes_detected::true"
584+
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
585+
assert_line "INPUT_BRANCH value: not-existend-branch"
586+
assert_line "INPUT_FILE_PATTERN: ."
587+
assert_line "INPUT_COMMIT_OPTIONS: "
588+
assert_line "::debug::Apply commit options "
589+
assert_line "INPUT_TAGGING_MESSAGE: "
590+
assert_line "No tagging message supplied. No tag will be added."
591+
assert_line "INPUT_PUSH_OPTIONS: "
592+
assert_line "::debug::Apply push options "
593+
assert_line "::debug::Push commit to remote branch not-existend-branch"
594+
595+
run git branch
596+
assert_line --partial "not-existend-branch"
597+
598+
run git branch -r
599+
assert_line --partial "origin/not-existend-branch"
600+
}
601+
602+
@test "it does not create new local branch if local branch already exists" {
603+
604+
git checkout -b not-existend-remote-branch
605+
git checkout master
606+
607+
INPUT_BRANCH="not-existend-remote-branch"
608+
INPUT_CREATE_BRANCH=true
609+
610+
run git branch
611+
assert_line --partial "not-existend-remote-branch"
612+
613+
run git branch -r
614+
refute_line --partial "origin/not-existend-remote-branch"
615+
616+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
617+
618+
run git_auto_commit
619+
620+
assert_success
621+
622+
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
623+
assert_line "::set-output name=changes_detected::true"
624+
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
625+
assert_line "INPUT_BRANCH value: not-existend-remote-branch"
626+
assert_line "INPUT_FILE_PATTERN: ."
627+
assert_line "INPUT_COMMIT_OPTIONS: "
628+
assert_line "::debug::Apply commit options "
629+
assert_line "INPUT_TAGGING_MESSAGE: "
630+
assert_line "No tagging message supplied. No tag will be added."
631+
assert_line "INPUT_PUSH_OPTIONS: "
632+
assert_line "::debug::Apply push options "
633+
assert_line "::debug::Push commit to remote branch not-existend-remote-branch"
634+
635+
run git branch
636+
assert_line --partial "not-existend-remote-branch"
637+
638+
run git branch -r
639+
assert_line --partial "origin/not-existend-remote-branch"
640+
}
641+
642+
@test "it creates new local branch and pushes branch to remote even if the remote branch already exists" {
643+
644+
# Create `existing-remote-branch` on remote with changes the local repository does not yet have
645+
cd $FAKE_TEMP_LOCAL_REPOSITORY;
646+
git checkout -b "existing-remote-branch"
647+
touch new-branch-file.txt
648+
git add new-branch-file.txt
649+
git commit -m "Add additional file";
650+
git push origin existing-remote-branch;
651+
652+
run git branch;
653+
assert_line --partial "existing-remote-branch"
654+
655+
# ---------
656+
# Switch to our regular local repository and run `git-auto-commit`
657+
cd $FAKE_LOCAL_REPOSITORY;
658+
659+
INPUT_BRANCH="existing-remote-branch"
660+
INPUT_CREATE_BRANCH=true
661+
662+
run git branch
663+
refute_line --partial "existing-remote-branch"
664+
665+
run git fetch --all;
666+
run git pull origin existing-remote-branch;
667+
run git branch -r;
668+
assert_line --partial "origin/existing-remote-branch"
669+
670+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
671+
672+
run git_auto_commit
673+
674+
assert_success
675+
676+
assert_line "INPUT_REPOSITORY value: ${INPUT_REPOSITORY}"
677+
assert_line "::set-output name=changes_detected::true"
678+
assert_line -e "::set-output name=commit_hash::[0-9a-f]{40}$"
679+
assert_line "INPUT_BRANCH value: existing-remote-branch"
680+
assert_line "INPUT_FILE_PATTERN: ."
681+
assert_line "INPUT_COMMIT_OPTIONS: "
682+
assert_line "::debug::Apply commit options "
683+
assert_line "INPUT_TAGGING_MESSAGE: "
684+
assert_line "No tagging message supplied. No tag will be added."
685+
assert_line "INPUT_PUSH_OPTIONS: "
686+
assert_line "::debug::Apply push options "
687+
assert_line "::debug::Push commit to remote branch existing-remote-branch"
688+
689+
run git branch
690+
assert_line --partial "existing-remote-branch"
691+
692+
run git branch -r
693+
assert_line --partial "origin/existing-remote-branch"
694+
695+
# Assert that branch "existing-remote-branch" was updated on remote
696+
current_sha="$(git rev-parse --verify --short existing-remote-branch)"
697+
remote_sha="$(git rev-parse --verify --short origin/existing-remote-branch)"
698+
699+
assert_equal $current_sha $remote_sha;
700+
}
701+
702+
@test "script fails if new local branch is checked out and push fails as remote has newer commits than local" {
703+
# Create `existing-remote-branch` on remote with changes the local repository does not yet have
704+
cd $FAKE_TEMP_LOCAL_REPOSITORY;
705+
git checkout -b "existing-remote-branch"
706+
touch new-branch-file.txt
707+
git add new-branch-file.txt
708+
git commit -m "Add additional file";
709+
git push origin existing-remote-branch;
710+
711+
run git branch;
712+
assert_line --partial "existing-remote-branch"
713+
714+
# ---------
715+
# Switch to our regular local repository and run `git-auto-commit`
716+
cd $FAKE_LOCAL_REPOSITORY;
717+
718+
INPUT_BRANCH="existing-remote-branch"
719+
INPUT_CREATE_BRANCH=true
720+
721+
run git branch
722+
refute_line --partial "existing-remote-branch"
723+
724+
run git fetch --all;
725+
run git branch -r;
726+
assert_line --partial "origin/existing-remote-branch"
727+
728+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
729+
730+
run git_auto_commit
731+
732+
assert_failure
733+
734+
assert_line "hint: Updates were rejected because the tip of your current branch is behind"
735+
736+
# Assert that branch exists locally and on remote
737+
run git branch
738+
assert_line --partial "existing-remote-branch"
739+
740+
run git branch -r
741+
assert_line --partial "origin/existing-remote-branch"
742+
743+
# Assert that branch "existing-remote-branch" was not updated on remote
744+
current_sha="$(git rev-parse --verify --short existing-remote-branch)"
745+
remote_sha="$(git rev-parse --verify --short origin/existing-remote-branch)"
746+
747+
refute [assert_equal $current_sha $remote_sha];
748+
}
749+
750+
@test "It pushes commit to remote if branch already exists and local repo is behind its remote counterpart" {
751+
# Create `new-branch` on remote with changes the local repository does not yet have
752+
cd $FAKE_TEMP_LOCAL_REPOSITORY;
753+
754+
git checkout -b "new-branch"
755+
touch new-branch-file.txt
756+
git add new-branch-file.txt
757+
758+
git commit --quiet -m "Add additional file";
759+
git push origin new-branch;
760+
761+
run git branch -r
762+
assert_line --partial "origin/new-branch"
763+
764+
# ---------
765+
# Switch to our regular local repository and run `git-auto-commit`
766+
cd $FAKE_LOCAL_REPOSITORY;
767+
768+
INPUT_BRANCH="new-branch"
769+
770+
# Assert that local remote does not know have "new-branch" locally nor does
771+
# know about the remote branch.
772+
run git branch
773+
refute_line --partial "new-branch"
774+
775+
run git branch -r
776+
refute_line --partial "origin/new-branch"
777+
778+
touch "${FAKE_LOCAL_REPOSITORY}"/new-file-{1,2,3}.txt
779+
780+
run git_auto_commit
781+
782+
assert_success
783+
784+
assert_line "INPUT_BRANCH value: new-branch"
785+
assert_line --partial "::debug::Push commit to remote branch new-branch"
786+
787+
# Assert that branch "new-branch" was updated on remote
788+
current_sha="$(git rev-parse --verify --short new-branch)"
789+
remote_sha="$(git rev-parse --verify --short origin/new-branch)"
790+
791+
assert_equal $current_sha $remote_sha;
792+
}

0 commit comments

Comments
 (0)