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
23 changes: 14 additions & 9 deletions .github/ISSUE_TEMPLATE/release_tracking_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,29 @@ labels: ['type: release']
- [ ] Tag Final

## Backports

To request a backport, add it to the checklist below and process it. See [RELEASING.md: How to add backports](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#how-to-add-backports) for details.


To request a backport, comment `/backport` on the PR, comment `/backport <PR>`
on this issue, or add it to the checklist below. See
[RELEASING.md: How to add backports](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#how-to-add-backports)
for details.

---

To manually control the release flow, see the [RELEASING.md: Manual Editing](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#manual-editing-of-tracking-issue) section.


To manually control the release flow, see the
[RELEASING.md: Manual Editing](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md#manual-editing-of-tracking-issue)
section.

<details>
<summary><b>Available Commands</b></summary>

Comment commands:
- `/prepare`: Determines version, creates tracking issue and preparation PR.
- `/prepare-complete [PR]`: Marks preparation task as complete.
- `/create-release-branch`: Cuts and pushes the release branch.
- `/create-rc`: Tags and publishes a new release candidate (RC).
- `/process-backports`: Cherry-picks pending backports.
- `/add-backports <PRs>`: Adds PRs to the backports and processes backports.
- `/backport <PRs>`: Adds PRs to the backports and processes backports.
- `/promote`: Promotes the latest RC to final release.

See [RELEASING.md](https://github.com/bazel-contrib/rules_python/blob/main/RELEASING.md) for details on how to use them.
</details>
18 changes: 12 additions & 6 deletions .github/workflows/on_comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,17 @@ def _get_bool(key: str, default: bool = False) -> bool:
return val.lower() == "true"


def _match_command(command: str, comment_body: str) -> re.Match[str] | None:
def _match_command(
command: str | tuple[str, ...], comment_body: str
) -> re.Match[str] | None:
"""Matches a slash command at the start of any line, capturing optional trailing args."""
cmd = command.lstrip("/")
if isinstance(command, str):
commands = (command,)
else:
commands = command
pattern = "|".join(re.escape(cmd.lstrip("/")) for cmd in commands)
return re.search(
rf"^\s*/{re.escape(cmd)}(?:\s+(\S.*?))?\s*$",
rf"^\s*/(?:{pattern})(?:\s+(\S.*?))?\s*$",
comment_body,
re.MULTILINE,
)
Expand Down Expand Up @@ -61,7 +67,7 @@ def _add_comment_reaction(repo: str, comment_id: str, content: str) -> None:

def _react_negative(repo: str, comment_id: str) -> None:
"""Logs error and adds a negative reaction to the comment."""
print("Error: No PRs specified for add-backports.", file=sys.stderr)
print("::error::No PRs specified for backport.")
if comment_id and repo:
_add_comment_reaction(repo=repo, comment_id=comment_id, content="-1")

Expand Down Expand Up @@ -95,7 +101,7 @@ def _process_release_issue_comment(
_write_github_output("command", "process-backports")
return

if m := _match_command("add-backports", comment_body):
if m := _match_command(("backport", "backports"), comment_body):
raw_args = m.group(1) if m.group(1) else ""
items = [item for item in re.split(r"[\s,]+", raw_args) if item]
if csv := ",".join(items):
Expand Down Expand Up @@ -128,7 +134,7 @@ def _process_backport_issue_comment(comment_body: str) -> None:

def _process_pr_comment(comment_body: str, pr_number: str) -> None:
"""Processes comments on a pull request."""
if _match_command("backport", comment_body):
if _match_command(("backport", "backports"), comment_body):
_write_github_output("command", "pr-backport")
_write_github_output("pr_number", pr_number)
return
Expand Down
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ automatically processed.

### Method B: Comment on the Tracking Issue

Comment `/add-backports <PR_REF> [<PR_REF> ...]` (space or comma separated) on
Comment `/backport <PR_REF> [<PR_REF> ...]` (space or comma separated) on
the tracking issue. The `<PR_REF>` can be a PR number (optionally prefixed with
`#`) or a PR URL (strictly for the configured repository). This will
automatically add the PRs to the checklist and trigger processing.
Expand Down
30 changes: 21 additions & 9 deletions tests/workflows/on_comment_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,10 @@ def test_release_issue_process_backports(monkeypatch, gha_env):
assert gha_env.read_env() == {"issue_number": "100"}


def test_release_issue_add_backports(monkeypatch, gha_env):
def test_release_issue_backport(monkeypatch, gha_env):
_run_comment(
monkeypatch,
"/add-backports 1, 2, 3",
"/backport 1, 2, 3",
has_release_label="true",
)
assert gha_env.read_outputs() == {
Expand All @@ -166,10 +166,10 @@ def test_release_issue_add_backports(monkeypatch, gha_env):
assert gha_env.read_env() == {"issue_number": "100"}


def test_release_issue_add_backports_hashes(monkeypatch, gha_env):
def test_release_issue_backport_hashes(monkeypatch, gha_env):
_run_comment(
monkeypatch,
"/add-backports #123 #567",
"/backport #123 #567",
has_release_label="true",
)
assert gha_env.read_outputs() == {
Expand All @@ -180,12 +180,10 @@ def test_release_issue_add_backports_hashes(monkeypatch, gha_env):
assert gha_env.read_env() == {"issue_number": "100"}


def test_release_issue_add_backports_empty(
monkeypatch, gha_env, mock_add_reaction, capsys
):
def test_release_issue_backport_empty(monkeypatch, gha_env, mock_add_reaction, capsys):
_run_comment(
monkeypatch,
"/add-backports",
"/backport",
has_release_label="true",
repo="bazel-contrib/rules_python",
comment_id="789",
Expand All @@ -196,7 +194,7 @@ def test_release_issue_add_backports_empty(
}
assert gha_env.read_env() == {"issue_number": "100"}
captured = capsys.readouterr()
assert "Error: No PRs specified for add-backports." in captured.err
assert "::error::No PRs specified for backport." in captured.out
mock_add_reaction.assert_called_once_with(
repo="bazel-contrib/rules_python",
comment_id="789",
Expand Down Expand Up @@ -311,6 +309,20 @@ def test_pr_backport(monkeypatch, gha_env):
assert gha_env.read_env() == {}


def test_pr_backports_plural_alias(monkeypatch, gha_env):
_run_comment(
monkeypatch,
"/backports",
is_pr="true",
event_number="300",
)
assert gha_env.read_outputs() == {
"command": "pr-backport",
"pr_number": "300",
}
assert gha_env.read_env() == {}


def test_pr_prepare_complete(monkeypatch, gha_env):
_run_comment(
monkeypatch,
Expand Down