Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package(default_visibility = ["//visibility:public"])

licenses(["notice"])

exports_files(glob(["*"]))
5 changes: 2 additions & 3 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,8 @@ verification of cherry-picks using a Backport Tracking Issue.
workflow.
* This will automatically create a standard Release Tracking Issue for
each target version (e.g., `Release 1.7.1`, `Release 1.8.1`, etc.).
* For patch releases, the created release tracking issues will have `Tag
RC` tasks automatically removed, as release candidates are not
required for patch releases.
* For patch releases, the created release tracking issue will have
non-patch release tasks removed.
* The backport PR will be automatically added to the checklist of each
created release tracking issue.

Expand Down
2 changes: 2 additions & 0 deletions tests/tools/private/release/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ py_library(
name = "release_test_helper",
testonly = True,
srcs = ["release_test_helper.py"],
data = ["//.github/ISSUE_TEMPLATE:release_tracking_template.md"],
target_compatible_with = NOT_WINDOWS,
deps = [
"//python/runfiles",
"//tools/private/release:mock_gh",
"//tools/private/release:release_lib",
"@pypi//pytest",
Expand Down
3 changes: 3 additions & 0 deletions tests/tools/private/release/add_backports_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ def test_add_backports_auto_discover_no_issues_creates_patch_release(
assert "- [ ] #124" in body
assert "- [ ] Sync Changelog #124" in body
assert "Tag RC" not in body
assert "Prepare Release" not in body
assert "Create Release branch" not in body
assert "- [ ] Tag Final" in body


def test_add_backports_patch_release_no_rc_added(mock_gh):
Expand Down
15 changes: 12 additions & 3 deletions tests/tools/private/release/backport_create_releases_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,23 @@ def test_create_releases_all_success(release_tool_env, mock_gh):
assert 1002 in gh.issues
assert 1003 in gh.issues

# 1.7.2 (patch) should not have Tag RC0
# 1.7.2 (patch) should not have Tag RC0, Prepare Release, or Create Release branch
assert gh.issues[1001]["title"] == "Release 1.7.2"
assert "Tag RC0" not in gh.issues[1001]["body"]
assert "## Backports\n- [ ] #456" in gh.issues[1001]["body"]
assert "Prepare Release" not in gh.issues[1001]["body"]
assert "Create Release branch" not in gh.issues[1001]["body"]
assert "Tag Final" in gh.issues[1001]["body"]
assert "- [ ] #456" in gh.issues[1001]["body"]
assert "- [ ] Sync Changelog #456" in gh.issues[1001]["body"]

# 1.9.0 (minor) should have Tag RC0
# 1.9.0 (minor) should have Tag RC0, Prepare Release, and Create Release branch
assert gh.issues[1003]["title"] == "Release 1.9.0"
assert "Tag RC0" in gh.issues[1003]["body"]
assert "Prepare Release" in gh.issues[1003]["body"]
assert "Create Release branch" in gh.issues[1003]["body"]
assert "Tag Final" in gh.issues[1003]["body"]
assert "- [ ] #456" in gh.issues[1003]["body"]
assert "- [ ] Sync Changelog #456" in gh.issues[1003]["body"]

# Verify backport issue updated
expected_updated_backport_body = """* PR: #456
Expand Down
6 changes: 4 additions & 2 deletions tests/tools/private/release/release_issue_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,12 @@ def test_load_release_tracking_template(tmp_path):
assert "- [ ] Tag RC0" in full_template
assert "- [ ] Tag RC1" in full_template

# Patch release version (strips RC tasks)
# Patch release version (strips .0-only release tasks: Prepare Release, Create Release branch, Tag RC)
patch_template = load_release_tracking_template(
version="1.2.1", template_path=template_file
)
assert "Tag RC" not in patch_template
assert "- [ ] Prepare Release" in patch_template
assert "Prepare Release" not in patch_template
assert "Create Release branch" not in patch_template
assert "- [ ] Tag Final" in patch_template
assert "## Backports" in patch_template
24 changes: 15 additions & 9 deletions tests/tools/private/release/release_test_helper.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import dataclasses
import shutil
from pathlib import Path
from unittest.mock import MagicMock, patch

import pytest

from python.runfiles import runfiles
from tools.private.release.mock_gh import MockGitHub


Expand All @@ -20,14 +22,17 @@ class ReleaseToolEnv:
github_output_file: Path


DEFAULT_RELEASE_TEMPLATE_CONTENT = (
"template content\n"
"- [ ] Prepare Release\n"
"- [ ] Tag RC0\n"
"- [ ] Tag Final\n"
"\n"
"## Backports\n"
)
def _find_real_template_path() -> Path:
r = runfiles.Create()
path = r.Rlocation(
"rules_python/.github/ISSUE_TEMPLATE/release_tracking_template.md"
)
if not path or not Path(path).is_file():
raise FileNotFoundError(
"Could not locate .github/ISSUE_TEMPLATE/release_tracking_template.md"
f" in runfiles: {path}"
)
return Path(path)


@pytest.fixture(name="mock_git")
Expand All @@ -52,11 +57,12 @@ def fixture_mock_gh():
@pytest.fixture(name="release_tool_env")
def fixture_release_tool_env(tmp_path, monkeypatch):
"""Fixture providing a temp cwd with release template set up."""
source_template = _find_real_template_path()
monkeypatch.chdir(tmp_path)
template_dir = tmp_path / ".github" / "ISSUE_TEMPLATE"
template_dir.mkdir(parents=True, exist_ok=True)
template_file = template_dir / "release_tracking_template.md"
template_file.write_text(DEFAULT_RELEASE_TEMPLATE_CONTENT, encoding="utf-8")
shutil.copy2(source_template, template_file)
github_output_file = tmp_path / "github_output"
monkeypatch.setenv("GITHUB_OUTPUT", str(github_output_file))
yield ReleaseToolEnv(git_root=tmp_path, github_output_file=github_output_file)
20 changes: 16 additions & 4 deletions tools/private/release/release_issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ def load_release_tracking_template(
version: str | None = None,
template_path: pathlib.Path | None = None,
) -> str:
"""Loads the release tracking issue template, stripping RC tasks for patch releases.
"""Loads the release tracking issue template, stripping non-patch tasks for patch releases.

Args:
version: Optional version string (e.g. '1.2.1'). If provided and represents a
patch release (i.e. does not end in '.0'), strips Tag RC tasks from the template.
patch release (i.e. does not end in '.0'), strips .0-only release tasks
('Prepare Release', 'Create Release branch', and 'Tag RC' tasks) from the template.
template_path: Optional path to the template file. Defaults to
.github/ISSUE_TEMPLATE/release_tracking_template.md.

Expand All @@ -29,8 +30,19 @@ def load_release_tracking_template(
is_patch = version is not None and not version.endswith(".0")
if is_patch:
lines = template_content.splitlines()
lines = [line for line in lines if not re.search(r"Tag RC\d+", line)]
template_content = "\n".join(lines)
filtered_lines = []
for line in lines:
parsed = parse_metadata_line(line)
if parsed:
name_lower = parsed["name"].lower()
if "prepare release" in name_lower:
continue
if "create release branch" in name_lower:
continue
if re.match(r"^tag rc\d+", name_lower):
continue
filtered_lines.append(line)
template_content = "\n".join(filtered_lines)
if not template_content.endswith("\n"):
template_content += "\n"

Expand Down