Skip to content

Commit 9ad6777

Browse files
feat: add configurable options for branch reset and commit behavior (#196)
Co-authored-by: ChristophShyper <45788587+ChristophShyper@users.noreply.github.com>
1 parent bc3d0ff commit 9ad6777

3 files changed

Lines changed: 93 additions & 41 deletions

File tree

README.md

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
- **🔄 Integration-ready:** Works seamlessly with other DevOps workflows
1515
- **💪 Force push options:** Support for `--force` and `--force-with-lease` when needed
1616
- **🔀 Pull request integration:** Perfect companion for automated PR workflows
17+
- **🎯 Deterministic branch reset:** Optionally reset target branches to a chosen base branch before committing
18+
- **🧩 Empty commit support:** Optionally create empty commits for no-diff automation flows
19+
- **🛡️ Rebase conflict control:** Choose strict failure or legacy best-effort behavior on rebase conflicts
1720

1821

1922
## 🔗 Related Actions
@@ -65,18 +68,22 @@ This action supports three tag levels for flexible versioning:
6568
6669
6770
### 🔧 Input Parameters
68-
| Input Variable | Required | Default | Description |
69-
|-----------------------|----------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
70-
| `github_token` | Yes | `""` | Personal Access Token for GitHub for pushing the code. |
71-
| `add_timestamp` | No | `false` | Whether to add the timestamp to a new branch name. Uses format `%Y-%m-%dT%H-%M-%SZ`. |
72-
| `amend` | No | `false` | Whether to make an amendment to the previous commit (`--amend`). Can be combined with `commit_message` to change the commit message. |
73-
| `commit_prefix` | No | `""` | Prefix added to commit message. Combines with `commit_message`. |
74-
| `commit_message` | No | `""` | Commit message to set. Combines with `commit_prefix`. Can be used with `amend` to change the commit message. |
75-
| `force` | No | `false` | Whether to use force push (`--force`). Use only when you need to overwrite remote changes. Potentially dangerous. |
76-
| `force_with_lease` | No | `false` | Whether to use force push with lease (`--force-with-lease`). Safer than `force` as it checks for remote changes. Set `fetch-depth: 0` for `actions/checkout`. |
77-
| `no_edit` | No | `false` | Whether to not edit commit message when using amend (`--no-edit`). |
78-
| `organization_domain` | No | `github.com` | GitHub Enterprise domain name. |
79-
| `target_branch` | No | *current branch* | Name of a new branch to push the code into. Creates branch if not existing unless there are no changes and `amend` is false. |
71+
| Input Variable | Required | Default | Description |
72+
|---------------------------|----------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|
73+
| `github_token` | Yes | `""` | Personal Access Token for GitHub for pushing the code. |
74+
| `add_timestamp` | No | `false` | Whether to add the timestamp to a new branch name. Uses format `%Y-%m-%dT%H-%M-%SZ`. |
75+
| `amend` | No | `false` | Whether to make an amendment to the previous commit (`--amend`). Can be combined with `commit_message` to change the commit message. |
76+
| `commit_prefix` | No | `""` | Prefix added to commit message. Combines with `commit_message`. |
77+
| `commit_message` | No | `""` | Commit message to set. Combines with `commit_prefix`. Can be used with `amend` to change the commit message. |
78+
| `force` | No | `false` | Whether to use force push (`--force`). Use only when you need to overwrite remote changes. Potentially dangerous. |
79+
| `force_with_lease` | No | `false` | Whether to use force push with lease (`--force-with-lease`). Safer than `force` as it checks for remote changes. Set `fetch-depth: 0` for `actions/checkout`. |
80+
| `base_branch` | No | `""` | Base branch used to sync or reset `target_branch`. When empty, the action auto-detects `main`/`master` or origin HEAD. |
81+
| `reset_target_branch` | No | `false` | Whether to hard-reset `target_branch` to `origin/base_branch` before committing. Recommended for deterministic release branches. |
82+
| `allow_empty_commit` | No | `false` | Whether to create an empty commit when there are no file changes. Useful for workflows that must open a PR with no file diff. |
83+
| `fail_on_rebase_conflict` | No | `true` | Whether to fail the action if rebase onto `base_branch` conflicts. Set to `false` to keep legacy best-effort rebase behavior. |
84+
| `no_edit` | No | `false` | Whether to not edit commit message when using amend (`--no-edit`). |
85+
| `organization_domain` | No | `github.com` | GitHub Enterprise domain name. |
86+
| `target_branch` | No | *current branch* | Name of a new branch to push the code into. Creates branch if not existing unless there are no changes and `amend` is false. |
8087

8188

8289
### 📤 Output Parameters

action.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,22 @@ inputs:
3030
description: Whether to use force push with lease (--force-with-lease). Safer than force as it checks for remote changes.
3131
required: false
3232
default: "false"
33+
base_branch:
34+
description: Base branch name used for branch sync/reset (defaults to auto-detected main/master).
35+
required: false
36+
default: ""
37+
reset_target_branch:
38+
description: Whether to hard-reset target branch to origin/base_branch before committing.
39+
required: false
40+
default: "false"
41+
allow_empty_commit:
42+
description: Whether to allow creating an empty commit when there are no file changes.
43+
required: false
44+
default: "false"
45+
fail_on_rebase_conflict:
46+
description: Whether to fail when branch rebase onto base branch conflicts.
47+
required: false
48+
default: "true"
3349
no_edit:
3450
description: Whether to not edit commit message when using amend
3551
required: false

entrypoint.sh

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,19 @@ set -e
66
RET_CODE=0
77

88
echo "Inputs:"
9-
echo " add_timestamp: ${INPUT_ADD_TIMESTAMP}"
10-
echo " amend: ${INPUT_AMEND}"
11-
echo " commit_prefix: ${INPUT_COMMIT_PREFIX}"
12-
echo " commit_message: ${INPUT_COMMIT_MESSAGE}"
13-
echo " force: ${INPUT_FORCE}"
14-
echo " force_with_lease: ${INPUT_FORCE_WITH_LEASE}"
15-
echo " no_edit: ${INPUT_NO_EDIT}"
16-
echo " organization_domain: ${INPUT_ORGANIZATION_DOMAIN}"
17-
echo " target_branch: ${INPUT_TARGET_BRANCH}"
9+
echo " add_timestamp: ${INPUT_ADD_TIMESTAMP}"
10+
echo " amend: ${INPUT_AMEND}"
11+
echo " commit_prefix: ${INPUT_COMMIT_PREFIX}"
12+
echo " commit_message: ${INPUT_COMMIT_MESSAGE}"
13+
echo " force: ${INPUT_FORCE}"
14+
echo " force_with_lease: ${INPUT_FORCE_WITH_LEASE}"
15+
echo " base_branch: ${INPUT_BASE_BRANCH}"
16+
echo " reset_target_branch: ${INPUT_RESET_TARGET_BRANCH}"
17+
echo " allow_empty_commit: ${INPUT_ALLOW_EMPTY_COMMIT}"
18+
echo " fail_on_rebase_conflict: ${INPUT_FAIL_ON_REBASE_CONFLICT}"
19+
echo " no_edit: ${INPUT_NO_EDIT}"
20+
echo " organization_domain: ${INPUT_ORGANIZATION_DOMAIN}"
21+
echo " target_branch: ${INPUT_TARGET_BRANCH}"
1822

1923
# Require github_token
2024
if [[ -z "${GITHUB_TOKEN}" ]]; then
@@ -40,6 +44,13 @@ get_current_branch() {
4044
printf '%s' "${branch}"
4145
}
4246

47+
input_true() {
48+
case "${1:-}" in
49+
true|TRUE|True|1|yes|YES|Yes|on|ON|On) return 0 ;;
50+
*) return 1 ;;
51+
esac
52+
}
53+
4354
# Get changed files
4455
git add -A
4556
FILES_CHANGED=$(git diff --staged --name-status)
@@ -50,7 +61,7 @@ else
5061
fi
5162

