Skip to content

Commit d0b0110

Browse files
Accept repositories where .git is a file (#417)
The repository check used `[ -d ".git" ]`, which fails for git submodules, linked worktrees and clones made with `--separate-git-dir`. In those cases `.git` is a file that points to the actual git directory. Use `-e` instead so both forms are accepted. Also escape the backticks around `repository` in the error message. Unescaped, bash ran `repository` as a command substitution and the input name was missing from the message. Add tests for submodules (absolute and relative path), `--separate-git-dir`, linked worktrees, the error message and a non-existing repository directory. Fixes #416
1 parent 9264814 commit d0b0110

2 files changed

Lines changed: 139 additions & 3 deletions

File tree

‎entrypoint.sh‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,11 @@ _git_is_dirty() {
139139
}
140140

141141
_check_if_is_git_repository() {
142-
if [ -d ".git" ]; then
142+
# `.git` is a file (not a directory) in submodules and linked worktrees.
143+
if [ -e ".git" ]; then
143144
_log "debug" "Repository found.";
144145
else
145-
_log "error" "Not a git repository. Please make sure to run this action in a git repository. Adjust the `repository` input if necessary.";
146+
_log "error" "Not a git repository. Please make sure to run this action in a git repository. Adjust the \`repository\` input if necessary.";
146147
exit 1;
147148
fi
148149
}

‎tests/git-auto-commit.bats‎

Lines changed: 136 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,142 @@ END
11311131
run git_auto_commit
11321132

11331133
assert_failure;
1134-
assert_line "::error::Not a git repository. Please make sure to run this action in a git repository. Adjust the `repository` input if necessary."
1134+
assert_line "::error::Not a git repository. Please make sure to run this action in a git repository. Adjust the \`repository\` input if necessary."
1135+
}
1136+
1137+
@test "It does not treat the error message for a missing git repository as a shell command" {
1138+
INPUT_REPOSITORY="${FAKE_FOLDER_WITHOUT_GIT_REPO}"
1139+
1140+
mkdir "${INPUT_REPOSITORY}"
1141+
1142+
run git_auto_commit
1143+
1144+
assert_failure;
1145+
refute_output --partial "command not found"
1146+
}
1147+
1148+
@test "It exits with error message if the repository input points to a non-existing directory" {
1149+
INPUT_REPOSITORY="${FAKE_FOLDER_WITHOUT_GIT_REPO}/does-not-exist"
1150+
1151+
run git_auto_commit
1152+
1153+
assert_failure;
1154+
}
1155+
1156+
@test "It commits and pushes changes in a git submodule" {
1157+
FAKE_SUPERPROJECT="${BATS_TEST_DIRNAME}/tests_superproject"
1158+
rm -rf "${FAKE_SUPERPROJECT}"
1159+
git init --quiet "${FAKE_SUPERPROJECT}"
1160+
cd "${FAKE_SUPERPROJECT}"
1161+
git -c protocol.file.allow=always submodule add --quiet "${FAKE_REMOTE}" posts
1162+
git commit --quiet -m "Add submodule"
1163+
1164+
# In a submodule `.git` is a file pointing to the superproject's `.git/modules` directory
1165+
assert [ -f "${FAKE_SUPERPROJECT}/posts/.git" ]
1166+
assert [ ! -d "${FAKE_SUPERPROJECT}/posts/.git" ]
1167+
1168+
cd "${FAKE_SUPERPROJECT}/posts"
1169+
git checkout --quiet "${FAKE_DEFAULT_BRANCH}"
1170+
cd "${FAKE_SUPERPROJECT}"
1171+
1172+
INPUT_REPOSITORY="${FAKE_SUPERPROJECT}/posts"
1173+
touch "${INPUT_REPOSITORY}"/new-file-{1,2,3}.txt
1174+
1175+
run git_auto_commit
1176+
1177+
assert_success
1178+
refute_output --partial "Not a git repository"
1179+
assert_line "::debug::Repository found."
1180+
1181+
run cat_github_output
1182+
assert_line "changes_detected=true"
1183+
assert_line -e "commit_hash=[0-9a-f]{40}$"
1184+
1185+
# The commit has been pushed to the submodule's remote
1186+
run git --git-dir="${FAKE_REMOTE}" log -n 1 --pretty=%s
1187+
assert_output "Commit Message"
1188+
1189+
run git --git-dir="${FAKE_REMOTE}" ls-tree --name-only -r "${FAKE_DEFAULT_BRANCH}"
1190+
assert_line "new-file-1.txt"
1191+
1192+
rm -rf "${FAKE_SUPERPROJECT}"
1193+
}
1194+
1195+
@test "It uses a relative path to a git submodule as repository" {
1196+
FAKE_SUPERPROJECT="${BATS_TEST_DIRNAME}/tests_superproject"
1197+
rm -rf "${FAKE_SUPERPROJECT}"
1198+
git init --quiet "${FAKE_SUPERPROJECT}"
1199+
cd "${FAKE_SUPERPROJECT}"
1200+
git -c protocol.file.allow=always submodule add --quiet "${FAKE_REMOTE}" posts
1201+
git commit --quiet -m "Add submodule"
1202+
git -C posts checkout --quiet "${FAKE_DEFAULT_BRANCH}"
1203+
1204+
INPUT_REPOSITORY="posts"
1205+
touch "${FAKE_SUPERPROJECT}"/posts/new-file-{1,2,3}.txt
1206+
1207+
run git_auto_commit
1208+
1209+
assert_success
1210+
assert_line "::debug::Repository found."
1211+
1212+
run git --git-dir="${FAKE_REMOTE}" ls-tree --name-only -r "${FAKE_DEFAULT_BRANCH}"
1213+
assert_line "new-file-1.txt"
1214+
1215+
rm -rf "${FAKE_SUPERPROJECT}"
1216+
INPUT_REPOSITORY="${FAKE_LOCAL_REPOSITORY}"
1217+
}
1218+
1219+
@test "It accepts a repository whose .git is a file pointing to a separate git directory" {
1220+
SEPARATE_GIT_DIR="${BATS_TEST_DIRNAME}/tests_separate_git_dir"
1221+
WORK_TREE="${BATS_TEST_DIRNAME}/tests_separate_work_tree"
1222+
rm -rf "${SEPARATE_GIT_DIR}" "${WORK_TREE}"
1223+
1224+
git clone --quiet --separate-git-dir="${SEPARATE_GIT_DIR}" "${FAKE_REMOTE}" "${WORK_TREE}"
1225+
1226+
assert [ -f "${WORK_TREE}/.git" ]
1227+
1228+
INPUT_REPOSITORY="${WORK_TREE}"
1229+
touch "${WORK_TREE}"/new-file-{1,2,3}.txt
1230+
1231+
run git_auto_commit
1232+
1233+
assert_success
1234+
assert_line "::debug::Repository found."
1235+
1236+
run cat_github_output
1237+
assert_line "changes_detected=true"
1238+
1239+
run git --git-dir="${FAKE_REMOTE}" ls-tree --name-only -r "${FAKE_DEFAULT_BRANCH}"
1240+
assert_line "new-file-1.txt"
1241+
1242+
rm -rf "${SEPARATE_GIT_DIR}" "${WORK_TREE}"
1243+
INPUT_REPOSITORY="${FAKE_LOCAL_REPOSITORY}"
1244+
}
1245+
1246+
@test "It accepts a linked git worktree as repository" {
1247+
WORKTREE="${BATS_TEST_DIRNAME}/tests_linked_worktree"
1248+
rm -rf "${WORKTREE}"
1249+
1250+
cd "${FAKE_LOCAL_REPOSITORY}"
1251+
git worktree add --quiet -b worktree-branch "${WORKTREE}"
1252+
1253+
assert [ -f "${WORKTREE}/.git" ]
1254+
1255+
INPUT_REPOSITORY="${WORKTREE}"
1256+
INPUT_BRANCH="worktree-branch"
1257+
touch "${WORKTREE}"/new-file-{1,2,3}.txt
1258+
1259+
run git_auto_commit
1260+
1261+
assert_success
1262+
assert_line "::debug::Repository found."
1263+
1264+
run git --git-dir="${FAKE_REMOTE}" ls-tree --name-only -r worktree-branch
1265+
assert_line "new-file-1.txt"
1266+
1267+
cd "${FAKE_LOCAL_REPOSITORY}"
1268+
git worktree remove --force "${WORKTREE}"
1269+
INPUT_REPOSITORY="${FAKE_LOCAL_REPOSITORY}"
11351270
}
11361271

11371272
@test "It detects if the repository is in a detached state and logs a warning" {

0 commit comments

Comments
 (0)