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
4 changes: 3 additions & 1 deletion sqlmesh/integrations/github/cicd/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,9 @@ def _run_all(controller: GithubController) -> None:
if has_required_approval and prod_plan_generated and controller.pr_targets_prod_branch:
deployed_to_prod = _deploy_production(controller)
elif is_auto_deploying_prod:
if not has_required_approval:
if controller.deploy_command_enabled and not has_required_approval:
skip_reason = "Skipped Deploying to Production because a `/deploy` command has not been detected yet"
elif controller.do_required_approval_check and not has_required_approval:
skip_reason = (
"Skipped Deploying to Production because a required approver has not approved"
)
Expand Down
4 changes: 2 additions & 2 deletions sqlmesh/integrations/github/cicd/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ def conclusion_handler(
conclusion_to_title = {
GithubCheckConclusion.SUCCESS: "Deployed to Prod",
GithubCheckConclusion.CANCELLED: "Cancelled deploying to prod",
GithubCheckConclusion.SKIPPED: skip_reason,
GithubCheckConclusion.SKIPPED: "Skipped deployment",
GithubCheckConclusion.FAILURE: "Failed to deploy to prod",
GithubCheckConclusion.ACTION_REQUIRED: "Failed due to error applying plan",
}
Expand All @@ -1031,7 +1031,7 @@ def conclusion_handler(
or f"Got an unexpected conclusion: {conclusion.value}"
)
if conclusion.is_skipped:
summary = title
summary = skip_reason
elif conclusion.is_failure:
captured_errors = self._console.consume_captured_errors()
summary = (
Expand Down
71 changes: 71 additions & 0 deletions tests/integrations/github/cicd/test_github_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -1295,3 +1295,74 @@ def test_comment_command_deploy_prod_not_enabled(
with open(github_output_file, "r", encoding="utf-8") as f:
output = f.read()
assert output == ""


def test_comment_command_deploy_prod_no_deploy_detected_yet(
github_client,
make_controller,
make_mock_check_run,
make_mock_issue_comment,
tmp_path: pathlib.Path,
mocker: MockerFixture,
):
"""
Scenario:
- PR is not merged
- No requred approvers defined
- Tests passed
- PR Merge Method defined
- Deploy command enabled but not yet triggered

Outcome:
- "Prod Environment Synced" step should explain the reason why it was skipped is because /deploy has not yet been detected
"""
mock_repo = github_client.get_repo()
mock_repo.create_check_run = mocker.MagicMock(
side_effect=lambda **kwargs: make_mock_check_run(**kwargs)
)

created_comments = []
mock_issue = mock_repo.get_issue()
mock_issue.create_comment = mocker.MagicMock(
side_effect=lambda comment: make_mock_issue_comment(
comment=comment, created_comments=created_comments
)
)
mock_issue.get_comments = mocker.MagicMock(side_effect=lambda: created_comments)

mock_pull_request = mock_repo.get_pull()
mock_pull_request.get_reviews = mocker.MagicMock(lambda: [])
mock_pull_request.merged = False
mock_pull_request.merge = mocker.MagicMock()

controller = make_controller(
"tests/fixtures/github/pull_request_synchronized.json",
github_client,
bot_config=GithubCICDBotConfig(merge_method=MergeMethod.REBASE, enable_deploy_command=True),
)
controller._context._run_tests = mocker.MagicMock(
side_effect=lambda **kwargs: (TestResult(), "")
)

github_output_file = tmp_path / "github_output.txt"

with mock.patch.dict(os.environ, {"GITHUB_OUTPUT": str(github_output_file)}):
command._run_all(controller)

assert "SQLMesh - Prod Plan Preview" in controller._check_run_mapping
assert "SQLMesh - PR Environment Synced" in controller._check_run_mapping
assert "SQLMesh - Prod Environment Synced" in controller._check_run_mapping
assert "SQLMesh - Run Unit Tests" in controller._check_run_mapping
prod_checks_runs = controller._check_run_mapping["SQLMesh - Prod Environment Synced"].all_kwargs
assert len(prod_checks_runs) == 2
assert GithubCheckStatus(prod_checks_runs[0]["status"]).is_queued
assert GithubCheckStatus(prod_checks_runs[1]["status"]).is_completed
assert prod_checks_runs[1]["output"]["title"] == "Skipped deployment"
assert (
prod_checks_runs[1]["output"]["summary"]
== "Skipped Deploying to Production because a `/deploy` command has not been detected yet"
)
assert GithubCheckConclusion(prod_checks_runs[1]["conclusion"]).is_skipped

# required approvers are irrelevant because /deploy command is enabled
assert "SQLMesh - Has Required Approval" not in controller._check_run_mapping
24 changes: 15 additions & 9 deletions tests/integrations/github/cicd/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,11 @@ def test_merge_pr_has_non_breaking_change_no_categorization(
assert GithubCheckStatus(prod_checks_runs[0]["status"]).is_queued
assert GithubCheckStatus(prod_checks_runs[1]["status"]).is_completed
assert GithubCheckConclusion(prod_checks_runs[1]["conclusion"]).is_skipped
skip_reason = "Skipped Deploying to Production because the PR environment was not updated"
assert prod_checks_runs[1]["output"]["title"] == skip_reason
assert prod_checks_runs[1]["output"]["summary"] == skip_reason
assert prod_checks_runs[1]["output"]["title"] == "Skipped deployment"
assert (
prod_checks_runs[1]["output"]["summary"]
== "Skipped Deploying to Production because the PR environment was not updated"
)

assert "SQLMesh - Has Required Approval" in controller._check_run_mapping
approval_checks_runs = controller._check_run_mapping[
Expand Down Expand Up @@ -1024,9 +1026,11 @@ def test_no_merge_since_no_deploy_signal(
assert GithubCheckStatus(prod_checks_runs[0]["status"]).is_queued
assert GithubCheckStatus(prod_checks_runs[1]["status"]).is_completed
assert GithubCheckConclusion(prod_checks_runs[1]["conclusion"]).is_skipped
skip_reason = "Skipped Deploying to Production because a required approver has not approved"
assert prod_checks_runs[1]["output"]["title"] == skip_reason
assert prod_checks_runs[1]["output"]["summary"] == skip_reason
assert prod_checks_runs[1]["output"]["title"] == "Skipped deployment"
assert (
prod_checks_runs[1]["output"]["summary"]
== "Skipped Deploying to Production because a required approver has not approved"
)

assert "SQLMesh - Has Required Approval" in controller._check_run_mapping
approval_checks_runs = controller._check_run_mapping[
Expand Down Expand Up @@ -1528,9 +1532,11 @@ def test_error_msg_when_applying_plan_with_bug(
assert GithubCheckStatus(prod_checks_runs[0]["status"]).is_queued
assert GithubCheckStatus(prod_checks_runs[1]["status"]).is_completed
assert GithubCheckConclusion(prod_checks_runs[1]["conclusion"]).is_skipped
skip_reason = "Skipped Deploying to Production because the PR environment was not updated"
assert prod_checks_runs[1]["output"]["title"] == skip_reason
assert prod_checks_runs[1]["output"]["summary"] == skip_reason
assert prod_checks_runs[1]["output"]["title"] == "Skipped deployment"
assert (
prod_checks_runs[1]["output"]["summary"]
== "Skipped Deploying to Production because the PR environment was not updated"
)

assert "SQLMesh - Has Required Approval" in controller._check_run_mapping
approval_checks_runs = controller._check_run_mapping[
Expand Down