GRM-27: fix: CI workflows for rootless runner compatibility
This commit was merged in pull request #6.
This commit is contained in:
@@ -9,7 +9,7 @@ from click.testing import CliRunner
|
||||
|
||||
from gitea_runner_manager.config import CONVENTIONAL_RE, TASK_ID_RE
|
||||
from gitea_runner_manager.exceptions import APIError
|
||||
from scripts.auto_merge import extract_task_id, main, validate_pr_title
|
||||
from scripts.auto_merge import extract_task_id, has_ready_to_merge_label, main, validate_pr_title
|
||||
|
||||
|
||||
class TestRegexes:
|
||||
@@ -53,40 +53,111 @@ class TestValidatePrTitle:
|
||||
assert "conventional" in str(exc.value)
|
||||
|
||||
|
||||
class TestHasReadyToMergeLabel:
|
||||
def test_label_present(self) -> None:
|
||||
client = MagicMock()
|
||||
client.get_pr_labels.return_value = [{"name": "bug"}, {"name": "ready-to-merge"}]
|
||||
assert has_ready_to_merge_label(client, "5") is True
|
||||
|
||||
def test_label_absent(self) -> None:
|
||||
client = MagicMock()
|
||||
client.get_pr_labels.return_value = [{"name": "bug"}]
|
||||
assert has_ready_to_merge_label(client, "5") is False
|
||||
|
||||
def test_no_labels(self) -> None:
|
||||
client = MagicMock()
|
||||
client.get_pr_labels.return_value = []
|
||||
assert has_ready_to_merge_label(client, "5") is False
|
||||
|
||||
|
||||
class TestMain:
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_successful_flow(self, mock_client_cls: MagicMock) -> None:
|
||||
def test_successful_flow_with_label_arg(self, mock_client_cls: MagicMock) -> None:
|
||||
mock_client = MagicMock()
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["GRM-19-fix-bug", "fix: resolve timeout", "owner/repo", "7", "ready-to-merge"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "squash-merged" in result.output
|
||||
mock_client.merge_pr.assert_called_once_with("7", "GRM-19: fix: resolve timeout")
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_successful_flow_label_fallback(self, mock_client_cls: MagicMock) -> None:
|
||||
"""Label not passed via arg, but PR has ready-to-merge via API."""
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["GRM-19-fix-bug", "fix: resolve timeout", "owner/repo", "7"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "squash-merged" in result.output
|
||||
mock_client_cls.assert_called_once()
|
||||
mock_client.merge_pr.assert_called_once_with("7", "GRM-19: fix: resolve timeout")
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_wrong_label_skips_merge(self, mock_client_cls: MagicMock) -> None:
|
||||
"""Label is not ready-to-merge and PR doesn't have it via API either."""
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "bug"}]
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["GRM-19-fix-bug", "fix: resolve timeout", "owner/repo", "7", "bug"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "skipping" in result.output
|
||||
mock_client.merge_pr.assert_not_called()
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_empty_label_falls_back_to_api(self, mock_client_cls: MagicMock) -> None:
|
||||
"""Gitea Actions doesn't populate label name, but API shows ready-to-merge."""
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
["GRM-19-fix-bug", "fix: resolve timeout", "owner/repo", "7", ""],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "squash-merged" in result.output
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": ""}, clear=True)
|
||||
def test_missing_token_exits(self) -> None:
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["branch", "title", "repo", "1"])
|
||||
result = runner.invoke(main, ["branch", "title", "owner/repo", "1"])
|
||||
assert result.exit_code == 1
|
||||
assert "REPO_TOKEN" in result.output
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
def test_missing_task_id_exits(self) -> None:
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_missing_task_id_exits(self, mock_client_cls: MagicMock) -> None:
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["feature-no-id", "fix: bug", "repo", "1"])
|
||||
result = runner.invoke(main, ["feature-no-id", "fix: bug", "owner/repo", "1"])
|
||||
assert result.exit_code == 1
|
||||
assert "task ID" in result.output
|
||||
|
||||
@patch.dict("os.environ", {"REPO_TOKEN": "tok"})
|
||||
def test_invalid_pr_title_exits(self) -> None:
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_invalid_pr_title_exits(self, mock_client_cls: MagicMock) -> None:
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, ["GRM-19-fix", "random title", "repo", "1"])
|
||||
result = runner.invoke(main, ["GRM-19-fix", "random title", "owner/repo", "1"])
|
||||
assert result.exit_code == 1
|
||||
assert "conventional" in result.output
|
||||
|
||||
@@ -94,6 +165,7 @@ class TestMain:
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_merge_pr_failure_raises_click(self, mock_client_cls: MagicMock) -> None:
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client.merge_pr.side_effect = APIError(http.HTTPStatus.INTERNAL_SERVER_ERROR, "server error")
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
@@ -105,6 +177,7 @@ class TestMain:
|
||||
@patch("scripts.auto_merge.GiteaClient")
|
||||
def test_merge_pr_json_parse_failure(self, mock_client_cls: MagicMock) -> None:
|
||||
mock_client = MagicMock()
|
||||
mock_client.get_pr_labels.return_value = [{"name": "ready-to-merge"}]
|
||||
mock_client.merge_pr.side_effect = APIError(http.HTTPStatus.BAD_GATEWAY, "bad gateway")
|
||||
mock_client_cls.return_value = mock_client
|
||||
runner = CliRunner()
|
||||
|
||||
Reference in New Issue
Block a user