From 8d5d4b05ef409e5ec4865493333c968a12045bf8 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 4 Feb 2025 10:24:11 +1100 Subject: [PATCH 1/2] chore: release_checklist.py checks for bump/v4.X.0 branches --- doc/dev/release_checklist.md | 2 +- script/release_checklist.py | 26 ++++++++++++++++++++++---- script/release_repos.yml | 2 ++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/doc/dev/release_checklist.md b/doc/dev/release_checklist.md index 80c40ba5d601..7680d0c10a2e 100644 --- a/doc/dev/release_checklist.md +++ b/doc/dev/release_checklist.md @@ -199,7 +199,7 @@ We'll use `v4.7.0-rc1` as the intended release version in this example. - We do this for the same list of repositories as for stable releases, see above. As above, there are dependencies between these, and so the process above is iterative. It greatly helps if you can merge the `bump/v4.7.0` PRs yourself! - It is essential for Mathlib CI that you then create the next `bump/v4.8.0` branch + - It is essential for Mathlib and Batteries CI that you then create the next `bump/v4.8.0` branch for the next development cycle. Set the `lean-toolchain` file on this branch to same `nightly` you used for this release. - (Note: we're currently uncertain if we really want to do this step. Check with Kim Morrison if you're unsure.) diff --git a/script/release_checklist.py b/script/release_checklist.py index 3968a77ff49e..d716d97d4026 100755 --- a/script/release_checklist.py +++ b/script/release_checklist.py @@ -142,6 +142,14 @@ def extract_org_repo_from_url(repo_url): return repo_url.replace("https://github.com/", "").rstrip("/") return repo_url +def get_next_version(version): + """Calculate the next version number, ignoring RC suffix.""" + # Strip v prefix and RC suffix if present + base_version = strip_rc_suffix(version.lstrip('v')) + major, minor, patch = map(int, base_version.split('.')) + # Next version is always .0 + return f"v{major}.{minor + 1}.0" + def main(): github_token = get_github_token() @@ -201,6 +209,7 @@ def main(): branch = repo["branch"] check_stable = repo["stable-branch"] check_tag = repo.get("toolchain-tag", True) + check_bump = repo.get("bump-branch", False) print(f"\nRepository: {name}") @@ -220,15 +229,24 @@ def main(): if check_tag: if not tag_exists(url, toolchain, github_token): print(f" ❌ Tag {toolchain} does not exist. Run `script/push_repo_release_tag.py {extract_org_repo_from_url(url)} {branch} {toolchain}`.") - continue - print(f" ✅ Tag {toolchain} exists") + else: + print(f" ✅ Tag {toolchain} exists") # Only check merging into stable if stable-branch is true and not a release candidate if check_stable and not is_release_candidate(toolchain): if not is_merged_into_stable(url, toolchain, "stable", github_token): print(f" ❌ Tag {toolchain} is not merged into stable") - continue - print(f" ✅ Tag {toolchain} is merged into stable") + else: + print(f" ✅ Tag {toolchain} is merged into stable") + + # Check for bump branch if configured + if check_bump: + next_version = get_next_version(toolchain) + bump_branch = f"bump/{next_version}" + if branch_exists(url, bump_branch, github_token): + print(f" ✅ Bump branch {bump_branch} exists") + else: + print(f" ❌ Bump branch {bump_branch} does not exist") if __name__ == "__main__": main() diff --git a/script/release_repos.yml b/script/release_repos.yml index 4246f1c36a45..e59f05e4492f 100644 --- a/script/release_repos.yml +++ b/script/release_repos.yml @@ -4,6 +4,7 @@ repositories: toolchain-tag: true stable-branch: true branch: main + bump-branch: true dependencies: [] - name: lean4checker @@ -76,6 +77,7 @@ repositories: toolchain-tag: true stable-branch: true branch: master + bump-branch: true dependencies: - Aesop - ProofWidgets4 From 01e8f42ce33b044e523e340101c2b554836a6409 Mon Sep 17 00:00:00 2001 From: Kim Morrison Date: Tue, 4 Feb 2025 10:31:57 +1100 Subject: [PATCH 2/2] chore: release_checklist.py checks if 'begin dev cycle' PR is needed --- script/release_checklist.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/script/release_checklist.py b/script/release_checklist.py index d716d97d4026..1aa74409faf1 100755 --- a/script/release_checklist.py +++ b/script/release_checklist.py @@ -191,7 +191,6 @@ def main(): print(f" ✅ Release notes look good.") else: previous_minor_version = version_minor - 1 - previous_stable_branch = f"releases/v{version_major}.{previous_minor_version}.0" previous_release = f"v{version_major}.{previous_minor_version}.0" print(f" ❌ Release notes not published. Please run `script/release_notes.py --since {previous_release}` on branch `{branch_name}`.") else: @@ -248,5 +247,34 @@ def main(): else: print(f" ❌ Bump branch {bump_branch} does not exist") + # Check lean4 master branch for next development cycle + print("\nChecking lean4 master branch configuration...") + next_version = get_next_version(toolchain) + next_minor = int(next_version.split('.')[1]) + + cmake_content = get_branch_content(lean_repo_url, "master", "src/CMakeLists.txt", github_token) + if cmake_content is None: + print(" ❌ Could not retrieve CMakeLists.txt from master") + else: + cmake_lines = cmake_content.splitlines() + # Find the actual minor version in CMakeLists.txt + for line in cmake_lines: + if line.strip().startswith("set(LEAN_VERSION_MINOR "): + actual_minor = int(line.split()[-1].rstrip(")")) + version_minor_correct = actual_minor >= next_minor + break + else: + version_minor_correct = False + + is_release_correct = any( + l.strip().startswith("set(LEAN_VERSION_IS_RELEASE 0)") + for l in cmake_lines + ) + + if not (version_minor_correct and is_release_correct): + print(" ❌ lean4 needs a \"begin dev cycle\" PR") + else: + print(" ✅ lean4 master branch is configured for next development cycle") + if __name__ == "__main__": main()