diff --git a/.github/ISSUE_TEMPLATE/release_tracking_template.md b/.github/ISSUE_TEMPLATE/release_tracking_template.md index ab634e75f3..efa78a9b63 100644 --- a/.github/ISSUE_TEMPLATE/release_tracking_template.md +++ b/.github/ISSUE_TEMPLATE/release_tracking_template.md @@ -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 ` +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. +
Available Commands - + 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 `: Adds PRs to the backports and processes backports. +- `/backport `: 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.
diff --git a/.github/workflows/on_comment.py b/.github/workflows/on_comment.py index 4d4b4ebb6a..1aa0f1baa0 100755 --- a/.github/workflows/on_comment.py +++ b/.github/workflows/on_comment.py @@ -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, ) @@ -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") @@ -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): @@ -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 diff --git a/RELEASING.md b/RELEASING.md index 6749e2f10b..f740cb3fa9 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -108,7 +108,7 @@ automatically processed. ### Method B: Comment on the Tracking Issue -Comment `/add-backports [ ...]` (space or comma separated) on +Comment `/backport [ ...]` (space or comma separated) on the tracking issue. The `` 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. diff --git a/tests/workflows/on_comment_test.py b/tests/workflows/on_comment_test.py index 9ec9413db1..d7df7da13e 100644 --- a/tests/workflows/on_comment_test.py +++ b/tests/workflows/on_comment_test.py @@ -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() == { @@ -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() == { @@ -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", @@ -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", @@ -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,