From 0026d3a38a63ed578a6871c95dbb02f036825388 Mon Sep 17 00:00:00 2001 From: Chmouel Boudjnah Date: Tue, 26 Sep 2023 13:18:03 +0200 Subject: [PATCH] Make status message as templates Status message was getting too complicated when managing with fmt.Sprintf and it was getting hard to maintain, changing this to use a more flexible go templates. And add tkn binary URL for download links in the message Signed-off-by: Chmouel Boudjnah --- pkg/formatting/starting.go | 32 +++++++++++++++ pkg/formatting/starting_test.go | 49 +++++++++++++++++++++++ pkg/formatting/templates/queuing.go.tmpl | 1 + pkg/formatting/templates/starting.go.tmpl | 5 +++ pkg/params/run.go | 7 +--- pkg/params/settings/config.go | 1 + pkg/pipelineascode/pipelineascode.go | 32 ++++++++++----- pkg/reconciler/reconciler.go | 20 ++++++--- 8 files changed, 124 insertions(+), 23 deletions(-) create mode 100644 pkg/formatting/starting.go create mode 100644 pkg/formatting/starting_test.go create mode 100644 pkg/formatting/templates/queuing.go.tmpl create mode 100644 pkg/formatting/templates/starting.go.tmpl diff --git a/pkg/formatting/starting.go b/pkg/formatting/starting.go new file mode 100644 index 000000000..a3181d988 --- /dev/null +++ b/pkg/formatting/starting.go @@ -0,0 +1,32 @@ +package formatting + +import ( + "bytes" + _ "embed" + "text/template" +) + +//go:embed templates/starting.go.tmpl +var StartingPipelineRunText string + +//go:embed templates/queuing.go.tmpl +var QueuingPipelineRunText string + +type MessageTemplate struct { + PipelineRunName string + Namespace string + ConsoleName string + ConsoleURL string + TknBinary string + TknBinaryURL string +} + +func (mt MessageTemplate) MakeTemplate(msg string) (string, error) { + outputBuffer := bytes.Buffer{} + t := template.Must(template.New("Message").Parse(msg)) + data := struct{ Mt MessageTemplate }{Mt: mt} + if err := t.Execute(&outputBuffer, data); err != nil { + return "", err + } + return outputBuffer.String(), nil +} diff --git a/pkg/formatting/starting_test.go b/pkg/formatting/starting_test.go new file mode 100644 index 000000000..923f78ef2 --- /dev/null +++ b/pkg/formatting/starting_test.go @@ -0,0 +1,49 @@ +package formatting + +import ( + "testing" +) + +func TestMessageTemplate_MakeTemplate(t *testing.T) { + mt := MessageTemplate{ + PipelineRunName: "test-pipeline", + Namespace: "test-namespace", + ConsoleName: "test-console", + ConsoleURL: "https://test-console-url.com", + TknBinary: "test-tkn", + TknBinaryURL: "https://test-tkn-url.com", + } + + tests := []struct { + name string + mt MessageTemplate + msg string + want string + wantErr bool + }{ + { + name: "Test MakeTemplate", + mt: mt, + msg: "Starting Pipelinerun {{.Mt.PipelineRunName}} in namespace {{.Mt.Namespace}}", + want: "Starting Pipelinerun test-pipeline in namespace test-namespace", + }, + { + name: "Error MakeTemplate", + mt: mt, + msg: "Starting Pipelinerun {{.Mt.PipelineRunName}} in namespace {{.FOOOBAR }}", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.mt.MakeTemplate(tt.msg) + if (err != nil) != tt.wantErr { + t.Errorf("MessageTemplate.MakeTemplate() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("MessageTemplate.MakeTemplate() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/formatting/templates/queuing.go.tmpl b/pkg/formatting/templates/queuing.go.tmpl new file mode 100644 index 000000000..7d2bd1ed7 --- /dev/null +++ b/pkg/formatting/templates/queuing.go.tmpl @@ -0,0 +1 @@ +PipelineRun {{ .Mt.PipelineRunName }} has been queued in namespace {{ .Mt.Namespace }}

