5454RELEASE_WORKFLOW_URL = (
5555 "https://github.com/smorinlabs/envgen/actions/workflows/release.yml"
5656)
57+ LOCKFILE_SYNC_ARGS = ["cargo" , "+1.88.0" , "generate-lockfile" ]
5758
5859
5960class BumpError (RuntimeError ):
@@ -99,12 +100,19 @@ def render_next_step(
99100 crate_version : str | None = None ,
100101 schema_version : str | None = None ,
101102 tag_name : str | None = None ,
103+ lockfile_synced : bool | None = None ,
102104) -> tuple [str , list [str ]]:
103105 if stage == "crate-after-bump" :
104106 resolved_crate_version = crate_version or read_cargo_version ()
107+ lines : list [str ] = []
108+ if lockfile_synced is True :
109+ lines .append ("Cargo.lock synchronized for locked checks." )
110+ elif lockfile_synced is False :
111+ lines .append ("Cargo.lock sync runs only in non-dry-run bump mode." )
112+ lines .append ("$ make check-release" )
105113 return (
106114 f"Crate release prep updated to v{ resolved_crate_version } ." ,
107- [ "$ make check-release" ] ,
115+ lines ,
108116 )
109117
110118 if stage == "crate-after-check-release" :
@@ -186,6 +194,7 @@ def emit_next_step(
186194 crate_version : str | None = None ,
187195 schema_version : str | None = None ,
188196 tag_name : str | None = None ,
197+ lockfile_synced : bool | None = None ,
189198) -> None :
190199 if not hints_enabled ():
191200 return
@@ -195,6 +204,7 @@ def emit_next_step(
195204 crate_version = crate_version ,
196205 schema_version = schema_version ,
197206 tag_name = tag_name ,
207+ lockfile_synced = lockfile_synced ,
198208 )
199209 print ("" )
200210 print (f"Hint: { summary } " )
@@ -349,6 +359,7 @@ def rotate_changelog(
349359 default_sections : list [str ],
350360 allow_empty : bool ,
351361 dry_run : bool ,
362+ make_override_command : str | None = None ,
352363) -> None :
353364 text = path .read_text (encoding = "utf-8" )
354365 match = UNRELEASED_RE .search (text )
@@ -361,10 +372,13 @@ def rotate_changelog(
361372 headings = default_sections
362373
363374 if not changelog_has_entries (body ) and not allow_empty :
364- fail (
365- f"Unreleased section in { path } has no entries. "
366- "Use --allow-empty-changelog to override."
367- )
375+ if make_override_command :
376+ fail (
377+ f"Unreleased section in { path } has no entries.\n "
378+ "Override from Make target:\n "
379+ f" { make_override_command } "
380+ )
381+ fail (f"Unreleased section in { path } has no entries." )
368382
369383 unreleased_block = "## [Unreleased]\n \n "
370384 unreleased_block += "" .join (f"### { heading } \n \n " for heading in headings )
@@ -427,6 +441,20 @@ def run_git_command(args: list[str], dry_run: bool) -> None:
427441 fail (f"Command failed: { quoted } " )
428442
429443
444+ def sync_cargo_lockfile (dry_run : bool ) -> None :
445+ command = shlex .join (LOCKFILE_SYNC_ARGS )
446+ if dry_run :
447+ print (f"[dry-run] would run: { command } " )
448+ return
449+
450+ result = subprocess .run (LOCKFILE_SYNC_ARGS , cwd = ROOT , check = False )
451+ if result .returncode != 0 :
452+ fail (
453+ "Failed to synchronize Cargo.lock after crate version bump.\n "
454+ "Run: make sync-lockfile"
455+ )
456+
457+
430458def create_tag (tag_name : str , message : str , dry_run : bool ) -> None :
431459 if local_tag_exists (tag_name ):
432460 fail (f"Local tag already exists: { tag_name } " )
@@ -485,6 +513,17 @@ def do_status(_args: argparse.Namespace) -> None:
485513
486514
487515def do_bump_crate (args : argparse .Namespace ) -> None :
516+ if args .level :
517+ make_override_command = (
518+ f"make bump-crate-{ args .level } ALLOW_EMPTY_CHANGELOG=1"
519+ )
520+ elif args .version :
521+ make_override_command = (
522+ f"make bump-crate VERSION={ args .version } ALLOW_EMPTY_CHANGELOG=1"
523+ )
524+ else :
525+ make_override_command = "make bump-crate ALLOW_EMPTY_CHANGELOG=1"
526+
488527 old , new = update_cargo_version (
489528 resolve_next_version (read_cargo_version (), args .level , args .version ),
490529 dry_run = args .dry_run ,
@@ -496,15 +535,36 @@ def do_bump_crate(args: argparse.Namespace) -> None:
496535 default_sections = CRATE_SECTIONS ,
497536 allow_empty = args .allow_empty_changelog ,
498537 dry_run = args .dry_run ,
538+ make_override_command = make_override_command ,
499539 )
500540
541+ sync_cargo_lockfile (args .dry_run )
542+
501543 print (f"crate version: { old } -> { new } " )
502544 print (f"updated: { CARGO_TOML } " )
503545 print (f"updated: { CHANGELOG } " )
504- emit_next_step ("crate-after-bump" , crate_version = new )
546+ if not args .dry_run :
547+ print (f"updated: { ROOT / 'Cargo.lock' } " )
548+ emit_next_step (
549+ "crate-after-bump" ,
550+ crate_version = new ,
551+ lockfile_synced = not args .dry_run ,
552+ )
505553
506554
507555def do_bump_schema (args : argparse .Namespace ) -> None :
556+ if args .level :
557+ make_override_command = (
558+ f"make bump-schema-{ args .level } ALLOW_EMPTY_SCHEMA_CHANGELOG=1"
559+ )
560+ elif args .version :
561+ make_override_command = (
562+ f"make bump-schema VERSION={ args .version } "
563+ "ALLOW_EMPTY_SCHEMA_CHANGELOG=1"
564+ )
565+ else :
566+ make_override_command = "make bump-schema ALLOW_EMPTY_SCHEMA_CHANGELOG=1"
567+
508568 old = read_schema_version_file ()
509569 new = resolve_next_version (old , args .level , args .version )
510570 if old == new :
@@ -529,6 +589,7 @@ def do_bump_schema(args: argparse.Namespace) -> None:
529589 default_sections = SCHEMA_SECTIONS ,
530590 allow_empty = args .allow_empty_changelog ,
531591 dry_run = args .dry_run ,
592+ make_override_command = make_override_command ,
532593 )
533594
534595 if args .dry_run :
0 commit comments