5263
SKIP_BRANCH_CREATION=false
53-
if [[ -z ${FILES_CHANGED} && "${INPUT_AMEND}" != "true" ]]; then
64+
if [[ -z ${FILES_CHANGED} && "${INPUT_AMEND}" != "true" && -z "${INPUT_TARGET_BRANCH}" ]] && ! input_true "${INPUT_ALLOW_EMPTY_COMMIT}"; then
5465
SKIP_BRANCH_CREATION=true
5566
BRANCH="$(get_current_branch)"
5667
echo -e "\n[INFO] No changes to commit and amend disabled; skipping branch creation."
@@ -81,15 +92,18 @@ if [[ "${SKIP_BRANCH_CREATION}" != "true" ]]; then
8192
# Check if remote branch exists
8293
REMOTE_BRANCH_EXISTS=$(git ls-remote --heads origin "${BRANCH}" 2>/dev/null | wc -l)
8394

84-
# Improved main branch detection
85-
MAIN_BRANCH="main"
86-
if git show-ref --verify --quiet "refs/remotes/origin/main"; then
95+
# Improved main branch detection with explicit override
96+
MAIN_BRANCH="${INPUT_BASE_BRANCH}"
97+
if [[ -z "${MAIN_BRANCH}" ]]; then
8798
MAIN_BRANCH="main"
88-
elif git show-ref --verify --quiet "refs/remotes/origin/master"; then
89-
MAIN_BRANCH="master"
90-
else
91-
# Try to get default branch from remote HEAD
92-
MAIN_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
99+
if git show-ref --verify --quiet "refs/remotes/origin/main"; then
100+
MAIN_BRANCH="main"
101+
elif git show-ref --verify --quiet "refs/remotes/origin/master"; then
102+
MAIN_BRANCH="master"
103+
else
104+
# Try to get default branch from remote HEAD
105+
MAIN_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
106+
fi
93107
fi
94108
echo "[INFO] Detected main branch: ${MAIN_BRANCH}"
95109