\ No newline at end of file diff --git a/pkg/formatting/templates/starting.go.tmpl b/pkg/formatting/templates/starting.go.tmpl new file mode 100644 index 000000000..6e6fc73b0 --- /dev/null +++ b/pkg/formatting/templates/starting.go.tmpl @@ -0,0 +1,5 @@ +Starting Pipelinerun {{ .Mt.PipelineRunName }} in namespace {{ .Mt.Namespace }}
+You can monitor the execution using the [{{ .Mt.ConsoleName }}]({{ .Mt.ConsoleURL }}) PipelineRun viewer or through the command line by +using the [{{ .Mt.TknBinary }}]({{ .Mt.TknBinaryURL }}) CLI with the following command: +
+{{ .Mt.TknBinary }} pr logs -n {{ .Mt.Namespace }} {{ .Mt.PipelineRunName }} -f diff --git a/pkg/params/run.go b/pkg/params/run.go index b4d2aef00..7eb86566b 100644 --- a/pkg/params/run.go +++ b/pkg/params/run.go @@ -17,12 +17,7 @@ import ( ) const ( - PACConfigmapName = "pipelines-as-code" - StartingPipelineRunText = `Starting Pipelinerun %s in namespace - %s

You can monitor the execution using the [%s](%s) PipelineRun viewer or through the command line by using the following command: -
%s pr logs -n %s %s -f` - QueuingPipelineRunText = `PipelineRun %s has been queued in namespace - %s

` + PACConfigmapName = "pipelines-as-code" ) type Run struct { diff --git a/pkg/params/settings/config.go b/pkg/params/settings/config.go index 10ad76be5..b42603d6b 100644 --- a/pkg/params/settings/config.go +++ b/pkg/params/settings/config.go @@ -61,6 +61,7 @@ const ( var ( TknBinaryName = `tkn` + TknBinaryURL = `https://tekton.dev/docs/cli/#installation` hubCatalogNameRegex = regexp.MustCompile(`^catalog-(\d+)-`) ) diff --git a/pkg/pipelineascode/pipelineascode.go b/pkg/pipelineascode/pipelineascode.go index 31ca10026..65ea46b41 100644 --- a/pkg/pipelineascode/pipelineascode.go +++ b/pkg/pipelineascode/pipelineascode.go @@ -5,10 +5,15 @@ import ( "fmt" "sync" + tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "go.uber.org/zap" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/openshift-pipelines/pipelines-as-code/pkg/action" "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/keys" "github.com/openshift-pipelines/pipelines-as-code/pkg/customparams" "github.com/openshift-pipelines/pipelines-as-code/pkg/events" + "github.com/openshift-pipelines/pipelines-as-code/pkg/formatting" "github.com/openshift-pipelines/pipelines-as-code/pkg/kubeinteraction" "github.com/openshift-pipelines/pipelines-as-code/pkg/matcher" "github.com/openshift-pipelines/pipelines-as-code/pkg/params" @@ -17,9 +22,6 @@ import ( "github.com/openshift-pipelines/pipelines-as-code/pkg/params/settings" "github.com/openshift-pipelines/pipelines-as-code/pkg/provider" "github.com/openshift-pipelines/pipelines-as-code/pkg/secrets" - tektonv1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "go.uber.org/zap" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -168,14 +170,20 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi // Create status with the log url p.logger.Infof("pipelinerun %s has been created in namespace %s for SHA: %s Target Branch: %s", pr.GetName(), match.Repo.GetNamespace(), p.event.SHA, p.event.BaseBranch) + consoleURL := p.run.Clients.ConsoleUI.DetailURL(pr) - // Create status with the log url - msg := fmt.Sprintf(params.StartingPipelineRunText, - pr.GetName(), match.Repo.GetNamespace(), - p.run.Clients.ConsoleUI.GetName(), consoleURL, - settings.TknBinaryName, - pr.GetNamespace(), - pr.GetName()) + mt := formatting.MessageTemplate{ + PipelineRunName: pr.GetName(), + Namespace: match.Repo.GetNamespace(), + ConsoleName: p.run.Clients.ConsoleUI.GetName(), + ConsoleURL: consoleURL, + TknBinary: settings.TknBinaryName, + TknBinaryURL: settings.TknBinaryURL, + } + msg, err := mt.MakeTemplate(formatting.StartingPipelineRunText) + if err != nil { + return nil, fmt.Errorf("cannot create message template: %w", err) + } status := provider.StatusOpts{ Status: "in_progress", Conclusion: "pending", @@ -189,7 +197,9 @@ func (p *PacRun) startPR(ctx context.Context, match matcher.Match) (*tektonv1.Pi // if pipelineRun is in pending state then report status as queued if pr.Spec.Status == tektonv1.PipelineRunSpecStatusPending { status.Status = "queued" - status.Text = fmt.Sprintf(params.QueuingPipelineRunText, pr.GetName(), match.Repo.GetNamespace()) + if status.Text, err = mt.MakeTemplate(formatting.QueuingPipelineRunText); err != nil { + return nil, fmt.Errorf("cannot create message template: %w", err) + } } if err := p.vcx.CreateStatus(ctx, p.run.Clients.Tekton, p.event, p.run.Info.Pac, status); err != nil { diff --git a/pkg/reconciler/reconciler.go b/pkg/reconciler/reconciler.go index ee7c6ca13..525863582 100644 --- a/pkg/reconciler/reconciler.go +++ b/pkg/reconciler/reconciler.go @@ -18,6 +18,7 @@ import ( "github.com/openshift-pipelines/pipelines-as-code/pkg/apis/pipelinesascode/v1alpha1" "github.com/openshift-pipelines/pipelines-as-code/pkg/customparams" "github.com/openshift-pipelines/pipelines-as-code/pkg/events" + "github.com/openshift-pipelines/pipelines-as-code/pkg/formatting" pipelinesascode "github.com/openshift-pipelines/pipelines-as-code/pkg/generated/listers/pipelinesascode/v1alpha1" "github.com/openshift-pipelines/pipelines-as-code/pkg/kubeinteraction" "github.com/openshift-pipelines/pipelines-as-code/pkg/metrics" @@ -196,12 +197,19 @@ func (r *Reconciler) updatePipelineRunToInProgress(ctx context.Context, logger * } consoleURL := r.run.Clients.ConsoleUI.DetailURL(pr) - msg := fmt.Sprintf(params.StartingPipelineRunText, - pr.GetName(), repo.GetNamespace(), - r.run.Clients.ConsoleUI.GetName(), consoleURL, - settings.TknBinaryName, - pr.GetNamespace(), - pr.GetName()) + + mt := formatting.MessageTemplate{ + PipelineRunName: pr.GetName(), + Namespace: repo.GetNamespace(), + ConsoleName: r.run.Clients.ConsoleUI.GetName(), + ConsoleURL: consoleURL, + TknBinary: settings.TknBinaryName, + TknBinaryURL: settings.TknBinaryURL, + } + msg, err := mt.MakeTemplate(formatting.StartingPipelineRunText) + if err != nil { + return fmt.Errorf("cannot create message template: %w", err) + } status := provider.StatusOpts{ Status: "in_progress", Conclusion: "pending",