@@ -481,11 +481,9 @@ def execute_release_steps(repo, version, config):
481481 run_command ("lake update" , cwd = repo_path , stream_output = True )
482482 elif repo_name == "verso" :
483483 # verso has nested Lake projects in test-projects/ that each have their own
484- # lake-manifest.json with a subverso pin. After updating the root manifest via
485- # `lake update`, sync the de-modulized subverso rev into all sub-manifests.
486- # The sub-projects use an old toolchain (v4.21.0) that doesn't support module/prelude
487- # syntax, so they need the de-modulized version (tagged no-modules/<root-rev>).
488- # The "SubVerso version consistency" CI check accepts either the root or de-modulized rev.
484+ # lake-manifest.json with a subverso pin and their own lean-toolchain.
485+ # After updating the root manifest via `lake update`, sync the de-modulized
486+ # subverso rev into all sub-manifests, and update their lean-toolchain files.
489487 run_command ("lake update" , cwd = repo_path , stream_output = True )
490488 print (blue ("Syncing de-modulized subverso rev to test-project sub-manifests..." ))
491489 sync_script = (
@@ -498,6 +496,15 @@ def execute_release_steps(repo, version, config):
498496 )
499497 run_command (sync_script , cwd = repo_path )
500498 print (green ("Synced de-modulized subverso rev to all test-project sub-manifests" ))
499+ # Update all lean-toolchain files in test-projects/ to match the root
500+ print (blue ("Updating lean-toolchain files in test-projects/..." ))
501+ find_result = run_command ("find test-projects -name lean-toolchain" , cwd = repo_path )
502+ for tc_path in find_result .stdout .strip ().splitlines ():
503+ if tc_path :
504+ tc_file = repo_path / tc_path
505+ with open (tc_file , "w" ) as f :
506+ f .write (f"leanprover/lean4:{ version } \n " )
507+ print (green (f" Updated { tc_path } " ))
501508 elif dependencies :
502509 run_command (f'perl -pi -e \' s/"v4\\ .[0-9]+(\\ .[0-9]+)?(-rc[0-9]+)?"/"' + version + '"/g\' lakefile.*' , cwd = repo_path )
503510 run_command ("lake update" , cwd = repo_path , stream_output = True )
@@ -659,56 +666,61 @@ def execute_release_steps(repo, version, config):
659666 # Fetch latest changes to ensure we have the most up-to-date nightly-testing branch
660667 print (blue ("Fetching latest changes from origin..." ))
661668 run_command ("git fetch origin" , cwd = repo_path )
662-
663- try :
664- print (blue ("Merging origin/nightly-testing..." ))
665- run_command ("git merge origin/nightly-testing" , cwd = repo_path )
666- print (green ("Merge completed successfully" ))
667- except subprocess .CalledProcessError :
668- # Merge failed due to conflicts - check which files are conflicted
669- print (blue ("Merge conflicts detected, checking which files are affected..." ))
670-
671- # Get conflicted files using git status
672- status_result = run_command ("git status --porcelain" , cwd = repo_path )
673- conflicted_files = []
674-
675- for line in status_result .stdout .splitlines ():
676- if len (line ) >= 2 and line [:2 ] in ['UU' , 'AA' , 'DD' , 'AU' , 'UA' , 'DU' , 'UD' ]:
677- # Extract filename (skip the first 3 characters which are status codes)
678- conflicted_files .append (line [3 :])
679-
680- # Filter out allowed files
681- allowed_patterns = ['lean-toolchain' , 'lake-manifest.json' ]
682- problematic_files = []
683-
684- for file in conflicted_files :
685- is_allowed = any (pattern in file for pattern in allowed_patterns )
686- if not is_allowed :
687- problematic_files .append (file )
688-
689- if problematic_files :
690- # There are conflicts in non-allowed files - fail
691- print (red ("❌ Merge failed!" ))
692- print (red (f"Merging nightly-testing resulted in conflicts in:" ))
693- for file in problematic_files :
694- print (red (f" - { file } " ))
695- print (red ("Please resolve these conflicts manually." ))
696- return
697- else :
698- # Only allowed files are conflicted - resolve them automatically
699- print (green (f"✅ Only allowed files conflicted: { ', ' .join (conflicted_files )} " ))
700- print (blue ("Resolving conflicts automatically..." ))
701-
702- # For lean-toolchain and lake-manifest.json, keep our versions
669+
670+ # Check if nightly-testing branch exists on origin (use local ref after fetch for exact match)
671+ nightly_check = run_command ("git show-ref --verify --quiet refs/remotes/origin/nightly-testing" , cwd = repo_path , check = False )
672+ if nightly_check .returncode != 0 :
673+ print (yellow ("No nightly-testing branch found on origin, skipping merge" ))
674+ else :
675+ try :
676+ print (blue ("Merging origin/nightly-testing..." ))
677+ run_command ("git merge origin/nightly-testing" , cwd = repo_path )
678+ print (green ("Merge completed successfully" ))
679+ except subprocess .CalledProcessError :
680+ # Merge failed due to conflicts - check which files are conflicted
681+ print (blue ("Merge conflicts detected, checking which files are affected..." ))
682+
683+ # Get conflicted files using git status
684+ status_result = run_command ("git status --porcelain" , cwd = repo_path )
685+ conflicted_files = []
686+
687+ for line in status_result .stdout .splitlines ():
688+ if len (line ) >= 2 and line [:2 ] in ['UU' , 'AA' , 'DD' , 'AU' , 'UA' , 'DU' , 'UD' ]:
689+ # Extract filename (skip the first 3 characters which are status codes)
690+ conflicted_files .append (line [3 :])
691+
692+ # Filter out allowed files
693+ allowed_patterns = ['lean-toolchain' , 'lake-manifest.json' ]
694+ problematic_files = []
695+
703696 for file in conflicted_files :
704- print (blue (f"Keeping our version of { file } " ))
705- run_command (f"git checkout --ours { file } " , cwd = repo_path )
706-
707- # Complete the merge
708- run_command ("git add ." , cwd = repo_path )
709- run_command ("git commit --no-edit" , cwd = repo_path )
710-
711- print (green ("✅ Merge completed successfully with automatic conflict resolution" ))
697+ is_allowed = any (pattern in file for pattern in allowed_patterns )
698+ if not is_allowed :
699+ problematic_files .append (file )
700+
701+ if problematic_files :
702+ # There are conflicts in non-allowed files - fail
703+ print (red ("❌ Merge failed!" ))
704+ print (red (f"Merging nightly-testing resulted in conflicts in:" ))
705+ for file in problematic_files :
706+ print (red (f" - { file } " ))
707+ print (red ("Please resolve these conflicts manually." ))
708+ return
709+ else :
710+ # Only allowed files are conflicted - resolve them automatically
711+ print (green (f"✅ Only allowed files conflicted: { ', ' .join (conflicted_files )} " ))
712+ print (blue ("Resolving conflicts automatically..." ))
713+
714+ # For lean-toolchain and lake-manifest.json, keep our versions
715+ for file in conflicted_files :
716+ print (blue (f"Keeping our version of { file } " ))
717+ run_command (f"git checkout --ours { file } " , cwd = repo_path )
718+
719+ # Complete the merge
720+ run_command ("git add ." , cwd = repo_path )
721+ run_command ("git commit --no-edit" , cwd = repo_path )
722+
723+ print (green ("✅ Merge completed successfully with automatic conflict resolution" ))
712724
713725 # Build and test (skip for Mathlib)
714726 if repo_name not in ["mathlib4" ]:
0 commit comments