From af4adc84cfa46585a674f9449c17c9bd945bf668 Mon Sep 17 00:00:00 2001 From: Richard Levasseur Date: Sat, 4 Jul 2026 03:56:10 +0000 Subject: [PATCH] chore(release): fix promote_rc arguments and align comments `promote_rc.py` was calling `Git.fetch` with `refspec` keyword argument which was not supported by `Git.fetch` signature, leading to fatal errors. The release promotion comment format was different from the release candidate creation comment format, leading to inconsistency. - Added `refspec` argument support to `Git.fetch` in `git.py`. - Added `sys.argv` printing at startup in `release.py` for debugging. - Updated `promote_rc.py` comment body to match `create_rc.py` style and added necessary helper variables. - Updated `git_test.py` to test `Git.fetch` with `refspec`. - Updated `promote_rc_test.py` to match the new comment format. --- tests/tools/private/release/git_test.py | 38 +++++++++++++++++++ .../tools/private/release/promote_rc_test.py | 27 ++++++++----- tools/private/release/git.py | 9 ++++- tools/private/release/promote_rc.py | 24 +++++++++--- tools/private/release/release.py | 1 + 5 files changed, 84 insertions(+), 15 deletions(-) diff --git a/tests/tools/private/release/git_test.py b/tests/tools/private/release/git_test.py index 59b5c31989..16667b8715 100644 --- a/tests/tools/private/release/git_test.py +++ b/tests/tools/private/release/git_test.py @@ -44,5 +44,43 @@ def test_checkout_track_remote_existing_branch( mock_reset_hard.assert_called_once_with("origin/my-branch") +class GitFetchTest(unittest.TestCase): + def setUp(self): + self.git = Git(".") + self.patcher = patch.object(self.git, "_run_git") + self.mock_run_git = self.patcher.start() + self.addCleanup(self.patcher.stop) + + def test_fetch_default(self): + self.git.fetch() + self.mock_run_git.assert_called_once_with( + "fetch", "origin", capture_output=False + ) + + def test_fetch_custom_remote(self): + self.git.fetch("upstream") + self.mock_run_git.assert_called_once_with( + "fetch", "upstream", capture_output=False + ) + + def test_fetch_with_refspec(self): + self.git.fetch("origin", refspec="my-branch") + self.mock_run_git.assert_called_once_with( + "fetch", "origin", "my-branch", capture_output=False + ) + + def test_fetch_with_tags_and_force(self): + self.git.fetch("origin", tags=True, force=True) + self.mock_run_git.assert_called_once_with( + "fetch", "origin", "--tags", "--force", capture_output=False + ) + + def test_fetch_all_options(self): + self.git.fetch("origin", refspec="my-branch", tags=True, force=True) + self.mock_run_git.assert_called_once_with( + "fetch", "origin", "my-branch", "--tags", "--force", capture_output=False + ) + + if __name__ == "__main__": unittest.main() diff --git a/tests/tools/private/release/promote_rc_test.py b/tests/tools/private/release/promote_rc_test.py index 68797e2e1e..f6fa2da970 100644 --- a/tests/tools/private/release/promote_rc_test.py +++ b/tests/tools/private/release/promote_rc_test.py @@ -50,9 +50,12 @@ def test_promote_rc_success(self): 123, expected_updated_body ) expected_comment = ( - "Version 2.0.0 has been tagged.\n\n" - "- **Release Page**: https://github.com/bazel-contrib/rules_python/releases/tag/2.0.0\n" - '- **BCR PR Search**: [is:pr ("bazel-contrib/rules_python" in:title) ("@2.0.0" in:title)](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.0%22%20in%3Atitle%29)' + "**New Release Tagged!** 🐍🌿\n\n" + "Version **2.0.0** has been successfully generated and tagged on branch [`release/2.0`](https://github.com/bazel-contrib/rules_python/tree/release/2.0).\n\n" + "- [Github Release 2.0.0](https://github.com/bazel-contrib/rules_python/releases/tag/2.0.0)\n" + "- [BCR Entry 2.0.0](https://registry.bazel.build/modules/rules_python/2.0.0)\n" + "- [BCR PRs](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.0%22%20in%3Atitle%29)\n" + "- [Release workflow status](https://github.com/bazel-contrib/rules_python/actions/workflows/release_promote_rc.yaml)" ) self.mock_gh.post_issue_comment.assert_called_once_with(123, expected_comment) @@ -95,9 +98,12 @@ def test_promote_rc_resolve_issue_success(self): 123, expected_updated_body ) expected_comment = ( - "Version 2.0.0 has been tagged.\n\n" - "- **Release Page**: https://github.com/bazel-contrib/rules_python/releases/tag/2.0.0\n" - '- **BCR PR Search**: [is:pr ("bazel-contrib/rules_python" in:title) ("@2.0.0" in:title)](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.0%22%20in%3Atitle%29)' + "**New Release Tagged!** 🐍🌿\n\n" + "Version **2.0.0** has been successfully generated and tagged on branch [`release/2.0`](https://github.com/bazel-contrib/rules_python/tree/release/2.0).\n\n" + "- [Github Release 2.0.0](https://github.com/bazel-contrib/rules_python/releases/tag/2.0.0)\n" + "- [BCR Entry 2.0.0](https://registry.bazel.build/modules/rules_python/2.0.0)\n" + "- [BCR PRs](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.0%22%20in%3Atitle%29)\n" + "- [Release workflow status](https://github.com/bazel-contrib/rules_python/actions/workflows/release_promote_rc.yaml)" ) self.mock_gh.post_issue_comment.assert_called_once_with(123, expected_comment) @@ -142,9 +148,12 @@ def test_promote_rc_resolves_version_from_issue(self): 123, expected_updated_body ) expected_comment = ( - "Version 2.0.1 has been tagged.\n\n" - "- **Release Page**: https://github.com/bazel-contrib/rules_python/releases/tag/2.0.1\n" - '- **BCR PR Search**: [is:pr ("bazel-contrib/rules_python" in:title) ("@2.0.1" in:title)](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.1%22%20in%3Atitle%29)' + "**New Release Tagged!** 🐍🌿\n\n" + "Version **2.0.1** has been successfully generated and tagged on branch [`release/2.0`](https://github.com/bazel-contrib/rules_python/tree/release/2.0).\n\n" + "- [Github Release 2.0.1](https://github.com/bazel-contrib/rules_python/releases/tag/2.0.1)\n" + "- [BCR Entry 2.0.1](https://registry.bazel.build/modules/rules_python/2.0.1)\n" + "- [BCR PRs](https://github.com/bazelbuild/bazel-central-registry/pulls?q=is%3Apr%20%28%22bazel-contrib/rules_python%22%20in%3Atitle%29%20%28%22%402.0.1%22%20in%3Atitle%29)\n" + "- [Release workflow status](https://github.com/bazel-contrib/rules_python/actions/workflows/release_promote_rc.yaml)" ) self.mock_gh.post_issue_comment.assert_called_once_with(123, expected_comment) diff --git a/tools/private/release/git.py b/tools/private/release/git.py index 69edba3565..3e7f77f39a 100644 --- a/tools/private/release/git.py +++ b/tools/private/release/git.py @@ -135,16 +135,23 @@ def push( self._run_git(*cmd, capture_output=False) def fetch( - self, remote: str = "origin", tags: bool = False, force: bool = False + self, + remote: str = "origin", + refspec: str | None = None, + tags: bool = False, + force: bool = False, ) -> None: """Fetches updates from a remote repository. Args: remote: The remote repository name. Defaults to 'origin'. + refspec: The refspec to fetch. tags: If True, fetches all tags. force: If True, force fetches updates. """ cmd = ["fetch", remote] + if refspec: + cmd.append(refspec) if tags: cmd.append("--tags") if force: diff --git a/tools/private/release/promote_rc.py b/tools/private/release/promote_rc.py index ac3a841526..4a261c3b84 100644 --- a/tools/private/release/promote_rc.py +++ b/tools/private/release/promote_rc.py @@ -1,6 +1,7 @@ """Subcommand to promote a release candidate to final release.""" import argparse +import os import urllib.parse from tools.private.release.gh import GitHub @@ -161,16 +162,29 @@ def run(self) -> int: print(f"Posting comment to tracking issue #{issue_num}...") + branch_url = f"{REPO_URL}/tree/{branch_name}" release_url = f"{REPO_URL}/releases/tag/{version}" + bcr_entry_url = f"https://registry.bazel.build/modules/rules_python/{version}" bcr_query = ( f'is:pr ("bazel-contrib/rules_python" in:title) ("@{version}" in:title)' ) bcr_search_url = f"https://github.com/bazelbuild/bazel-central-registry/pulls?q={urllib.parse.quote(bcr_query)}" - comment_body = ( - f"Version {version} has been tagged.\n\n" - f"- **Release Page**: {release_url}\n" - f"- **BCR PR Search**: [{bcr_query}]({bcr_search_url})" - ) + + if run_id := os.environ.get("GITHUB_RUN_ID"): + release_workflow_url = f"{REPO_URL}/actions/runs/{run_id}" + else: + release_workflow_url = ( + f"{REPO_URL}/actions/workflows/release_promote_rc.yaml" + ) + + comment_body = f"""**New Release Tagged!** 🐍🌿 + +Version **{version}** has been successfully generated and tagged on branch [`{branch_name}`]({branch_url}). + +- [Github Release {version}]({release_url}) +- [BCR Entry {version}]({bcr_entry_url}) +- [BCR PRs]({bcr_search_url}) +- [Release workflow status]({release_workflow_url})""" self.gh.post_issue_comment(issue_num, comment_body) return 0 diff --git a/tools/private/release/release.py b/tools/private/release/release.py index 6364c61b23..8ad9c2e33e 100644 --- a/tools/private/release/release.py +++ b/tools/private/release/release.py @@ -46,6 +46,7 @@ def create_parser(): def main(): + print(f"sys.argv: {sys.argv}") if "BUILD_WORKSPACE_DIRECTORY" in os.environ: os.chdir(os.environ["BUILD_WORKSPACE_DIRECTORY"])