@@ -110,15 +124,28 @@ if [[ "${SKIP_BRANCH_CREATION}" != "true" ]]; then
110124
}
111125
fi
112126

113-
# Ensure branch is up-to-date with main/master (only if they're different branches)
127+
# Ensure branch is synchronized with base branch
114128
if [[ "${BRANCH}" != "${MAIN_BRANCH}" ]] && git show-ref --verify --quiet "refs/remotes/origin/${MAIN_BRANCH}"; then
115-
echo "[INFO] Rebasing branch onto ${MAIN_BRANCH}..."
116-
git rebase "origin/${MAIN_BRANCH}" || {
117-
echo "[WARNING] Rebase onto ${MAIN_BRANCH} failed. This may indicate conflicts."
118-
echo "[INFO] Attempting to abort the rebase and continue without sync..."
119-
git rebase --abort 2>/dev/null || true
120-
echo "[INFO] Branch will remain at its current state without sync to ${MAIN_BRANCH}"
121-
}
129+
if input_true "${INPUT_RESET_TARGET_BRANCH}"; then
130+
echo "[INFO] Hard resetting '${BRANCH}' to origin/${MAIN_BRANCH}..."
131+
git reset --hard "origin/${MAIN_BRANCH}" || {
132+
echo "[ERROR] Failed to hard reset '${BRANCH}' to origin/${MAIN_BRANCH}"
133+
exit 1
134+
}
135+
else
136+
echo "[INFO] Rebasing branch onto ${MAIN_BRANCH}..."
137+
git rebase "origin/${MAIN_BRANCH}" || {
138+
if input_true "${INPUT_FAIL_ON_REBASE_CONFLICT}"; then
139+
echo "[ERROR] Rebase onto ${MAIN_BRANCH} failed and fail_on_rebase_conflict=true"
140+
git rebase --abort 2>/dev/null || true
141+
exit 1
142+
fi
143+
echo "[WARNING] Rebase onto ${MAIN_BRANCH} failed."
144+
echo "[INFO] Attempting to abort the rebase and continue without sync..."
145+
git rebase --abort 2>/dev/null || true
146+
echo "[INFO] Branch will remain at its current state without sync to ${MAIN_BRANCH}"
147+
}
148+
fi
122149
fi
123150
else
124151
echo "[INFO] Remote branch '${BRANCH}' does not exist, creating new branch..."
@@ -142,10 +169,12 @@ fi
142169

143170
# Create an auto commit
144171
COMMIT_PARAMS=()
145-
COMMIT_PARAMS+=("--allow-empty")
172+
if input_true "${INPUT_ALLOW_EMPTY_COMMIT}"; then
173+
COMMIT_PARAMS+=("--allow-empty")
174+
fi
146175

147-
# Commit if there are changes OR if we're amending (even without changes)
148-
if [[ -n ${FILES_CHANGED} || "${INPUT_AMEND}" == "true" ]]; then
176+
# Commit if there are changes, or amend is requested, or empty commit is allowed
177+
if [[ -n ${FILES_CHANGED} || "${INPUT_AMEND}" == "true" ]] || input_true "${INPUT_ALLOW_EMPTY_COMMIT}"; then
149178
if [[ -n ${FILES_CHANGED} ]]; then
150179
echo "[INFO] Committing changes."
151180
fi

0 commit comments

Comments
 (0)