diff --git a/tool/actions-plan-preview/Dockerfile b/tool/actions-plan-preview/Dockerfile index 81e8520d98..c2e340e22c 100644 --- a/tool/actions-plan-preview/Dockerfile +++ b/tool/actions-plan-preview/Dockerfile @@ -5,7 +5,7 @@ RUN go mod download COPY . ./ RUN go build -o /plan-preview . -FROM ghcr.io/pipe-cd/pipectl:v0.43.1 +FROM ghcr.io/pipe-cd/pipectl:v0.53.0 COPY --from=builder /plan-preview / ENV PATH=$PATH:/app/cmd/pipectl RUN chmod +x /plan-preview diff --git a/tool/actions-plan-preview/go.mod b/tool/actions-plan-preview/go.mod index add8067367..48b1dd3a4c 100644 --- a/tool/actions-plan-preview/go.mod +++ b/tool/actions-plan-preview/go.mod @@ -4,17 +4,22 @@ go 1.24.1 require ( github.com/google/go-github/v36 v36.0.0 + github.com/pipe-cd/pipecd v0.53.0 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 - github.com/stretchr/testify v1.7.0 + github.com/stretchr/testify v1.10.0 golang.org/x/oauth2 v0.27.0 ) require ( - github.com/davecgh/go-spew v1.1.0 // indirect + github.com/coreos/go-oidc/v3 v3.11.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect + github.com/go-jose/go-jose/v4 v4.0.5 // indirect github.com/google/go-querystring v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect golang.org/x/crypto v0.36.0 // indirect golang.org/x/net v0.38.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/tool/actions-plan-preview/go.sum b/tool/actions-plan-preview/go.sum index fa3003c5a5..3ea7a329a0 100644 --- a/tool/actions-plan-preview/go.sum +++ b/tool/actions-plan-preview/go.sum @@ -1,22 +1,29 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= +github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= +github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github/v36 v36.0.0 h1:ndCzM616/oijwufI7nBRa+5eZHLldT+4yIB68ib5ogs= github.com/google/go-github/v36 v36.0.0/go.mod h1:LFlKC047IOqiglRGNqNb9s/iAPTnnjtlshm+bxp+kwk= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/pipe-cd/pipecd v0.53.0 h1:q6AiDhPFsS0enAehvn2UTVJMKfdnLDPB1BNo6Pr+FgQ= +github.com/pipe-cd/pipecd v0.53.0/go.mod h1:BI0uxrpeuxcjFykL5+tnLc5DRd8v24Hm/it7fBOth6Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= @@ -30,8 +37,9 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tool/actions-plan-preview/planpreview.go b/tool/actions-plan-preview/planpreview.go index 7c9564718a..bb7583e74a 100644 --- a/tool/actions-plan-preview/planpreview.go +++ b/tool/actions-plan-preview/planpreview.go @@ -28,6 +28,8 @@ import ( "unicode/utf8" "github.com/shurcooL/githubv4" + + "github.com/pipe-cd/pipecd/pkg/model" ) type PlanPreviewResult struct { @@ -47,9 +49,13 @@ func (r *PlanPreviewResult) NoChange() bool { type ApplicationResult struct { ApplicationInfo SyncStrategy string // QUICK_SYNC, PIPELINE - PlanSummary string - PlanDetails string - NoChange bool + // Deprecated: Use PluginPlanResults in pipedv1 + PlanSummary string + // Deprecated: Use PluginPlanResults in pipedv1 + PlanDetails string + NoChange bool + + PluginPlanResults []*model.PluginPlanPreviewResult } type FailurePiped struct { @@ -59,8 +65,11 @@ type FailurePiped struct { type FailureApplication struct { ApplicationInfo - Reason string + Reason string + // Deprecated: Use PluginPlanResults in pipedv1 PlanDetails string + + PluginPlanResults []*model.PluginPlanPreviewResult } type PipedInfo struct { @@ -69,12 +78,16 @@ type PipedInfo struct { } type ApplicationInfo struct { - ApplicationID string - ApplicationName string - ApplicationURL string - Env string + ApplicationID string + ApplicationName string + ApplicationURL string + Env string + // Deprecated: Use PluginNames in pipedv1 ApplicationKind string // KUBERNETES, TERRAFORM, CLOUDRUN, LAMBDA, ECS ApplicationDirectory string + + PlannedPluginNames string + AllPluginNames string } func retrievePlanPreview( @@ -133,12 +146,14 @@ const ( failureBadgeURL = `[![PLAN_PREVIEW](https://img.shields.io/static/v1?label=PipeCD&message=Plan_Preview&color=orange&style=flat)](https://pipecd.dev/docs/user-guide/plan-preview/)` actionBadgeURLFormat = "[![ACTIONS](https://img.shields.io/static/v1?label=PipeCD&message=Action_Log&style=flat)](%s)" - noChangeTitleFormat = "Ran plan-preview against head commit %s of this pull request. PipeCD detected `0` updated application. It means no deployment will be triggered once this pull request got merged.\n" - hasChangeTitleFormat = "Ran plan-preview against head commit %s of this pull request. PipeCD detected `%d` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations.\n" - detailsFormat = "
\nDetails (Click me)\n

\n\n``` %s\n%s\n```\n

\n
\n\n" - detailsOmittedMessage = "The details are too long to display. Please check the actions log to see full details." - appInfoWithEnvFormat = "app: [%s](%s), env: %s, kind: %s" - appInfoWithoutEnvFormat = "app: [%s](%s), kind: %s" + noChangeTitleFormat = "Ran plan-preview against head commit %s of this pull request. PipeCD detected `0` updated application. It means no deployment will be triggered once this pull request got merged.\n" + hasChangeTitleFormat = "Ran plan-preview against head commit %s of this pull request. PipeCD detected `%d` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations.\n" + detailsFormat = "
\nDetails (Click me)\n

\n\n``` %s\n%s\n```\n

\n
\n\n" + detailsOmittedMessage = "The details are too long to display. Please check the actions log to see full details." + appInfoWithEnvFormat = "app: [%s](%s), env: %s, kind: %s" + appInfoWithoutEnvFormat = "app: [%s](%s), kind: %s" + appInfoWithEnvFormatV1 = "app: [%s](%s), env: %s, planned plugin(s): %s" + appInfoWithoutEnvFormatV1 = "app: [%s](%s), planned plugin(s): %s" ghMessageLenLimit = 65536 @@ -196,30 +211,67 @@ func makeCommentBody(event *githubEvent, r *PlanPreviewResult, title string) str for _, app := range changedApps { fmt.Fprintf(&b, "### %s\n", makeTitleText(&app.ApplicationInfo)) fmt.Fprintf(&b, "Sync strategy: %s\n", app.SyncStrategy) - fmt.Fprintf(&b, "Summary: %s\n\n", app.PlanSummary) - - var ( - lang = "diff" - details = app.PlanDetails - ) - if app.ApplicationKind == "TERRAFORM" { - lang = "hcl" - if shortened, err := generateTerraformShortPlanDetails(details); err == nil { - details = shortened + + if app.AllPluginNames == "" { + // pipedv0 + fmt.Fprintf(&b, "Summary: %s\n\n", app.PlanSummary) + var ( + lang = "diff" + details = app.PlanDetails + ) + if app.ApplicationKind == "TERRAFORM" { + lang = "hcl" + if shortened, err := generateTerraformShortPlanDetails(details); err == nil { + details = shortened + } } - } - l := utf8.RuneCountInString(details) - if detailLen+l > detailsLenLimit { - fmt.Fprintf(&b, detailsFormat, lang, detailsOmittedMessage) - detailLen += utf8.RuneCountInString(detailsOmittedMessage) - continue - } + l := utf8.RuneCountInString(details) + if detailLen+l > detailsLenLimit { + fmt.Fprintf(&b, detailsFormat, lang, detailsOmittedMessage) + detailLen += utf8.RuneCountInString(detailsOmittedMessage) + continue + } - if l > 0 { - detailLen += l - fmt.Fprintf(&b, detailsFormat, lang, details) + if l > 0 { + detailLen += l + fmt.Fprintf(&b, detailsFormat, lang, details) + } + } else { + // pipedv1 + fmt.Fprintf(&b, " Plugin(s): %s\n", app.AllPluginNames) + fmt.Fprintf(&b, " Summary:\n") + for _, ppr := range app.PluginPlanResults { + fmt.Fprintf(&b, " - %s(%s): %s\n", ppr.PluginName, ppr.DeployTarget, ppr.PlanSummary) + } + fmt.Fprint(&b, " Details:\n") + for _, ppr := range app.PluginPlanResults { + fmt.Fprintf(&b, " - %s(%s):\n", ppr.PluginName, ppr.DeployTarget) + + details := string(ppr.PlanDetails) + switch ppr.DiffLanguage { + case "": + ppr.DiffLanguage = "diff" // Use diff by default + case "hcl": + if shortened, err := generateTerraformShortPlanDetails(details); err == nil { + details = shortened + } + } + + l := utf8.RuneCountInString(details) + if detailLen+l > detailsLenLimit { + fmt.Fprintf(&b, detailsFormat, ppr.DiffLanguage, detailsOmittedMessage) + detailLen += utf8.RuneCountInString(detailsOmittedMessage) + continue + } + + if l > 0 { + detailLen += l + fmt.Fprintf(&b, detailsFormat, ppr.DiffLanguage, details) + } + } } + } if len(pipelineApps)+len(quickSyncApps) > 0 { @@ -253,13 +305,24 @@ func makeCommentBody(event *githubEvent, r *PlanPreviewResult, title string) str fmt.Fprintf(&b, "\n### %s\n", makeTitleText(&app.ApplicationInfo)) fmt.Fprintf(&b, "Reason: %s\n\n", app.Reason) - var lang = "diff" - if app.ApplicationKind == "TERRAFORM" { - lang = "hcl" - } - - if len(app.PlanDetails) > 0 { - fmt.Fprintf(&b, detailsFormat, lang, app.PlanDetails) + if app.AllPluginNames == "" { + // pipedv0 + var lang = "diff" + if app.ApplicationKind == "TERRAFORM" { + lang = "hcl" + } + + if len(app.PlanDetails) > 0 { + fmt.Fprintf(&b, detailsFormat, lang, app.PlanDetails) + } + } else { + // pipedv1 + for _, ppr := range app.PluginPlanResults { + fmt.Fprintf(&b, " - %s(%s):\n", ppr.PluginName, ppr.DeployTarget) + if len(ppr.PlanDetails) > 0 { + fmt.Fprintf(&b, detailsFormat, ppr.DiffLanguage, ppr.PlanDetails) + } + } } } } @@ -311,10 +374,19 @@ func makeActionLogURL() string { } func makeTitleText(app *ApplicationInfo) string { - if app.Env == "" { - return fmt.Sprintf(appInfoWithoutEnvFormat, app.ApplicationName, app.ApplicationURL, strings.ToLower(app.ApplicationKind)) + if app.AllPluginNames == "" { + // pipedv0 + if app.Env == "" { + return fmt.Sprintf(appInfoWithoutEnvFormat, app.ApplicationName, app.ApplicationURL, strings.ToLower(app.ApplicationKind)) + } + return fmt.Sprintf(appInfoWithEnvFormat, app.ApplicationName, app.ApplicationURL, app.Env, strings.ToLower(app.ApplicationKind)) + } else { + // pipedv1 + if app.Env == "" { + return fmt.Sprintf(appInfoWithoutEnvFormatV1, app.ApplicationName, app.ApplicationURL, app.PlannedPluginNames) + } + return fmt.Sprintf(appInfoWithEnvFormatV1, app.ApplicationName, app.ApplicationURL, app.Env, app.PlannedPluginNames) } - return fmt.Sprintf(appInfoWithEnvFormat, app.ApplicationName, app.ApplicationURL, app.Env, strings.ToLower(app.ApplicationKind)) } func generateTerraformShortPlanDetails(details string) (string, error) { diff --git a/tool/actions-plan-preview/planpreview_test.go b/tool/actions-plan-preview/planpreview_test.go index e1beb638ce..10f410ff41 100644 --- a/tool/actions-plan-preview/planpreview_test.go +++ b/tool/actions-plan-preview/planpreview_test.go @@ -20,6 +20,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/pipe-cd/pipecd/pkg/model" ) func TestMakeCommentBody(t *testing.T) { @@ -233,6 +235,151 @@ func TestMakeCommentBody(t *testing.T) { }, expected: "testdata/comment-has-failed-piped.txt", }, + // pipedv1 + { + name: "plugin: one success app", + event: githubEvent{ + HeadCommit: "abc", + }, + title: "", + result: PlanPreviewResult{ + Applications: []ApplicationResult{ + { + ApplicationInfo: ApplicationInfo{ + ApplicationID: "app-1", + ApplicationName: "app-name-1", + ApplicationURL: "app-url-1", + Env: "env-1", + PlannedPluginNames: "kubernetes", + AllPluginNames: "kubernetes", + ApplicationDirectory: "app-dir-1", + }, + SyncStrategy: "QUICK_SYNC", + NoChange: false, + PluginPlanResults: []*model.PluginPlanPreviewResult{ + { + PluginName: "kubernetes", + DeployTarget: "dt-1", + PlanSummary: []byte("2 resources will be added, 1 resource will be deleted and 5 resources will be changed"), + PlanDetails: []byte("details-1"), + }, + }, + }, + }, + }, + expected: "testdata/comment-plugin-one-success-app.txt", + }, + { + name: "plugin: one success app with multiple plugins", + event: githubEvent{ + HeadCommit: "abc", + }, + title: "", + result: PlanPreviewResult{ + Applications: []ApplicationResult{ + { + ApplicationInfo: ApplicationInfo{ + ApplicationID: "app-1", + ApplicationName: "app-name-1", + ApplicationURL: "app-url-1", + Env: "env-1", + PlannedPluginNames: "kubernetes, terraform", + AllPluginNames: "kubernetes, terraform, analysis", + ApplicationDirectory: "app-dir-1", + }, + SyncStrategy: "PIPELINE", + NoChange: false, + PluginPlanResults: []*model.PluginPlanPreviewResult{ + { + PluginName: "kubernetes", + DeployTarget: "dt-1", + PlanSummary: []byte("2 resources will be added, 1 resource will be deleted and 5 resources will be changed"), + PlanDetails: []byte("details-1"), + }, + { + PluginName: "terraform", + DeployTarget: "dt-2", + PlanSummary: []byte("1 resource will be added, 2 resources will be deleted and 3 resources will be changed"), + PlanDetails: []byte("details-2"), + DiffLanguage: "hcl", + }, + }, + }, + }, + }, + expected: "testdata/comment-plugin-one-success-app-multiple-plugins.txt", + }, + { + name: "plugin: has failed app", + event: githubEvent{ + HeadCommit: "abc", + }, + title: "", + result: PlanPreviewResult{ + Applications: []ApplicationResult{ + { + ApplicationInfo: ApplicationInfo{ + ApplicationID: "app-1", + ApplicationName: "app-name-1", + ApplicationURL: "app-url-1", + Env: "env-1", + PlannedPluginNames: "kubernetes", + AllPluginNames: "kubernetes", + ApplicationDirectory: "app-dir-1", + }, + SyncStrategy: "PIPELINE", + NoChange: false, + PluginPlanResults: []*model.PluginPlanPreviewResult{ + { + PluginName: "kubernetes", + DeployTarget: "dt-1", + PlanSummary: []byte("2 resources will be added, 1 resource will be deleted and 5 resources will be changed"), + PlanDetails: []byte("details-1"), + }, + }, + }, + }, + FailureApplications: []FailureApplication{ + { + ApplicationInfo: ApplicationInfo{ + ApplicationID: "app-2", + ApplicationName: "app-name-2", + ApplicationURL: "app-url-2", + Env: "env-2", + PlannedPluginNames: "kubernetes-failed", + AllPluginNames: "kubernetes-failed", + ApplicationDirectory: "app-dir-2", + }, + Reason: "wrong application configuration", + }, + }, + }, + expected: "testdata/comment-plugin-has-failed-app.txt", + }, + { + name: "plugin: one failure app with unknown plugin", + event: githubEvent{ + HeadCommit: "abc", + }, + title: "", + result: PlanPreviewResult{ + FailureApplications: []FailureApplication{ + { + ApplicationInfo: ApplicationInfo{ + ApplicationID: "app-2", + ApplicationName: "app-name-2", + ApplicationURL: "app-url-2", + Env: "env-2", + PlannedPluginNames: "", + AllPluginNames: "", + ApplicationDirectory: "app-dir-2", + }, + Reason: "wrong application configuration", + }, + }, + }, + expected: "testdata/comment-plugin-one-failure-app-unknown-plugin.txt", + }, } for _, tc := range testcases { @@ -724,3 +871,62 @@ guarantee to take exactly these actions if you run "terraform apply" now.`, }) } } + +func TestMakeTitleText(t *testing.T) { + t.Parallel() + + testcases := []struct { + name string + app *ApplicationInfo + want string + }{ + { + name: "pipedv0: without env", + app: &ApplicationInfo{ + ApplicationName: "test-app", + ApplicationURL: "https://pipecd.dev/apps/test-app", + ApplicationKind: "KUBERNETES", + }, + want: "app: [test-app](https://pipecd.dev/apps/test-app), kind: kubernetes", + }, + { + name: "pipedv0: with env", + app: &ApplicationInfo{ + ApplicationName: "test-app", + ApplicationURL: "https://pipecd.dev/apps/test-app", + ApplicationKind: "KUBERNETES", + Env: "dev", + }, + want: "app: [test-app](https://pipecd.dev/apps/test-app), env: dev, kind: kubernetes", + }, + { + name: "pipedv1: without env", + app: &ApplicationInfo{ + ApplicationName: "test-app", + ApplicationURL: "https://pipecd.dev/apps/test-app", + PlannedPluginNames: "kubernetes", + AllPluginNames: "kubernetes,analysis", + }, + want: "app: [test-app](https://pipecd.dev/apps/test-app), planned plugin(s): kubernetes", + }, + { + name: "pipedv1: with env", + app: &ApplicationInfo{ + ApplicationName: "test-app", + ApplicationURL: "https://pipecd.dev/apps/test-app", + PlannedPluginNames: "kubernetes,terraform", + AllPluginNames: "kubernetes,terraform,analysis", + Env: "dev", + }, + want: "app: [test-app](https://pipecd.dev/apps/test-app), env: dev, planned plugin(s): kubernetes,terraform", + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + got := makeTitleText(tc.app) + assert.Equal(t, tc.want, got) + }) + } +} diff --git a/tool/actions-plan-preview/testdata/comment-plugin-has-failed-app.txt b/tool/actions-plan-preview/testdata/comment-plugin-has-failed-app.txt new file mode 100644 index 0000000000..75ad24583e --- /dev/null +++ b/tool/actions-plan-preview/testdata/comment-plugin-has-failed-app.txt @@ -0,0 +1,32 @@ + +[![PLAN_PREVIEW](https://img.shields.io/static/v1?label=PipeCD&message=Plan_Preview&color=orange&style=flat)](https://pipecd.dev/docs/user-guide/plan-preview/) + +Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. + +## Plans + +### app: [app-name-1](app-url-1), env: env-1, planned plugin(s): kubernetes +Sync strategy: PIPELINE + Plugin(s): kubernetes + Summary: + - kubernetes(dt-1): 2 resources will be added, 1 resource will be deleted and 5 resources will be changed + Details: + - kubernetes(dt-1): +
+Details (Click me) +

+ +``` diff +details-1 +``` +

+
+ + +## NOTE + +**An error occurred while building plan-preview for the following applications** + +### app: [app-name-2](app-url-2), env: env-2, planned plugin(s): kubernetes-failed +Reason: wrong application configuration + diff --git a/tool/actions-plan-preview/testdata/comment-plugin-one-failure-app-unknown-plugin.txt b/tool/actions-plan-preview/testdata/comment-plugin-one-failure-app-unknown-plugin.txt new file mode 100644 index 0000000000..00bac32567 --- /dev/null +++ b/tool/actions-plan-preview/testdata/comment-plugin-one-failure-app-unknown-plugin.txt @@ -0,0 +1,12 @@ + +[![PLAN_PREVIEW](https://img.shields.io/static/v1?label=PipeCD&message=Plan_Preview&color=orange&style=flat)](https://pipecd.dev/docs/user-guide/plan-preview/) + +Ran plan-preview against head commit abc of this pull request. PipeCD detected `0` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. + +## NOTE + +**An error occurred while building plan-preview for the following applications** + +### app: [app-name-2](app-url-2), env: env-2, planned plugin(s): +Reason: wrong application configuration + diff --git a/tool/actions-plan-preview/testdata/comment-plugin-one-success-app-multiple-plugins.txt b/tool/actions-plan-preview/testdata/comment-plugin-one-success-app-multiple-plugins.txt new file mode 100644 index 0000000000..29848849d3 --- /dev/null +++ b/tool/actions-plan-preview/testdata/comment-plugin-one-success-app-multiple-plugins.txt @@ -0,0 +1,36 @@ + +[![PLAN_PREVIEW](https://img.shields.io/static/v1?label=PipeCD&message=Plan_Preview&color=success&style=flat)](https://pipecd.dev/docs/user-guide/plan-preview/) + +Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. + +## Plans + +### app: [app-name-1](app-url-1), env: env-1, planned plugin(s): kubernetes, terraform +Sync strategy: PIPELINE + Plugin(s): kubernetes, terraform, analysis + Summary: + - kubernetes(dt-1): 2 resources will be added, 1 resource will be deleted and 5 resources will be changed + - terraform(dt-2): 1 resource will be added, 2 resources will be deleted and 3 resources will be changed + Details: + - kubernetes(dt-1): +
+Details (Click me) +

+ +``` diff +details-1 +``` +

+
+ + - terraform(dt-2): +
+Details (Click me) +

+ +``` hcl +details-2 +``` +

+
+ diff --git a/tool/actions-plan-preview/testdata/comment-plugin-one-success-app.txt b/tool/actions-plan-preview/testdata/comment-plugin-one-success-app.txt new file mode 100644 index 0000000000..46ce9aee76 --- /dev/null +++ b/tool/actions-plan-preview/testdata/comment-plugin-one-success-app.txt @@ -0,0 +1,24 @@ + +[![PLAN_PREVIEW](https://img.shields.io/static/v1?label=PipeCD&message=Plan_Preview&color=success&style=flat)](https://pipecd.dev/docs/user-guide/plan-preview/) + +Ran plan-preview against head commit abc of this pull request. PipeCD detected `1` updated applications and here are their plan results. Once this pull request got merged their deployments will be triggered to run as these estimations. + +## Plans + +### app: [app-name-1](app-url-1), env: env-1, planned plugin(s): kubernetes +Sync strategy: QUICK_SYNC + Plugin(s): kubernetes + Summary: + - kubernetes(dt-1): 2 resources will be added, 1 resource will be deleted and 5 resources will be changed + Details: + - kubernetes(dt-1): +
+Details (Click me) +

+ +``` diff +details-1 +``` +

+
+