Skip to content

Commit 079efc8

Browse files
authored
Chore!: Update ci/cd bot default behaviour to match CLI behaviour (#4900)
1 parent 8be77dc commit 079efc8

File tree

5 files changed

+77
-10
lines changed

5 files changed

+77
-10
lines changed

docs/integrations/github.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,13 @@ Below is an example of how to define the default config for the bot in either YA
293293
| `enable_deploy_command` | Indicates if the `/deploy` command should be enabled in order to allowed synchronized deploys to production. Default: `False` | bool | N |
294294
| `command_namespace` | The namespace to use for SQLMesh commands. For example if you provide `#SQLMesh` as a value then commands will be expected in the format of `#SQLMesh/<command>`. Default: `None` meaning no namespace is used. | string | N |
295295
| `auto_categorize_changes` | Auto categorization behavior to use for the bot. If not provided then the project-wide categorization behavior is used. See [Auto-categorize model changes](https://sqlmesh.readthedocs.io/en/stable/guides/configuration/#auto-categorize-model-changes) for details. | dict | N |
296-
| `default_pr_start` | Default start when creating PR environment plans. If running in a mode where the bot automatically backfills models (based on `auto_categorize_changes` behavior) then this can be used to limit the amount of data backfilled. Defaults to `None` meaning the start date is set to the earliest model's start or to 1 day ago if [data previews](../concepts/plans.md#data-preview) need to be computed. | str | N |
296+
| `default_pr_start` | Default start when creating PR environment plans. If running in a mode where the bot automatically backfills models (based on `auto_categorize_changes` behavior) then this can be used to limit the amount of data backfilled. Defaults to `None` meaning the start date is set to the earliest model's start or to 1 day ago if [data previews](../concepts/plans.md#data-preview) need to be computed.| str | N |
297297
| `pr_min_intervals` | Intended for use when `default_pr_start` is set to a relative time, eg `1 week ago`. This ensures that at least this many intervals across every model are included for backfill in the PR environment. Without this, models with an interval unit wider than `default_pr_start` (such as `@monthly` models if `default_pr_start` was set to `1 week ago`) will be excluded from backfill entirely. | int | N |
298298
| `skip_pr_backfill` | Indicates if the bot should skip backfilling models in the PR environment. Default: `True` | bool | N |
299299
| `pr_include_unmodified` | Indicates whether to include unmodified models in the PR environment. Default to the project's config value (which defaults to `False`) | bool | N |
300300
| `run_on_deploy_to_prod` | Indicates whether to run latest intervals when deploying to prod. If set to false, the deployment will backfill only the changed models up to the existing latest interval in production, ignoring any missing intervals beyond this point. Default: `False` | bool | N |
301301
| `pr_environment_name` | The name of the PR environment to create for which a PR number will be appended to. Defaults to the repo name if not provided. Note: The name will be normalized to alphanumeric + underscore and lowercase. | str | N |
302-
| `prod_branch_name` | The name of the git branch associated with production. Ex: `prod`. Default: `main` or `master` is considered prod | str | N |
302+
| `prod_branch_name` | The name of the git branch associated with production. Ex: `prod`. Default: `main` or `master` is considered prod | str | N |
303303

304304
Example with all properties defined:
305305

sqlmesh/core/config/root.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,18 @@ def _normalize_identifiers(key: str) -> None:
260260

261261
return self
262262

263+
@model_validator(mode="after")
264+
def _inherit_project_config_in_cicd_bot(self) -> Self:
265+
if self.cicd_bot:
266+
# inherit the project-level settings into the CICD bot if they have not been explicitly overridden
267+
if self.cicd_bot.auto_categorize_changes_ is None:
268+
self.cicd_bot.auto_categorize_changes_ = self.plan.auto_categorize_changes
269+
270+
if self.cicd_bot.pr_include_unmodified_ is None:
271+
self.cicd_bot.pr_include_unmodified_ = self.plan.include_unmodified
272+
273+
return self
274+
263275
def get_default_test_connection(
264276
self,
265277
default_catalog: t.Optional[str] = None,

sqlmesh/integrations/github/cicd/config.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from sqlmesh.core.config.base import BaseConfig
88
from sqlmesh.utils.date import TimeLike
99
from sqlmesh.utils.pydantic import model_validator
10+
from sqlmesh.core.console import get_console
1011

1112

1213
class MergeMethod(str, Enum):
@@ -22,10 +23,12 @@ class GithubCICDBotConfig(BaseConfig):
2223
enable_deploy_command: bool = False
2324
merge_method: t.Optional[MergeMethod] = None
2425
command_namespace: t.Optional[str] = None
25-
auto_categorize_changes: CategorizerConfig = CategorizerConfig.all_off()
26+
auto_categorize_changes_: t.Optional[CategorizerConfig] = Field(
27+
default=None, alias="auto_categorize_changes"
28+
)
2629
default_pr_start: t.Optional[TimeLike] = None
27-
skip_pr_backfill: bool = True
28-
pr_include_unmodified: t.Optional[bool] = None
30+
skip_pr_backfill_: t.Optional[bool] = Field(default=None, alias="skip_pr_backfill")
31+
pr_include_unmodified_: t.Optional[bool] = Field(default=None, alias="pr_include_unmodified")
2932
run_on_deploy_to_prod: bool = False
3033
pr_environment_name: t.Optional[str] = None
3134
pr_min_intervals: t.Optional[int] = None
@@ -50,6 +53,26 @@ def prod_branch_names(self) -> t.List[str]:
5053
return [self.prod_branch_names_]
5154
return ["main", "master"]
5255

56+
@property
57+
def auto_categorize_changes(self) -> CategorizerConfig:
58+
return self.auto_categorize_changes_ or CategorizerConfig.all_off()
59+
60+
@property
61+
def pr_include_unmodified(self) -> bool:
62+
return self.pr_include_unmodified_ or False
63+
64+
@property
65+
def skip_pr_backfill(self) -> bool:
66+
if self.skip_pr_backfill_ is None:
67+
get_console().log_warning(
68+
"`skip_pr_backfill` is unset, defaulting it to `true` (no data will be backfilled).\n"
69+
"Future versions of SQLMesh will default to `skip_pr_backfill: false` to align with the CLI default behaviour.\n"
70+
"If you would like to preserve the current behaviour and remove this warning, please explicitly set `skip_pr_backfill: true` in the bot config.\n\n"
71+
"For more information on configuring the bot, see: https://sqlmesh.readthedocs.io/en/stable/integrations/github/"
72+
)
73+
return True
74+
return self.skip_pr_backfill_
75+
5376
FIELDS_FOR_ANALYTICS: t.ClassVar[t.Set[str]] = {
5477
"invalidate_environment_after_deploy",
5578
"enable_deploy_command",

tests/core/analytics/test_collector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def test_on_cicd_command(collector: AnalyticsCollector, mocker: MockerFixture):
145145
{
146146
"seq_num": 1,
147147
"event_type": "CICD_COMMAND",
148-
"event": '{"command_name": "test_cicd", "command_args": ["arg_1", "arg_2"], "parent_command_names": ["parent_a", "parent_b"], "cicd_bot_config": {"invalidate_environment_after_deploy": true, "enable_deploy_command": false, "auto_categorize_changes": {"external": "off", "python": "off", "sql": "off", "seed": "off"}, "skip_pr_backfill": true, "run_on_deploy_to_prod": false}}',
148+
"event": '{"command_name": "test_cicd", "command_args": ["arg_1", "arg_2"], "parent_command_names": ["parent_a", "parent_b"], "cicd_bot_config": {"invalidate_environment_after_deploy": true, "enable_deploy_command": false, "run_on_deploy_to_prod": false}}',
149149
**common_fields,
150150
}
151151
),

tests/integrations/github/cicd/test_config.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ def test_load_yaml_config_default(tmp_path):
3434
assert config.cicd_bot.invalidate_environment_after_deploy
3535
assert config.cicd_bot.merge_method is None
3636
assert config.cicd_bot.command_namespace is None
37-
assert config.cicd_bot.auto_categorize_changes == CategorizerConfig.all_off()
37+
assert config.cicd_bot.auto_categorize_changes == config.plan.auto_categorize_changes
3838
assert config.cicd_bot.default_pr_start is None
3939
assert not config.cicd_bot.enable_deploy_command
4040
assert config.cicd_bot.skip_pr_backfill
41-
assert config.cicd_bot.pr_include_unmodified is None
41+
assert not config.cicd_bot.pr_include_unmodified
4242
assert config.cicd_bot.pr_environment_name is None
4343
assert config.cicd_bot.prod_branch_names == ["main", "master"]
4444
assert not config.cicd_bot.pr_min_intervals
@@ -115,11 +115,11 @@ def test_load_python_config_defaults(tmp_path):
115115
assert config.cicd_bot.invalidate_environment_after_deploy
116116
assert config.cicd_bot.merge_method is None
117117
assert config.cicd_bot.command_namespace is None
118-
assert config.cicd_bot.auto_categorize_changes == CategorizerConfig.all_off()
118+
assert config.cicd_bot.auto_categorize_changes == config.plan.auto_categorize_changes
119119
assert config.cicd_bot.default_pr_start is None
120120
assert not config.cicd_bot.enable_deploy_command
121121
assert config.cicd_bot.skip_pr_backfill
122-
assert config.cicd_bot.pr_include_unmodified is None
122+
assert not config.cicd_bot.pr_include_unmodified
123123
assert config.cicd_bot.pr_environment_name is None
124124
assert config.cicd_bot.prod_branch_names == ["main", "master"]
125125
assert not config.cicd_bot.pr_min_intervals
@@ -258,3 +258,35 @@ def test_ttl_in_past(tmp_path):
258258
match="TTL '1 week' is in the past. Please specify a relative time in the future. Ex: `in 1 week` instead of `1 week`.",
259259
):
260260
load_config_from_paths(Config, project_paths=[tmp_path / "config.yaml"])
261+
262+
263+
def test_properties_inherit_from_project_config(tmp_path):
264+
(tmp_path / "config.yaml").write_text("""
265+
plan:
266+
auto_categorize_changes:
267+
external: off
268+
python: full
269+
sql: off
270+
seed: full
271+
include_unmodified: true
272+
273+
cicd_bot:
274+
type: github
275+
276+
model_defaults:
277+
dialect: duckdb
278+
""")
279+
280+
config = load_config_from_paths(Config, [tmp_path / "config.yaml"])
281+
282+
assert (
283+
config.cicd_bot.auto_categorize_changes
284+
== config.plan.auto_categorize_changes
285+
== CategorizerConfig(
286+
external=AutoCategorizationMode.OFF,
287+
python=AutoCategorizationMode.FULL,
288+
sql=AutoCategorizationMode.OFF,
289+
seed=AutoCategorizationMode.FULL,
290+
)
291+
)
292+
assert config.cicd_bot.pr_include_unmodified == config.plan.include_unmodified == True

0 commit comments

Comments
 (0)