From 0c46be585460c61757f8b5bfc0daa893e02003f2 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Wed, 25 Dec 2019 18:30:54 +0900 Subject: [PATCH 01/10] Add testcase to verify HTML escaped output --- terraform/template_test.go | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/terraform/template_test.go b/terraform/template_test.go index bf7aefc..7b186ba 100644 --- a/terraform/template_test.go +++ b/terraform/template_test.go @@ -86,6 +86,27 @@ b
c
 
+`, + }, + { + template: "", + value: CommonTemplate{ + Title: "a", + Message: "b", + Result: `This is a "result".`, + Body: "d", + }, + resp: ` +a + +b + + + +
Details (Click me) + +
This is a "result".
+
`, }, { @@ -181,6 +202,24 @@ b c +`, + }, + { + template: "", + value: CommonTemplate{ + Title: "a", + Message: "b", + Result: `This is a "result".`, + Body: "d", + }, + resp: ` +a + +b + + + +This is a "result". `, }, { @@ -272,6 +311,27 @@ message
body
 
+`, + }, + { + template: DefaultPlanTemplate, + value: CommonTemplate{ + Title: "title", + Message: "message", + Result: "", + Body: `This is a "body".`, + }, + resp: ` +title + +message + + + +
Details (Click me) + +
This is a "body".
+
`, }, { @@ -491,6 +551,27 @@ message
body
 
+`, + }, + { + template: "", + value: CommonTemplate{ + Title: "title", + Message: "message", + Result: "", + Body: `This is a "body".`, + }, + resp: ` +title + +message + + + +
Details (Click me) + +
This is a "body".
+
`, }, { From 9dc94b1f998487833aba41196f251b6ee55436a4 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:06:25 +0900 Subject: [PATCH 02/10] Add UseRawOutput to CommonTemplate --- terraform/template.go | 11 ++++++----- terraform/template_test.go | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/terraform/template.go b/terraform/template.go index cd52f2c..27e6bae 100644 --- a/terraform/template.go +++ b/terraform/template.go @@ -101,11 +101,12 @@ type Template interface { // CommonTemplate represents template entities type CommonTemplate struct { - Title string - Message string - Result string - Body string - Link string + Title string + Message string + Result string + Body string + Link string + UseRawOutput bool } // DefaultTemplate is a default template for terraform commands diff --git a/terraform/template_test.go b/terraform/template_test.go index 7b186ba..97ce46c 100644 --- a/terraform/template_test.go +++ b/terraform/template_test.go @@ -624,7 +624,7 @@ func TestGetValue(t *testing.T) { template := testCase.template value := template.GetValue() if !reflect.DeepEqual(value, testCase.expected) { - t.Errorf("got %q but want %q", value, testCase.expected) + t.Errorf("got %#v but want %#v", value, testCase.expected) } } } From 8fc65c3ff4fc353edf1d97e6a1e0f7b801bd1b65 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:09:36 +0900 Subject: [PATCH 03/10] Add conditional branch by UseRawOutput --- terraform/template.go | 103 ++++++++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 34 deletions(-) diff --git a/terraform/template.go b/terraform/template.go index 27e6bae..c355791 100644 --- a/terraform/template.go +++ b/terraform/template.go @@ -2,7 +2,7 @@ package terraform import ( "bytes" - "html/template" + htmltemplate "html/template" ) const ( @@ -196,67 +196,93 @@ func NewApplyTemplate(template string) *ApplyTemplate { // Execute binds the execution result of terraform command into tepmlate func (t *DefaultTemplate) Execute() (resp string, err error) { - tpl, err := template.New("default").Parse(t.Template) - if err != nil { - return resp, err - } - var b bytes.Buffer - if err := tpl.Execute(&b, map[string]interface{}{ + data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, "Result": "", "Body": t.Result, "Link": t.Link, - }); err != nil { - return resp, err } + + var b bytes.Buffer + + if t.UseRawOutput { + // do nothing + } else { + tpl, err := htmltemplate.New("default").Parse(t.Template) + if err != nil { + return resp, err + } + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } + } + resp = b.String() return resp, err } // Execute binds the execution result of terraform fmt into tepmlate func (t *FmtTemplate) Execute() (resp string, err error) { - tpl, err := template.New("fmt").Parse(t.Template) - if err != nil { - return resp, err - } - var b bytes.Buffer - if err := tpl.Execute(&b, map[string]interface{}{ + data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, "Result": "", "Body": t.Result, "Link": t.Link, - }); err != nil { - return resp, err } + + var b bytes.Buffer + + if t.UseRawOutput { + // do nothing + } else { + tpl, err := htmltemplate.New("fmt").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } + } + resp = b.String() return resp, err } // Execute binds the execution result of terraform plan into tepmlate func (t *PlanTemplate) Execute() (resp string, err error) { - tpl, err := template.New("plan").Parse(t.Template) - if err != nil { - return resp, err - } - var b bytes.Buffer - if err := tpl.Execute(&b, map[string]interface{}{ + data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, "Result": t.Result, "Body": t.Body, "Link": t.Link, - }); err != nil { - return resp, err } + + var b bytes.Buffer + + if t.UseRawOutput { + // do nothing + } else { + tpl, err := htmltemplate.New("plan").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } + } + resp = b.String() return resp, err } // Execute binds the execution result of terraform plan into template func (t *DestroyWarningTemplate) Execute() (resp string, err error) { - tpl, err := template.New("destroy_warning").Parse(t.Template) + tpl, err := htmltemplate.New("destroy_warning").Parse(t.Template) if err != nil { return resp, err } @@ -276,20 +302,29 @@ func (t *DestroyWarningTemplate) Execute() (resp string, err error) { // Execute binds the execution result of terraform apply into tepmlate func (t *ApplyTemplate) Execute() (resp string, err error) { - tpl, err := template.New("apply").Parse(t.Template) - if err != nil { - return resp, err - } - var b bytes.Buffer - if err := tpl.Execute(&b, map[string]interface{}{ + data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, "Result": t.Result, "Body": t.Body, "Link": t.Link, - }); err != nil { - return resp, err } + + var b bytes.Buffer + + if t.UseRawOutput { + // do nothing + } else { + tpl, err := htmltemplate.New("apply").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } + } + resp = b.String() return resp, err } From 966795afd31a66c691e06daf3681e935fa7f8eb9 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:17:05 +0900 Subject: [PATCH 04/10] Generate output without HTML escape --- terraform/template.go | 36 +++++++++++-- terraform/template_test.go | 107 +++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 4 deletions(-) diff --git a/terraform/template.go b/terraform/template.go index c355791..b542f50 100644 --- a/terraform/template.go +++ b/terraform/template.go @@ -3,6 +3,7 @@ package terraform import ( "bytes" htmltemplate "html/template" + texttemplate "text/template" ) const ( @@ -207,7 +208,13 @@ func (t *DefaultTemplate) Execute() (resp string, err error) { var b bytes.Buffer if t.UseRawOutput { - // do nothing + tpl, err := texttemplate.New("default").Parse(t.Template) + if err != nil { + return resp, err + } + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } } else { tpl, err := htmltemplate.New("default").Parse(t.Template) if err != nil { @@ -235,7 +242,14 @@ func (t *FmtTemplate) Execute() (resp string, err error) { var b bytes.Buffer if t.UseRawOutput { - // do nothing + tpl, err := texttemplate.New("fmt").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } } else { tpl, err := htmltemplate.New("fmt").Parse(t.Template) if err != nil { @@ -264,7 +278,14 @@ func (t *PlanTemplate) Execute() (resp string, err error) { var b bytes.Buffer if t.UseRawOutput { - // do nothing + tpl, err := texttemplate.New("plan").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } } else { tpl, err := htmltemplate.New("plan").Parse(t.Template) if err != nil { @@ -313,7 +334,14 @@ func (t *ApplyTemplate) Execute() (resp string, err error) { var b bytes.Buffer if t.UseRawOutput { - // do nothing + tpl, err := texttemplate.New("apply").Parse(t.Template) + if err != nil { + return resp, err + } + + if err := tpl.Execute(&b, data); err != nil { + return resp, err + } } else { tpl, err := htmltemplate.New("apply").Parse(t.Template) if err != nil { diff --git a/terraform/template_test.go b/terraform/template_test.go index 97ce46c..fd98d8f 100644 --- a/terraform/template_test.go +++ b/terraform/template_test.go @@ -107,6 +107,50 @@ b
This is a "result".
 
+`, + }, + { + template: "", + value: CommonTemplate{ + Title: "a", + Message: "b", + Result: `This is a "result".`, + Body: "d", + UseRawOutput: true, + }, + resp: ` +a + +b + + + +
Details (Click me) + +
This is a "result".
+
+`, + }, + { + template: "", + value: CommonTemplate{ + Title: "a", + Message: "b", + Result: `This is a "result".`, + Body: "d", + UseRawOutput: true, + }, + resp: ` +a + +b + + + +
Details (Click me) + +
This is a "result".
+
`, }, { @@ -220,6 +264,25 @@ b This is a "result". +`, + }, + { + template: "", + value: CommonTemplate{ + Title: "a", + Message: "b", + Result: `This is a "result".`, + Body: "d", + UseRawOutput: true, + }, + resp: ` +a + +b + + + +This is a "result". `, }, { @@ -332,6 +395,28 @@ message
This is a "body".
 
+`, + }, + { + template: DefaultPlanTemplate, + value: CommonTemplate{ + Title: "title", + Message: "message", + Result: "", + Body: `This is a "body".`, + UseRawOutput: true, + }, + resp: ` +title + +message + + + +
Details (Click me) + +
This is a "body".
+
`, }, { @@ -572,6 +657,28 @@ message
This is a "body".
 
+`, + }, + { + template: "", + value: CommonTemplate{ + Title: "title", + Message: "message", + Result: "", + Body: `This is a "body".`, + UseRawOutput: true, + }, + resp: ` +title + +message + + + +
Details (Click me) + +
This is a "body".
+
`, }, { From 32abc03cc35cbc6085d9d965cb5991af02c90cda Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:25:37 +0900 Subject: [PATCH 05/10] Refeactor template logic --- terraform/template.go | 126 ++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 86 deletions(-) diff --git a/terraform/template.go b/terraform/template.go index b542f50..9eaba92 100644 --- a/terraform/template.go +++ b/terraform/template.go @@ -195,42 +195,32 @@ func NewApplyTemplate(template string) *ApplyTemplate { } } -// Execute binds the execution result of terraform command into tepmlate -func (t *DefaultTemplate) Execute() (resp string, err error) { - data := map[string]interface{}{ - "Title": t.Title, - "Message": t.Message, - "Result": "", - "Body": t.Result, - "Link": t.Link, - } - +func generateOutput(kind, template string, data map[string]interface{}, useRawOutput bool) (string, error) { var b bytes.Buffer - if t.UseRawOutput { - tpl, err := texttemplate.New("default").Parse(t.Template) + if useRawOutput { + tpl, err := texttemplate.New(kind).Parse(template) if err != nil { - return resp, err + return "", err } if err := tpl.Execute(&b, data); err != nil { - return resp, err + return "", err } } else { - tpl, err := htmltemplate.New("default").Parse(t.Template) + tpl, err := htmltemplate.New(kind).Parse(template) if err != nil { - return resp, err + return "", err } if err := tpl.Execute(&b, data); err != nil { - return resp, err + return "", err } } - resp = b.String() - return resp, err + return b.String(), nil } -// Execute binds the execution result of terraform fmt into tepmlate -func (t *FmtTemplate) Execute() (resp string, err error) { +// Execute binds the execution result of terraform command into tepmlate +func (t *DefaultTemplate) Execute() (string, error) { data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, @@ -239,34 +229,34 @@ func (t *FmtTemplate) Execute() (resp string, err error) { "Link": t.Link, } - var b bytes.Buffer + resp, err := generateOutput("default", t.Template, data, t.UseRawOutput) + if err != nil { + return "", err + } - if t.UseRawOutput { - tpl, err := texttemplate.New("fmt").Parse(t.Template) - if err != nil { - return resp, err - } + return resp, nil +} - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } - } else { - tpl, err := htmltemplate.New("fmt").Parse(t.Template) - if err != nil { - return resp, err - } +// Execute binds the execution result of terraform fmt into tepmlate +func (t *FmtTemplate) Execute() (string, error) { + data := map[string]interface{}{ + "Title": t.Title, + "Message": t.Message, + "Result": "", + "Body": t.Result, + "Link": t.Link, + } - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } + resp, err := generateOutput("fmt", t.Template, data, t.UseRawOutput) + if err != nil { + return "", err } - resp = b.String() - return resp, err + return resp, nil } // Execute binds the execution result of terraform plan into tepmlate -func (t *PlanTemplate) Execute() (resp string, err error) { +func (t *PlanTemplate) Execute() (string, error) { data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, @@ -275,30 +265,12 @@ func (t *PlanTemplate) Execute() (resp string, err error) { "Link": t.Link, } - var b bytes.Buffer - - if t.UseRawOutput { - tpl, err := texttemplate.New("plan").Parse(t.Template) - if err != nil { - return resp, err - } - - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } - } else { - tpl, err := htmltemplate.New("plan").Parse(t.Template) - if err != nil { - return resp, err - } - - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } + resp, err := generateOutput("plan", t.Template, data, t.UseRawOutput) + if err != nil { + return "", err } - resp = b.String() - return resp, err + return resp, nil } // Execute binds the execution result of terraform plan into template @@ -322,7 +294,7 @@ func (t *DestroyWarningTemplate) Execute() (resp string, err error) { } // Execute binds the execution result of terraform apply into tepmlate -func (t *ApplyTemplate) Execute() (resp string, err error) { +func (t *ApplyTemplate) Execute() (string, error) { data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, @@ -331,30 +303,12 @@ func (t *ApplyTemplate) Execute() (resp string, err error) { "Link": t.Link, } - var b bytes.Buffer - - if t.UseRawOutput { - tpl, err := texttemplate.New("apply").Parse(t.Template) - if err != nil { - return resp, err - } - - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } - } else { - tpl, err := htmltemplate.New("apply").Parse(t.Template) - if err != nil { - return resp, err - } - - if err := tpl.Execute(&b, data); err != nil { - return resp, err - } + resp, err := generateOutput("apply", t.Template, data, t.UseRawOutput) + if err != nil { + return "", err } - resp = b.String() - return resp, err + return resp, nil } // SetValue sets template entities to CommonTemplate From 58cc54e063eec886435b008a35b1dcb0e1016dc9 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:30:49 +0900 Subject: [PATCH 06/10] Support UseRawOutput in destroy warning --- terraform/template.go | 20 +++++++++----------- terraform/template_test.go | 22 ++++++++++++++++++++-- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/terraform/template.go b/terraform/template.go index 9eaba92..490b946 100644 --- a/terraform/template.go +++ b/terraform/template.go @@ -274,23 +274,21 @@ func (t *PlanTemplate) Execute() (string, error) { } // Execute binds the execution result of terraform plan into template -func (t *DestroyWarningTemplate) Execute() (resp string, err error) { - tpl, err := htmltemplate.New("destroy_warning").Parse(t.Template) - if err != nil { - return resp, err - } - var b bytes.Buffer - if err := tpl.Execute(&b, map[string]interface{}{ +func (t *DestroyWarningTemplate) Execute() (string, error) { + data := map[string]interface{}{ "Title": t.Title, "Message": t.Message, "Result": t.Result, "Body": t.Body, "Link": t.Link, - }); err != nil { - return resp, err } - resp = b.String() - return resp, err + + resp, err := generateOutput("destroy_warning", t.Template, data, t.UseRawOutput) + if err != nil { + return "", err + } + + return resp, nil } // Execute binds the execution result of terraform apply into tepmlate diff --git a/terraform/template_test.go b/terraform/template_test.go index fd98d8f..c947061 100644 --- a/terraform/template_test.go +++ b/terraform/template_test.go @@ -485,7 +485,7 @@ This plan contains resource delete operation. Please check the plan result very template: DefaultDestroyWarningTemplate, value: CommonTemplate{ Title: "title", - Result: "result", + Result: `This is a "result".`, }, resp: ` title @@ -493,7 +493,25 @@ title This plan contains resource delete operation. Please check the plan result very carefully! -
result
+
This is a "result".
+
+ +`, + }, + { + template: DefaultDestroyWarningTemplate, + value: CommonTemplate{ + Title: "title", + Result: `This is a "result".`, + UseRawOutput: true, + }, + resp: ` +title + +This plan contains resource delete operation. Please check the plan result very carefully! + + +
This is a "result".
 
`, From 9f7da2634dd56a9f7eb8d575f4a2a8dbcf6438ce Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:41:31 +0900 Subject: [PATCH 07/10] Add use_raw_output config --- config/config.go | 9 +++++---- config/config_test.go | 2 ++ example-use-raw-output.tfnotify.yaml | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 example-use-raw-output.tfnotify.yaml diff --git a/config/config.go b/config/config.go index dbe10bb..b8fe115 100644 --- a/config/config.go +++ b/config/config.go @@ -62,10 +62,11 @@ type TypetalkNotifier struct { // Terraform represents terraform configurations type Terraform struct { - Default Default `yaml:"default"` - Fmt Fmt `yaml:"fmt"` - Plan Plan `yaml:"plan"` - Apply Apply `yaml:"apply"` + Default Default `yaml:"default"` + Fmt Fmt `yaml:"fmt"` + Plan Plan `yaml:"plan"` + Apply Apply `yaml:"apply"` + UseRawOutput bool `yaml:"use_raw_output,omitempty"` } // Default is a default setting for terraform commands diff --git a/config/config_test.go b/config/config_test.go index 880fc5a..5d37c8a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -56,6 +56,7 @@ func TestLoadFile(t *testing.T) { Apply: Apply{ Template: "", }, + UseRawOutput: false, }, path: "../example.tfnotify.yaml", }, @@ -99,6 +100,7 @@ func TestLoadFile(t *testing.T) { Apply: Apply{ Template: "", }, + UseRawOutput: false, }, path: "../example-with-destroy.tfnotify.yaml", }, diff --git a/example-use-raw-output.tfnotify.yaml b/example-use-raw-output.tfnotify.yaml new file mode 100644 index 0000000..bf0ade8 --- /dev/null +++ b/example-use-raw-output.tfnotify.yaml @@ -0,0 +1,21 @@ +ci: circleci +notifier: + github: + token: $GITHUB_TOKEN + repository: + owner: "mercari" + name: "tfnotify" +terraform: + use_raw_output: true + plan: + template: | + {{ .Title }} + {{ .Message }} + {{if .Result}} +
{{ .Result }}
+      
+ {{end}} +
Details (Click me) + +
{{ .Body }}
+      
From 129fbf3dca8893a6cc3e805f8100aa3a27e5b7e7 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 12:50:43 +0900 Subject: [PATCH 08/10] Pass UseRawOutput to GitHub client --- main.go | 1 + notifier/github/client.go | 17 +++++++++-------- notifier/github/notify.go | 22 ++++++++++++---------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/main.go b/main.go index 50adcbf..126bfeb 100644 --- a/main.go +++ b/main.go @@ -105,6 +105,7 @@ func (t *tfnotify) Run() error { }, CI: ci.URL, Parser: t.parser, + UseRawOutput: t.config.Terraform.UseRawOutput, Template: t.template, DestroyWarningTemplate: t.destroyWarningTemplate, WarnDestroy: t.warnDestroy, diff --git a/notifier/github/client.go b/notifier/github/client.go index 42b1fee..2d4586b 100644 --- a/notifier/github/client.go +++ b/notifier/github/client.go @@ -34,14 +34,15 @@ type Client struct { // Config is a configuration for GitHub client type Config struct { - Token string - BaseURL string - Owner string - Repo string - PR PullRequest - CI string - Parser terraform.Parser - WarnDestroy bool + Token string + BaseURL string + Owner string + Repo string + PR PullRequest + CI string + Parser terraform.Parser + UseRawOutput bool + WarnDestroy bool // Template is used for all Terraform command output Template terraform.Template // DestroyWarningTemplate is used only for additional warning diff --git a/notifier/github/notify.go b/notifier/github/notify.go index fa60be1..7a63064 100644 --- a/notifier/github/notify.go +++ b/notifier/github/notify.go @@ -33,11 +33,12 @@ func (g *NotifyService) Notify(body string) (exit int, err error) { } template.SetValue(terraform.CommonTemplate{ - Title: cfg.PR.Title, - Message: cfg.PR.Message, - Result: result.Result, - Body: body, - Link: cfg.CI, + Title: cfg.PR.Title, + Message: cfg.PR.Message, + Result: result.Result, + Body: body, + Link: cfg.CI, + UseRawOutput: cfg.UseRawOutput, }) body, err = template.Execute() if err != nil { @@ -70,11 +71,12 @@ func (g *NotifyService) notifyDestoryWarning(body string, result terraform.Parse cfg := g.client.Config destroyWarningTemplate := g.client.Config.DestroyWarningTemplate destroyWarningTemplate.SetValue(terraform.CommonTemplate{ - Title: cfg.PR.DestroyWarningTitle, - Message: cfg.PR.DestroyWarningMessage, - Result: result.Result, - Body: body, - Link: cfg.CI, + Title: cfg.PR.DestroyWarningTitle, + Message: cfg.PR.DestroyWarningMessage, + Result: result.Result, + Body: body, + Link: cfg.CI, + UseRawOutput: cfg.UseRawOutput, }) body, err := destroyWarningTemplate.Execute() if err != nil { From 6c76f26e5f8857f04249d6c2abec2936943a90f8 Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Thu, 26 Dec 2019 13:19:53 +0900 Subject: [PATCH 09/10] Write about use_raw_output in README --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index e297e4f..4177735 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,35 @@ terraform: # ... ``` +Sometimes you may want not to HTML-escape Terraform command outputs. +For example, when you use use code block to print command output, it's better to use raw characters instead of character references (e.g. `-/+` -> `-/+`, `"` -> `"`). + +You can disable HTML escape by adding `use_raw_output: true` configuration. +With this configuration, Terraform doesn't HTML-escape any Terraform output. + +~~~yaml +--- +# ... +terraform: + use_raw_output: true + # ... + plan: + template: | + {{ .Title }} [CI link]( {{ .Link }} ) + {{ .Message }} + {{if .Result}} + ``` + {{ .Result }} + ``` + {{end}} +
Details (Click me) + + ``` + {{ .Body }} + ``` + # ... +~~~ +
From 1cbe16e465a3313ee0d5ec4a50afe7ae0e1183bf Mon Sep 17 00:00:00 2001 From: Daisuke Fujita Date: Mon, 6 Jan 2020 12:02:59 +0900 Subject: [PATCH 10/10] Update README.md Co-Authored-By: Ryuzo Yamamoto --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4177735..3442383 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ terraform: ``` Sometimes you may want not to HTML-escape Terraform command outputs. -For example, when you use use code block to print command output, it's better to use raw characters instead of character references (e.g. `-/+` -> `-/+`, `"` -> `"`). +For example, when you use code block to print command output, it's better to use raw characters instead of character references (e.g. `-/+` -> `-/+`, `"` -> `"`). You can disable HTML escape by adding `use_raw_output: true` configuration. With this configuration, Terraform doesn't HTML-escape any Terraform output.