@@ -30,6 +30,7 @@ import (
30
30
"ariga.io/atlas-action/atlasaction/cloud"
31
31
"ariga.io/atlas-go-sdk/atlasexec"
32
32
"ariga.io/atlas/sql/migrate"
33
+ "ariga.io/atlas/sql/sqlclient"
33
34
"github.com/fatih/color"
34
35
)
35
36
@@ -66,13 +67,16 @@ type (
66
67
MigrateLint (context.Context , * atlasexec.SummaryReport )
67
68
SchemaPlan (context.Context , * atlasexec.SchemaPlan )
68
69
SchemaApply (context.Context , * atlasexec.SchemaApply )
70
+ SchemaLint (context.Context , * SchemaLintReport )
69
71
}
70
72
// SCMClient contains methods for interacting with SCM platforms (GitHub, Gitlab etc...).
71
73
SCMClient interface {
72
74
// CommentLint comments on the pull request with the lint report.
73
75
CommentLint (context.Context , * TriggerContext , * atlasexec.SummaryReport ) error
74
76
// CommentPlan comments on the pull request with the schema plan.
75
77
CommentPlan (context.Context , * TriggerContext , * atlasexec.SchemaPlan ) error
78
+ // CommentSchemaLint comments on the pull request with the schema lint report.
79
+ CommentSchemaLint (context.Context , * TriggerContext , * SchemaLintReport ) error
76
80
}
77
81
Logger interface {
78
82
// Infof logs an info message.
@@ -115,6 +119,8 @@ type (
115
119
SchemaTest (context.Context , * atlasexec.SchemaTestParams ) (string , error )
116
120
// SchemaPlan runs the `schema plan` command.
117
121
SchemaPlan (context.Context , * atlasexec.SchemaPlanParams ) (* atlasexec.SchemaPlan , error )
122
+ // SchemaLint runs the `schema lint` command.
123
+ SchemaLint (context.Context , * atlasexec.SchemaLintParams ) (* atlasexec.SchemaLintReport , error )
118
124
// SchemaPlanList runs the `schema plan list` command.
119
125
SchemaPlanList (context.Context , * atlasexec.SchemaPlanListParams ) ([]atlasexec.SchemaPlanFile , error )
120
126
// SchemaPlanLint runs the `schema plan lint` command.
@@ -162,6 +168,10 @@ type (
162
168
Commit string // Latest commit SHA.
163
169
Body string // Body (description) of the pull request.
164
170
}
171
+ SchemaLintReport struct {
172
+ URL []string `json:"URL,omitempty"` // Redacted schema URLs
173
+ * atlasexec.SchemaLintReport
174
+ }
165
175
)
166
176
167
177
// AtlasDirectives returns any directives that are
@@ -297,6 +307,7 @@ const (
297
307
CmdMigrateAutoRebase = "migrate/autorebase"
298
308
// Declarative workflow Commands
299
309
CmdSchemaPush = "schema/push"
310
+ CmdSchemaLint = "schema/lint"
300
311
CmdSchemaTest = "schema/test"
301
312
CmdSchemaPlan = "schema/plan"
302
313
CmdSchemaPlanApprove = "schema/plan/approve"
@@ -328,6 +339,8 @@ func (a *Actions) Run(ctx context.Context, act string) error {
328
339
return a .MigrateAutoRebase (ctx )
329
340
case CmdSchemaPush :
330
341
return a .SchemaPush (ctx )
342
+ case CmdSchemaLint :
343
+ return a .SchemaLint (ctx )
331
344
case CmdSchemaTest :
332
345
return a .SchemaTest (ctx )
333
346
case CmdSchemaPlan :
@@ -725,6 +738,62 @@ func (a *Actions) SchemaPush(ctx context.Context) error {
725
738
return nil
726
739
}
727
740
741
+ // SchemaLint runs the GitHub Action for "ariga/atlas-action/schema/lint"
742
+ func (a * Actions ) SchemaLint (ctx context.Context ) error {
743
+ tc , err := a .GetTriggerContext (ctx )
744
+ switch {
745
+ case err != nil :
746
+ return fmt .Errorf ("unable to get the trigger context: %w" , err )
747
+ }
748
+ params := & atlasexec.SchemaLintParams {
749
+ ConfigURL : a .GetInput ("config" ),
750
+ Vars : a .GetVarsInput ("vars" ),
751
+ Env : a .GetInput ("env" ),
752
+ URL : a .GetArrayInput ("url" ),
753
+ Schema : a .GetArrayInput ("schema" ),
754
+ DevURL : a .GetInput ("dev-url" ),
755
+ }
756
+ report , err := a .Atlas .SchemaLint (ctx , params )
757
+ if err != nil {
758
+ a .SetOutput ("error" , err .Error ())
759
+ return fmt .Errorf ("`atlas schema lint` completed with errors:\n %s" , err )
760
+ }
761
+ if len (report .Steps ) == 0 {
762
+ a .Infof ("`atlas schema lint` completed successfully, no issues found" )
763
+ return nil
764
+ }
765
+ redactedURLs := make ([]string , 0 , len (params .URL ))
766
+ for _ , u := range params .URL {
767
+ redacted , err := redactedURL (u )
768
+ if err != nil {
769
+ a .Errorf ("failed to redact URL: %v" , err )
770
+ } else {
771
+ redactedURLs = append (redactedURLs , redacted )
772
+ }
773
+ }
774
+ rp := & SchemaLintReport {
775
+ URL : redactedURLs ,
776
+ SchemaLintReport : report ,
777
+ }
778
+ if r , ok := a .Action .(Reporter ); ok {
779
+ r .SchemaLint (ctx , rp )
780
+ }
781
+ if tc .PullRequest != nil {
782
+ switch c , err := tc .SCMClient (); {
783
+ case errors .Is (err , ErrNoSCM ):
784
+ a .Infof ("No SCM client available, skipping PR comment" )
785
+ case err != nil :
786
+ a .Errorf ("failed to get SCM client: %v" , err )
787
+ default :
788
+ if err = c .CommentSchemaLint (ctx , tc , rp ); err != nil {
789
+ a .Errorf ("failed to comment on the pull request: %v" , err )
790
+ }
791
+ }
792
+ }
793
+ a .Infof ("`atlas schema lint` completed successfully, no issues found" )
794
+ return nil
795
+ }
796
+
728
797
// SchemaTest runs the GitHub Action for "ariga/atlas-action/schema/test"
729
798
func (a * Actions ) SchemaTest (ctx context.Context ) error {
730
799
result , err := a .Atlas .SchemaTest (ctx , & atlasexec.SchemaTestParams {
@@ -1655,6 +1724,14 @@ func fprintln(name string, val ...any) error {
1655
1724
return err
1656
1725
}
1657
1726
1727
+ func redactedURL (s string ) (string , error ) {
1728
+ u , err := sqlclient .ParseURL (s )
1729
+ if err != nil {
1730
+ return "" , err
1731
+ }
1732
+ return u .Redacted (), nil
1733
+ }
1734
+
1658
1735
// commentMarker creates a hidden marker to identify the comment as one created by this action.
1659
1736
func commentMarker (id string ) string {
1660
1737
return fmt .Sprintf (`<!-- generated by ariga/atlas-action for %v -->` , id )
0 commit comments