2929 format_intervals ,
3030)
3131from sqlmesh .core .user import User
32+ from sqlmesh .core .config import Config
3233from sqlmesh .integrations .github .cicd .config import GithubCICDBotConfig
3334from sqlmesh .utils import word_characters_only , Verbosity
3435from sqlmesh .utils .concurrency import NodeExecutionFailedError
3839 NoChangesPlanError ,
3940 PlanError ,
4041 UncategorizedPlanError ,
42+ LinterError ,
4143)
4244from sqlmesh .utils .pydantic import PydanticModel
4345
5052 from github .PullRequestReview import PullRequestReview
5153 from github .Repository import Repository
5254
53- from sqlmesh .core .config import Config
54-
5555logger = logging .getLogger (__name__ )
5656
5757
@@ -302,6 +302,7 @@ def __init__(
302302 self ._prod_plan_builder : t .Optional [PlanBuilder ] = None
303303 self ._prod_plan_with_gaps_builder : t .Optional [PlanBuilder ] = None
304304 self ._check_run_mapping : t .Dict [str , CheckRun ] = {}
305+ self ._linter_error = False
305306
306307 if not isinstance (get_console (), MarkdownConsole ):
307308 raise CICDBotError ("Console must be a markdown console." )
@@ -326,10 +327,8 @@ def __init__(
326327 if review .state .lower () == "approved"
327328 }
328329 logger .debug (f"Approvers: { ', ' .join (self ._approvers )} " )
329- self ._context : Context = Context (
330- paths = self ._paths ,
331- config = self .config ,
332- )
330+
331+ self ._context : Context = Context (paths = self ._paths , config = self .config )
333332
334333 @property
335334 def deploy_command_enabled (self ) -> bool :
@@ -394,6 +393,7 @@ def pr_plan(self) -> Plan:
394393 self ._pr_plan_builder = self ._context .plan_builder (
395394 environment = self .pr_environment_name ,
396395 skip_tests = True ,
396+ skip_linter = True ,
397397 categorizer_config = self .bot_config .auto_categorize_changes ,
398398 start = self .bot_config .default_pr_start ,
399399 skip_backfill = self .bot_config .skip_pr_backfill ,
@@ -408,6 +408,7 @@ def prod_plan(self) -> Plan:
408408 self ._prod_plan_builder = self ._context .plan_builder (
409409 c .PROD ,
410410 no_gaps = True ,
411+ skip_backfill = True ,
411412 skip_tests = True ,
412413 categorizer_config = self .bot_config .auto_categorize_changes ,
413414 run = self .bot_config .run_on_deploy_to_prod ,
@@ -478,6 +479,13 @@ def run_tests(self) -> t.Tuple[unittest.result.TestResult, str]:
478479 """
479480 return self ._context ._run_tests (verbosity = Verbosity .VERBOSE )
480481
482+ def run_linter (self ) -> None :
483+ """
484+ Run linter for the PR
485+ """
486+ # self._console.clear_captured_outputs()
487+ self ._context .lint_models (console = self ._console )
488+
481489 def _get_or_create_comment (self , header : str = BOT_HEADER_MSG ) -> IssueComment :
482490 comment = seq_get (
483491 [comment for comment in self ._issue .get_comments () if header in comment .body ],
@@ -654,6 +662,34 @@ def _update_check_handler(
654662 full_summary = summary ,
655663 )
656664
665+ def update_linter_check (
666+ self ,
667+ status : GithubCheckStatus ,
668+ conclusion : t .Optional [GithubCheckConclusion ] = None ,
669+ ) -> None :
670+ def conclusion_handler (
671+ conclusion : GithubCheckConclusion ,
672+ ) -> t .Tuple [GithubCheckConclusion , str , t .Optional [str ]]:
673+ linter_summary = self ._console .consume_captured_output () or "Linter Success"
674+
675+ title = "Linter results"
676+
677+ return conclusion , title , linter_summary
678+
679+ self ._update_check_handler (
680+ check_name = "SQLMesh - Linter" ,
681+ status = status ,
682+ conclusion = conclusion ,
683+ status_handler = lambda status : (
684+ {
685+ GithubCheckStatus .IN_PROGRESS : "Running linter" ,
686+ GithubCheckStatus .QUEUED : "Waiting to Run linter" ,
687+ }[status ],
688+ None ,
689+ ),
690+ conclusion_handler = conclusion_handler ,
691+ )
692+
657693 def update_test_check (
658694 self ,
659695 status : GithubCheckStatus ,
@@ -751,7 +787,7 @@ def update_pr_environment_check(
751787 Updates the status of the merge commit for the PR environment.
752788 """
753789 conclusion : t .Optional [GithubCheckConclusion ] = None
754- if isinstance (exception , (NoChangesPlanError , TestFailure )):
790+ if isinstance (exception , (NoChangesPlanError , TestFailure , LinterError )):
755791 conclusion = GithubCheckConclusion .SKIPPED
756792 elif isinstance (exception , UncategorizedPlanError ):
757793 conclusion = GithubCheckConclusion .ACTION_REQUIRED
0 commit comments