@neferbyte/cherry-release-cli 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/cherry-release +80 -23
  2. package/package.json +1 -1
@@ -3,12 +3,41 @@ set -e
3
3
 
4
4
  # ─── Constants ────────────────────────────────────────────────────────────────
5
5
 
6
- BRANCHES=(staging production)
6
+ ALL_BRANCHES=(development staging production)
7
7
  ORIGINAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
8
8
  WORKTREE_DIR="/tmp/cherry-release-test"
9
9
  WORKTREES_TO_CLEAN=()
10
10
  SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
11
11
 
12
+ # ─── Parse --force flag ──────────────────────────────────────────────────────
13
+
14
+ FORCE_ALL=false
15
+ declare -A FORCE_BRANCH
16
+ for b in "${ALL_BRANCHES[@]}"; do FORCE_BRANCH[$b]=false; done
17
+
18
+ if [[ "$1" == "--force" ]]; then
19
+ shift
20
+ if [[ $# -eq 0 ]]; then
21
+ FORCE_ALL=true
22
+ else
23
+ for arg in "$@"; do
24
+ found=false
25
+ for b in "${ALL_BRANCHES[@]}"; do
26
+ if [[ "$arg" == "$b" ]]; then
27
+ FORCE_BRANCH[$b]=true
28
+ found=true
29
+ break
30
+ fi
31
+ done
32
+ if [[ "$found" == false ]]; then
33
+ echo -e "\033[1;31mError:\033[0m Unknown branch '$arg'. Valid branches: ${ALL_BRANCHES[*]}" >&2
34
+ exit 1
35
+ fi
36
+ done
37
+ shift $#
38
+ fi
39
+ fi
40
+
12
41
  # ─── Helpers ──────────────────────────────────────────────────────────────────
13
42
 
14
43
  fail() {
@@ -24,6 +53,15 @@ check_ok() {
24
53
  echo -e " \033[1;32m✓\033[0m $1"
25
54
  }
26
55
 
56
+ should_deploy() {
57
+ local branch=$1
58
+ local commit_count=$2
59
+ [[ "$FORCE_ALL" == true ]] && return 0
60
+ [[ "${FORCE_BRANCH[$branch]}" == true ]] && return 0
61
+ [[ "$commit_count" -gt 0 ]] && return 0
62
+ return 1
63
+ }
64
+
27
65
  cleanup() {
28
66
  for wt in "${WORKTREES_TO_CLEAN[@]}"; do
29
67
  if [[ -d "$wt" ]]; then
@@ -79,7 +117,7 @@ fi
79
117
  check_ok "development can fast-forward to origin"
80
118
 
81
119
  # 6. staging and production have no local-only commits ahead of origin
82
- for branch in "${BRANCHES[@]}"; do
120
+ for branch in staging production; do
83
121
  local_ref=$(git rev-parse "$branch" 2>/dev/null || true)
84
122
  remote_ref=$(git rev-parse "origin/$branch" 2>/dev/null || true)
85
123
 
@@ -96,7 +134,7 @@ check_ok "No local-only commits on staging/production"
96
134
 
97
135
  # 7. Auto-discover commits to promote (per target branch)
98
136
  declare -A COMMITS_FOR
99
- for branch in "${BRANCHES[@]}"; do
137
+ for branch in staging production; do
100
138
  hashes=$(git cherry "origin/$branch" origin/development | grep '^+' | awk '{print $2}')
101
139
 
102
140
  # Filter out version bump commits (commit-and-tag-version)
@@ -114,15 +152,27 @@ done
114
152
  staging_count=$(echo "${COMMITS_FOR[staging]}" | wc -w | tr -d ' ')
115
153
  production_count=$(echo "${COMMITS_FOR[production]}" | wc -w | tr -d ' ')
116
154
 
117
- if [[ "$staging_count" -eq 0 && "$production_count" -eq 0 ]]; then
118
- echo -e "\n\033[1;32mNothing to promote.\033[0m staging and production are up to date."
155
+ # Check if there's anything to do
156
+ has_work=false
157
+ for branch in "${ALL_BRANCHES[@]}"; do
158
+ count=0
159
+ [[ "$branch" == "staging" ]] && count=$staging_count
160
+ [[ "$branch" == "production" ]] && count=$production_count
161
+ if should_deploy "$branch" "$count"; then
162
+ has_work=true
163
+ break
164
+ fi
165
+ done
166
+
167
+ if [[ "$has_work" == false ]]; then
168
+ echo -e "\n\033[1;32mNothing to do.\033[0m All branches are up to date."
119
169
  exit 0
120
170
  fi
121
171
 
122
172
  check_ok "Discovered commits to promote (staging: $staging_count, production: $production_count)"
123
173
 
124
174
  # 8. Dry-run cherry-picks in temporary worktrees
125
- for branch in "${BRANCHES[@]}"; do
175
+ for branch in staging production; do
126
176
  commits=(${COMMITS_FOR[$branch]})
127
177
  if [[ ${#commits[@]} -eq 0 ]]; then
128
178
  continue
@@ -155,24 +205,29 @@ echo -e "\n\033[1;32mAll pre-flight checks passed.\033[0m"
155
205
  # ─── Phase 2: Execution ──────────────────────────────────────────────────────
156
206
 
157
207
  # --- development ---
158
- step "Deploying to development"
159
-
160
- git checkout development
161
- git pull --ff-only
162
- "$SCRIPT_DIR/cherry-release-version" patch
163
- git push --follow-tags origin development
164
- echo -e " \033[1;32m✓\033[0m development released"
208
+ if should_deploy "development" "$staging_count"; then
209
+ step "Deploying to development"
210
+ git checkout development
211
+ git pull --ff-only
212
+ "$SCRIPT_DIR/cherry-release-version" patch
213
+ git push --follow-tags origin development
214
+ echo -e " \033[1;32m✓\033[0m development released"
215
+ else
216
+ echo -e "\n\033[1;34m→\033[0m Skipping development (up to date)"
217
+ fi
165
218
 
166
219
  # --- staging ---
167
220
  staging_commits=(${COMMITS_FOR[staging]})
168
- if [[ ${#staging_commits[@]} -gt 0 ]]; then
221
+ if should_deploy "staging" "${#staging_commits[@]}"; then
169
222
  step "Deploying to staging (${#staging_commits[@]} commit(s))"
170
223
  git checkout staging
171
224
  git reset --hard origin/staging --quiet
172
- for hash in "${staging_commits[@]}"; do
173
- git cherry-pick "$hash"
174
- done
175
- git push origin staging
225
+ if [[ ${#staging_commits[@]} -gt 0 ]]; then
226
+ for hash in "${staging_commits[@]}"; do
227
+ git cherry-pick "$hash"
228
+ done
229
+ git push origin staging
230
+ fi
176
231
  "$SCRIPT_DIR/cherry-release-version" patch
177
232
  git push --follow-tags origin staging
178
233
  echo -e " \033[1;32m✓\033[0m staging released"
@@ -182,14 +237,16 @@ fi
182
237
 
183
238
  # --- production ---
184
239
  production_commits=(${COMMITS_FOR[production]})
185
- if [[ ${#production_commits[@]} -gt 0 ]]; then
240
+ if should_deploy "production" "${#production_commits[@]}"; then
186
241
  step "Deploying to production (${#production_commits[@]} commit(s))"
187
242
  git checkout production
188
243
  git reset --hard origin/production --quiet
189
- for hash in "${production_commits[@]}"; do
190
- git cherry-pick "$hash"
191
- done
192
- git push origin production
244
+ if [[ ${#production_commits[@]} -gt 0 ]]; then
245
+ for hash in "${production_commits[@]}"; do
246
+ git cherry-pick "$hash"
247
+ done
248
+ git push origin production
249
+ fi
193
250
  "$SCRIPT_DIR/cherry-release-version" patch
194
251
  git push --follow-tags origin production
195
252
  echo -e " \033[1;32m✓\033[0m production released"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neferbyte/cherry-release-cli",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Cherry-pick commits across environment branches and tag releases",
5
5
  "license": "MIT",
6
6
  "bin": {