@@ -91,6 +91,7 @@ Options:
9191 --patch bump patch version
9292 --preserve-summary preserve summary file (override default behavior)
9393 --remove-summary rename/remove summary file (override default behavior)
94+ --allow-unclean allow uncommitted changes for dry runs only (not default)
9495
9596Summary File Behavior:
9697 Default: Dry-runs preserve summary file, real releases rename it
@@ -180,6 +181,7 @@ main() {
180181 bump_type=" minor"
181182 preserve_summary=" false"
182183 remove_summary=" false"
184+ allow_unclean=" false"
183185
184186 # Parse options using zparseopts for strict parameter validation
185187 declare -A opts
@@ -197,6 +199,7 @@ main() {
197199 -debug \
198200 -preserve-summary \
199201 -remove-summary \
202+ -allow-unclean \
200203 || {
201204 # Unknown option
202205 print_error " Unknown option: $@ "
@@ -241,31 +244,49 @@ main() {
241244 --remove-summary)
242245 remove_summary=" true"
243246 ;;
247+ --allow-unclean)
248+ allow_unclean=" true"
249+ ;;
244250 esac
245251 done
246252
247253 # Check for uncommitted changes in scripts/release/
248254 if [[ -n $( git status --porcelain scripts/release/) ]]; then
249- print_error " Uncommitted changes detected in scripts/release/. Please commit all changes in the release tree before running a release."
250- exit 1
255+ if [[ " $dry_run " == " true" && " $allow_unclean " == " true" ]]; then
256+ print_warning " Uncommitted changes detected in scripts/release/, but --allow-unclean is set and this is a dry run. Proceeding anyway."
257+ else
258+ print_error " Uncommitted changes detected in scripts/release/. Please commit all changes in the release tree before running a release."
259+ exit 1
260+ fi
251261 fi
252262 # Check for uncommitted changes in .github/workflows
253263 if [[ -n $( git status --porcelain .github/workflows/) ]]; then
254- print_error " Uncommitted changes detected in .github/workflows/. Please commit all changes in the workflow tree before running a release."
255- exit 1
264+ if [[ " $dry_run " == " true" && " $allow_unclean " == " true" ]]; then
265+ print_warning " Uncommitted changes detected in .github/workflows/, but --allow-unclean is set and this is a dry run. Proceeding anyway."
266+ else
267+ print_error " Uncommitted changes detected in .github/workflows/. Please commit all changes in the workflow tree before running a release."
268+ exit 1
269+ fi
256270 fi
257271
258- # Check for required major changes summary file
272+ # --- Major changes summary file check (existence only) ---
273+ local base_version=" "
274+ local summary_file=" "
275+ local new_summary_file=" "
276+ local should_rename=false
259277 if [[ -n " $prev_version " ]]; then
260- local required_summary_file=" docs/release/latest-major-changes-since-${prev_version} .md"
261- if [[ ! -f " $required_summary_file " ]]; then
262- print_error " Required major changes summary file missing: $required_summary_file "
263- print_error " AI must create this file before any release or dry run."
264- print_error " This file must contain a summary of major changes since version $prev_version ."
278+ base_version=" $prev_version "
279+ summary_file=" docs/release/latest-major-changes-since-${base_version} .md"
280+ # new_summary_file will be set after version bump
281+ if [[ ! -f " $summary_file " ]]; then
282+ print_error " No major changes summary file found for base $base_version "
283+ print_error " AI must create docs/release/latest-major-changes-since-${base_version} .md before any release or dry run"
284+ print_error " This file must contain a summary of major changes since version $base_version "
265285 exit 1
266286 fi
267- print_success " Found required summary file: $required_summary_file "
287+ print_success " Found required summary file: $summary_file "
268288 fi
289+ # --- End major changes summary file check ---
269290
270291 check_prerequisites
271292
@@ -293,113 +314,11 @@ main() {
293314 fi
294315 print_success " Intended new version: $intended_new_version "
295316
296- # --- Major changes summary file handling ---
297- if [[ -n " $prev_version " ]]; then
298- local base_version=" $prev_version "
299- local summary_file=" docs/release/latest-major-changes-since-${base_version} .md"
300- local new_summary_file=" docs/release/${intended_new_version} -major-changes-since-${base_version} .md"
301-
302- if [[ -f " $summary_file " ]]; then
303- # Determine whether to rename the summary file based on flags and run type
304- local should_rename=false
305-
306- # Default behavior: dry-runs preserve, real releases rename
307- if [[ " $dry_run " == " true" ]]; then
308- should_rename=false # Default: preserve for dry-runs
309- else
310- should_rename=true # Default: rename for real releases
311- fi
312-
313- # Override with explicit flags
314- if [[ " $preserve_summary " == " true" ]]; then
315- should_rename=false
316- print_status " Forcing summary file preservation (--preserve-summary)"
317- fi
318-
319- if [[ " $remove_summary " == " true" ]]; then
320- should_rename=true
321- print_status " Forcing summary file rename (--remove-summary)"
322- fi
323-
324- # Handle conflicting flags
325- if [[ " $preserve_summary " == " true" && " $remove_summary " == " true" ]]; then
326- print_error " Conflicting flags: --preserve-summary and --remove-summary cannot be used together"
327- exit 1
328- fi
329-
330- if [[ " $should_rename " == " true" ]]; then
331- # Always remove the target file if it exists to ensure clean rename
332- if [[ -f " $new_summary_file " ]]; then
333- print_warning " $new_summary_file already exists. Removing existing file."
334- rm -f " $new_summary_file "
335- if [[ -f " $new_summary_file " ]]; then
336- print_error " Failed to remove existing file: $new_summary_file "
337- exit 1
338- fi
339- fi
340-
341- print_status " Renaming $summary_file to $new_summary_file "
342-
343- # Perform the rename operation with explicit error checking
344- if mv " $summary_file " " $new_summary_file " 2> /dev/null; then
345- # Verify the rename actually succeeded
346- if [[ -f " $new_summary_file " && ! -f " $summary_file " ]]; then
347- print_success " Successfully renamed summary file"
348-
349- # Handle git operations with better error handling
350- if git add " $new_summary_file " 2> /dev/null; then
351- print_status " Added new summary file to git"
352- else
353- print_warning " Failed to add new summary file to git (may already be tracked)"
354- fi
355-
356- # Remove old file from git if it exists
357- if git rm " $summary_file " 2> /dev/null; then
358- print_status " Removed old summary file from git"
359- else
360- print_warning " Old summary file not in git (already removed or never tracked)"
361- fi
362-
363- # Commit the changes
364- if git commit -m " docs(release): rename major changes summary for release $intended_new_version (refs #68)" 2> /dev/null; then
365- print_status " Committed summary file rename"
366-
367- # Push the changes
368- if git push 2> /dev/null; then
369- print_success " Pushed summary file changes"
370- else
371- print_warning " Failed to push summary file changes (may already be up to date)"
372- fi
373- else
374- print_warning " Failed to commit summary file rename (no changes to commit)"
375- fi
376-
377- print_success " Committed and pushed $new_summary_file "
378- else
379- print_error " Rename operation appeared to succeed but file verification failed"
380- print_error " Expected: $new_summary_file to exist and $summary_file to not exist"
381- exit 1
382- fi
383- else
384- print_error " Failed to rename summary file from $summary_file to $new_summary_file "
385- print_error " This may be due to file system permissions or the target file being locked"
386- exit 1
387- fi
388- else
389- # Preserve the summary file
390- print_status " Preserving summary file: $summary_file "
391- print_success " Summary file will remain available for future runs"
392- fi
393- else
394- # Summary file doesn't exist - this is always an error
395- print_error " No major changes summary file found for base $base_version "
396- print_error " AI must create docs/release/latest-major-changes-since-${base_version} .md before any release or dry run"
397- print_error " This file must contain a summary of major changes since version $base_version "
398- exit 1
399- fi
317+ # Set new_summary_file for later use
318+ if [[ -n " $base_version " ]]; then
319+ new_summary_file=" docs/release/${intended_new_version} -major-changes-since-${base_version} .md"
400320 fi
401- # --- End major changes summary file handling ---
402-
321+
403322 # Step 2: Trigger release workflow
404323 print_status " Step 2: Triggering release workflow..."
405324 release_args=(--force)
@@ -485,6 +404,89 @@ main() {
485404 print_status " ==== END OF RELEASE NOTES ===="
486405 # Clean up
487406 rm -rf " $tmpdir "
407+
408+ # --- Major changes summary file handling (only after successful release) ---
409+ if [[ -n " $base_version " && -f " $summary_file " ]]; then
410+ # Determine whether to rename the summary file based on flags and run type
411+ should_rename=false
412+ # Default behavior: dry-runs preserve, real releases rename
413+ if [[ " $dry_run " == " true" ]]; then
414+ should_rename=false # Default: preserve for dry-runs
415+ else
416+ should_rename=true # Default: rename for real releases
417+ fi
418+ # Override with explicit flags
419+ if [[ " $preserve_summary " == " true" ]]; then
420+ should_rename=false
421+ print_status " Forcing summary file preservation (--preserve-summary)"
422+ fi
423+ if [[ " $remove_summary " == " true" ]]; then
424+ should_rename=true
425+ print_status " Forcing summary file rename (--remove-summary)"
426+ fi
427+ # Handle conflicting flags
428+ if [[ " $preserve_summary " == " true" && " $remove_summary " == " true" ]]; then
429+ print_error " Conflicting flags: --preserve-summary and --remove-summary cannot be used together"
430+ exit 1
431+ fi
432+ if [[ " $should_rename " == " true" ]]; then
433+ # Always remove the target file if it exists to ensure clean rename
434+ if [[ -f " $new_summary_file " ]]; then
435+ print_warning " $new_summary_file already exists. Removing existing file."
436+ rm -f " $new_summary_file "
437+ if [[ -f " $new_summary_file " ]]; then
438+ print_error " Failed to remove existing file: $new_summary_file "
439+ exit 1
440+ fi
441+ fi
442+ print_status " Renaming $summary_file to $new_summary_file "
443+ # Perform the rename operation with explicit error checking
444+ if mv " $summary_file " " $new_summary_file " 2> /dev/null; then
445+ # Verify the rename actually succeeded
446+ if [[ -f " $new_summary_file " && ! -f " $summary_file " ]]; then
447+ print_success " Successfully renamed summary file"
448+ # Handle git operations with better error handling
449+ if git add " $new_summary_file " 2> /dev/null; then
450+ print_status " Added new summary file to git"
451+ else
452+ print_warning " Failed to add new summary file to git (may already be tracked)"
453+ fi
454+ # Remove old file from git if it exists
455+ if git rm " $summary_file " 2> /dev/null; then
456+ print_status " Removed old summary file from git"
457+ else
458+ print_warning " Old summary file not in git (already removed or never tracked)"
459+ fi
460+ # Commit the changes
461+ if git commit -m " docs(release): rename major changes summary for release $intended_new_version (refs #68)" 2> /dev/null; then
462+ print_status " Committed summary file rename"
463+ # Push the changes
464+ if git push 2> /dev/null; then
465+ print_success " Pushed summary file changes"
466+ else
467+ print_warning " Failed to push summary file changes (may already be up to date)"
468+ fi
469+ else
470+ print_warning " Failed to commit summary file rename (no changes to commit)"
471+ fi
472+ print_success " Committed and pushed $new_summary_file "
473+ else
474+ print_error " Rename operation appeared to succeed but file verification failed"
475+ print_error " Expected: $new_summary_file to exist and $summary_file to not exist"
476+ exit 1
477+ fi
478+ else
479+ print_error " Failed to rename summary file from $summary_file to $new_summary_file "
480+ print_error " This may be due to file system permissions or the target file being locked"
481+ exit 1
482+ fi
483+ else
484+ # Preserve the summary file
485+ print_status " Preserving summary file: $summary_file "
486+ print_success " Summary file will remain available for future runs"
487+ fi
488+ fi
489+ # --- End major changes summary file handling ---
488490}
489491
490492main " $@ "
0 commit comments