diff --git a/server/controllers/events/testdata/test-repos/automerge/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/automerge/exp-output-autoplan.txt index 4f8bbe1fa0..c32ed6dfdc 100644 --- a/server/controllers/events/testdata/test-repos/automerge/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/automerge/exp-output-autoplan.txt @@ -49,6 +49,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. * `atlantis plan -d dir2` --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-autoplan.txt index 6d3aa862ab..7f0f5f45a8 100644 --- a/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-autoplan.txt @@ -69,6 +69,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-plan-again.txt b/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-plan-again.txt index ce5547f08a..c9a7d87124 100644 --- a/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-plan-again.txt +++ b/server/controllers/events/testdata/test-repos/import-multiple-project/exp-output-plan-again.txt @@ -53,6 +53,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 1 with changes, 1 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/modules-yaml/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/modules-yaml/exp-output-autoplan.txt index 25fe0e6121..1e55d623b5 100644 --- a/server/controllers/events/testdata/test-repos/modules-yaml/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/modules-yaml/exp-output-autoplan.txt @@ -63,6 +63,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-apply.txt b/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-apply.txt index 34121591c1..eb6bda8987 100644 --- a/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-apply.txt +++ b/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-apply.txt @@ -19,4 +19,7 @@ workspace = "default" ### 2. dir: `dir2` workspace: `default` **Apply Failed**: All policies must pass for project before running apply. ---- \ No newline at end of file +--- +### Apply Summary + +2 projects, 1 successful, 1 failed, 0 errored \ No newline at end of file diff --git a/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt index 55d2149939..098c4eba93 100644 --- a/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/policy-checks-multi-projects/exp-output-autoplan.txt @@ -63,6 +63,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-apply.txt b/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-apply.txt index 8490f306d7..a136ff9691 100644 --- a/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-apply.txt +++ b/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-apply.txt @@ -20,4 +20,7 @@ null_resource.staging[0]: Creation complete after *s [id=*******************] Apply complete! Resources: 1 added, 0 changed, 0 destroyed. ``` ---- \ No newline at end of file +--- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored \ No newline at end of file diff --git a/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-autoplan.txt index 4f48c365d6..29f5f76dae 100644 --- a/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/repo-config-file/exp-output-autoplan.txt @@ -49,6 +49,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. * `atlantis plan -d infrastructure/production` --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/server-side-cfg/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/server-side-cfg/exp-output-autoplan.txt index 615a3f4c61..ad9591b8ae 100644 --- a/server/controllers/events/testdata/test-repos/server-side-cfg/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/server-side-cfg/exp-output-autoplan.txt @@ -71,6 +71,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-apply-all.txt b/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-apply-all.txt index 711bf571ce..61eac2271a 100644 --- a/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-apply-all.txt +++ b/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-apply-all.txt @@ -38,4 +38,7 @@ postapply ---- \ No newline at end of file +--- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored \ No newline at end of file diff --git a/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-autoplan.txt index 88eda9d431..dcbb45bf78 100644 --- a/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/simple-yaml/exp-output-autoplan.txt @@ -70,6 +70,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/simple/exp-output-apply-var-all.txt b/server/controllers/events/testdata/test-repos/simple/exp-output-apply-var-all.txt index bd6526fa8c..2977099b55 100644 --- a/server/controllers/events/testdata/test-repos/simple/exp-output-apply-var-all.txt +++ b/server/controllers/events/testdata/test-repos/simple/exp-output-apply-var-all.txt @@ -46,4 +46,7 @@ workspace = "new_workspace" ---- \ No newline at end of file +--- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored \ No newline at end of file diff --git a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-autoplan.txt index df46d869e6..49c4dc2673 100644 --- a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-autoplan.txt @@ -69,6 +69,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan-again.txt b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan-again.txt index df46d869e6..49c4dc2673 100644 --- a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan-again.txt +++ b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan-again.txt @@ -69,6 +69,10 @@ Plan: 1 to add, 0 to change, 0 to destroy. Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan.txt b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan.txt index 2766ea44de..fb3cfdbbd7 100644 --- a/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan.txt +++ b/server/controllers/events/testdata/test-repos/state-rm-multiple-project/exp-output-plan.txt @@ -37,6 +37,10 @@ and found no differences, so no changes are needed. * `atlantis plan -d dir2` --- +### Plan Summary + +2 projects, 0 with changes, 2 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/tfvars-yaml/exp-output-autoplan.txt b/server/controllers/events/testdata/test-repos/tfvars-yaml/exp-output-autoplan.txt index d8a084bd85..82ce193d9f 100644 --- a/server/controllers/events/testdata/test-repos/tfvars-yaml/exp-output-autoplan.txt +++ b/server/controllers/events/testdata/test-repos/tfvars-yaml/exp-output-autoplan.txt @@ -67,6 +67,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-production.txt b/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-production.txt index 73d66792e4..cd4e8e0b95 100644 --- a/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-production.txt +++ b/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-production.txt @@ -63,6 +63,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-staging.txt b/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-staging.txt index 73d66792e4..cd4e8e0b95 100644 --- a/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-staging.txt +++ b/server/controllers/events/testdata/test-repos/workspace-parallel-yaml/exp-output-autoplan-staging.txt @@ -63,6 +63,10 @@ Changes to Outputs: Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * `atlantis apply` * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: diff --git a/server/events/apply_command_runner_test.go b/server/events/apply_command_runner_test.go index 27b1efa4fe..838ca3e299 100644 --- a/server/events/apply_command_runner_test.go +++ b/server/events/apply_command_runner_test.go @@ -258,7 +258,7 @@ func TestApplyCommandRunner_ExecutionOrder(t *testing.T) { }, ExpComment: "Ran Apply for 2 projects:\n\n" + "1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n\n### 1. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### " + - "2. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---", + "2. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---\n### Apply Summary\n\n2 projects, 1 successful, 0 failed, 1 errored", }, { Description: "When first apply fails, the second not will run", @@ -343,7 +343,7 @@ func TestApplyCommandRunner_ExecutionOrder(t *testing.T) { }, ExpComment: "Ran Apply for 2 projects:\n\n" + "1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n\n### 1. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### " + - "2. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---", + "2. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---\n### Apply Summary\n\n2 projects, 1 successful, 0 failed, 1 errored", }, { Description: "When one out of two fails, the following two will not run", @@ -398,7 +398,7 @@ func TestApplyCommandRunner_ExecutionOrder(t *testing.T) { "1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n\n### 1. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### " + "2. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### " + "3. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---\n### " + - "4. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---", + "4. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### Apply Summary\n\n4 projects, 3 successful, 0 failed, 1 errored", }, { Description: "Don't block when parallel is not set", @@ -430,7 +430,7 @@ func TestApplyCommandRunner_ExecutionOrder(t *testing.T) { }, ExpComment: "Ran Apply for 2 projects:\n\n" + "1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n\n### 1. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---\n### " + - "2. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---", + "2. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### Apply Summary\n\n2 projects, 1 successful, 0 failed, 1 errored", }, { Description: "Don't block when abortOnExcecutionOrderFail is not set", @@ -460,7 +460,7 @@ func TestApplyCommandRunner_ExecutionOrder(t *testing.T) { }, ExpComment: "Ran Apply for 2 projects:\n\n" + "1. dir: `` workspace: ``\n1. dir: `` workspace: ``\n\n### 1. dir: `` workspace: ``\n**Apply Error**\n```\nshabang\n```\n\n---\n### " + - "2. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---", + "2. dir: `` workspace: ``\n```diff\nGreat success!\n```\n\n---\n### Apply Summary\n\n2 projects, 1 successful, 0 failed, 1 errored", }, } diff --git a/server/events/markdown_renderer.go b/server/events/markdown_renderer.go index 17328852d3..74a72c6719 100644 --- a/server/events/markdown_renderer.go +++ b/server/events/markdown_renderer.go @@ -93,6 +93,22 @@ type resultData struct { commonData } +type planResultData struct { + Results []projectResultTmplData + commonData + NumPlansWithChanges int + NumPlansWithNoChanges int + NumPlanFailures int +} + +type applyResultData struct { + Results []projectResultTmplData + commonData + NumApplySuccesses int + NumApplyFailures int + NumApplyErrors int +} + type planSuccessData struct { models.PlanSuccess PlanSummary string @@ -187,6 +203,11 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, numPolicyCheckSuccesses := 0 numPolicyApprovalSuccesses := 0 numVersionSuccesses := 0 + numPlansWithChanges := 0 + numPlansWithNoChanges := 0 + numApplySuccesses := 0 + numApplyFailures := 0 + numApplyErrors := 0 templates := m.markdownTemplates @@ -213,6 +234,11 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, resultData.Rendered = m.renderTemplateTrimSpace(templates.Lookup("planSuccessUnwrapped"), data) } resultData.NoChanges = result.PlanSuccess.NoChanges() + if result.PlanSuccess.NoChanges() { + numPlansWithNoChanges++ + } else { + numPlansWithChanges++ + } numPlanSuccesses++ } else if result.PolicyCheckResults != nil && common.Command == policyCheckCommandTitle { policyCheckResults := policyCheckResultsData{ @@ -255,6 +281,7 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, } else { resultData.Rendered = m.renderTemplateTrimSpace(templates.Lookup("applyUnwrappedSuccess"), struct{ Output string }{output}) } + numApplySuccesses++ } else if result.VersionSuccess != "" { output := strings.TrimSpace(result.VersionSuccess) if m.shouldUseWrappedTmpl(vcsHost, output) { @@ -289,8 +316,14 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, tmpl = templates.Lookup("wrappedErr") } resultData.Rendered = m.renderTemplateTrimSpace(tmpl, errData{result.Error.Error(), resultData.Rendered, common}) + if common.Command == applyCommandTitle { + numApplyErrors++ + } } else if result.Failure != "" { resultData.Rendered = m.renderTemplateTrimSpace(templates.Lookup("failure"), failureData{result.Failure, resultData.Rendered, common}) + if common.Command == applyCommandTitle { + numApplyFailures++ + } } resultsTmplData = append(resultsTmplData, resultData) } @@ -324,7 +357,7 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, tmpl = templates.Lookup("multiProjectPlan") case common.Command == policyCheckCommandTitle: if numPolicyCheckSuccesses == len(results) { - tmpl = templates.Lookup("multiProjectPlan") + tmpl = templates.Lookup("multiProjectPolicy") } else { tmpl = templates.Lookup("multiProjectPolicyUnsuccessful") } @@ -350,6 +383,14 @@ func (m *MarkdownRenderer) renderProjectResults(results []command.ProjectResult, default: return fmt.Sprintf("no template matched–this is a bug: command=%s", common.Command) } + + switch { + case common.Command == planCommandTitle: + numPlanFailures := len(results) - numPlanSuccesses + return m.renderTemplateTrimSpace(tmpl, planResultData{resultsTmplData, common, numPlansWithChanges, numPlansWithNoChanges, numPlanFailures}) + case common.Command == applyCommandTitle: + return m.renderTemplateTrimSpace(tmpl, applyResultData{resultsTmplData, common, numApplySuccesses, numApplyFailures, numApplyErrors}) + } return m.renderTemplateTrimSpace(tmpl, resultData{resultsTmplData, common}) } diff --git a/server/events/markdown_renderer_test.go b/server/events/markdown_renderer_test.go index 1b048b044d..eebd1a8b87 100644 --- a/server/events/markdown_renderer_test.go +++ b/server/events/markdown_renderer_test.go @@ -26,6 +26,11 @@ import ( . "github.com/runatlantis/atlantis/testing" ) +// Strip Carriage Returns, leading and trailing spaces and replace 'dollar' with 'backtick' in the string +func normalize(s string) string { + return strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(s, "$", "`"), "\r", "")) +} + func TestRenderErr(t *testing.T) { err := errors.New("err") cases := []struct { @@ -63,9 +68,9 @@ func TestRenderErr(t *testing.T) { t.Run(fmt.Sprintf("%s_%t", c.Description, verbose), func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, models.Github) if !verbose { - Equals(t, strings.TrimSpace(c.Expected), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, c.Expected+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected)+"\n\n
Log\n

\n\n```\nlog```\n

", normalize(s)) } }) } @@ -108,9 +113,9 @@ func TestRenderFailure(t *testing.T) { t.Run(fmt.Sprintf("%s_%t", c.Description, verbose), func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, models.Github) if !verbose { - Equals(t, strings.TrimSpace(c.Expected), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, c.Expected+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -124,7 +129,7 @@ func TestRenderErrAndFailure(t *testing.T) { Failure: "failure", } s := r.Render(res, command.Plan, "", "", false, models.Github) - Equals(t, "**Plan Error**\n```\nerror\n```", s) + Equals(t, "**Plan Error**\n```\nerror\n```", normalize(s)) } func TestRenderProjectResults(t *testing.T) { @@ -424,7 +429,8 @@ $$$ :put_litter_in_its_place: A plan file was discarded. Re-plan would be required before applying. * :repeat: To **plan** this project again, comment: - * $atlantis plan -d path -w workspace$`, + * $atlantis plan -d path -w workspace$ +`, }, { "single successful state rm", @@ -470,7 +476,8 @@ $$$ $$$diff success -$$$`, +$$$ +`, }, { "single successful apply with project name", @@ -489,7 +496,8 @@ $$$`, $$$diff success -$$$`, +$$$ +`, }, { "multiple successful plans", @@ -548,6 +556,10 @@ $$$ * $atlantis plan -d path2 -w workspace$ --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -667,6 +679,9 @@ success2 $$$ --- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored `, }, { @@ -686,7 +701,8 @@ $$$ **Plan Error** $$$ error -$$$`, +$$$ +`, }, { "single failed plan", @@ -702,7 +718,8 @@ $$$`, models.Github, `Ran Plan for dir: $path$ workspace: $workspace$ -**Plan Failed**: failure`, +**Plan Failed**: failure +`, }, { "successful, failed, and errored plan", @@ -761,6 +778,10 @@ error $$$ --- +### Plan Summary + +3 projects, 1 with changes, 0 with no changes, 2 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -911,6 +932,9 @@ error $$$ --- +### Apply Summary + +3 projects, 1 successful, 1 failed, 1 errored `, }, { @@ -958,6 +982,9 @@ error $$$ --- +### Apply Summary + +3 projects, 1 successful, 1 failed, 1 errored `, }, } @@ -971,11 +998,10 @@ $$$ for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, c.SubCommand, "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -1094,6 +1120,7 @@ $$$ * :repeat: To **plan** this project again, comment: * $atlantis plan -d path -w workspace$ +--- ### 2. project: $projectname$ dir: $path2$ workspace: $workspace$ $$$diff terraform-output2 @@ -1105,6 +1132,10 @@ $$$ * :repeat: To **plan** this project again, comment: * $atlantis plan -d path2 -w workspace$ +--- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed `, }, } @@ -1127,11 +1158,10 @@ $$$ for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -1244,6 +1274,7 @@ $$$ * :repeat: To **plan** this project again, comment: * $atlantis plan -d path -w workspace$ +--- ### 2. project: $projectname$ dir: $path2$ workspace: $workspace$ $$$diff terraform-output2 @@ -1253,6 +1284,10 @@ $$$ * :repeat: To **plan** this project again, comment: * $atlantis plan -d path2 -w workspace$ +--- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed `, }, } @@ -1276,11 +1311,10 @@ $$$ for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -1342,8 +1376,7 @@ $$$ * :repeat: To re-run policies **plan** this project again by commenting: * $atlantis plan -d path -w workspace$` - expWithBackticks := strings.Replace(exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) + Equals(t, normalize(exp), normalize(rendered)) } // Test that if folding is disabled that it's not used. @@ -1480,9 +1513,7 @@ $$$ ` + c.Output + ` $$$` } - - expWithBackticks := strings.Replace(exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) + Equals(t, normalize(exp), normalize(rendered)) }) } } @@ -1656,8 +1687,7 @@ $$$` } } - expWithBackticks := strings.Replace(exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) + Equals(t, normalize(exp), normalize(rendered)) }) } } @@ -1714,9 +1744,12 @@ $$$ ----` - expWithBackticks := strings.Replace(exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) +--- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored +` + Equals(t, normalize(exp), normalize(rendered)) } func TestRenderProjectResults_MultiProjectPlanWrapped(t *testing.T) { @@ -1793,12 +1826,16 @@ $$$ Plan: 1 to add, 0 to change, 0 to destroy. --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: - * $atlantis unlock$` - expWithBackticks := strings.Replace(exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) + * $atlantis unlock$ +` + Equals(t, normalize(exp), normalize(rendered)) } // Test rendering when there was an error in one of the plans and we deleted @@ -1851,7 +1888,11 @@ func TestRenderProjectResults_PlansDeleted(t *testing.T) { ### 2. dir: $.$ workspace: $production$ **Plan Failed**: failure ----`, +--- +### Plan Summary + +2 projects, 0 with changes, 0 with no changes, 2 failed +`, }, "one failure, one success": { cr: command.Result{ @@ -1890,7 +1931,11 @@ $$$ This plan was not saved because one or more projects failed and automerge requires all plans pass. ----`, +--- +### Plan Summary + +2 projects, 1 with changes, 0 with no changes, 1 failed +`, }, } @@ -1908,8 +1953,7 @@ This plan was not saved because one or more projects failed and automerge requir false, // hideUnchangedPlanComments ) rendered := mr.Render(c.cr, command.Plan, "", "log", false, models.Github) - expWithBackticks := strings.Replace(c.exp, "$", "`", -1) - Equals(t, expWithBackticks, rendered) + Equals(t, normalize(c.exp), normalize(rendered)) }) } } @@ -2051,7 +2095,8 @@ $$$ $$$diff success -$$$`, +$$$ +`, }, { "single successful apply with project name", @@ -2069,7 +2114,8 @@ $$$`, $$$diff success -$$$`, +$$$ +`, }, { "multiple successful plans", @@ -2125,6 +2171,10 @@ $$$ * $atlantis plan -d path2 -w workspace$ --- +### Plan Summary + +2 projects, 2 with changes, 0 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -2165,6 +2215,9 @@ success2 $$$ --- +### Apply Summary + +2 projects, 2 successful, 0 failed, 0 errored `, }, { @@ -2183,7 +2236,8 @@ $$$ **Plan Error** $$$ error -$$$`, +$$$ +`, }, { "single failed plan", @@ -2198,7 +2252,8 @@ $$$`, models.Github, `Ran Plan for dir: $path$ workspace: $workspace$ -**Plan Failed**: failure`, +**Plan Failed**: failure +`, }, { "successful, failed, and errored plan", @@ -2255,6 +2310,10 @@ error $$$ --- +### Plan Summary + +3 projects, 1 with changes, 0 with no changes, 2 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -2305,6 +2364,9 @@ error $$$ --- +### Apply Summary + +3 projects, 1 successful, 1 failed, 1 errored `, }, { @@ -2351,6 +2413,9 @@ error $$$ --- +### Apply Summary + +3 projects, 1 successful, 1 failed, 1 errored `, }, } @@ -2374,11 +2439,10 @@ $$$ for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -2812,11 +2876,10 @@ func TestRenderProjectResultsWithEnableDiffMarkdownFormat(t *testing.T) { for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, "", "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } @@ -2937,6 +3000,10 @@ $$$ * $atlantis plan -d path3 -w workspace$ --- +### Plan Summary + +3 projects, 2 with changes, 1 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -2988,6 +3055,10 @@ $$$ 1. project: $projectname$ dir: $path2$ workspace: $workspace$ 1. project: $projectname2$ dir: $path3$ workspace: $workspace$ +### Plan Summary + +3 projects, 0 with changes, 3 with no changes, 0 failed + * :fast_forward: To **apply** all unapplied plans from this pull request, comment: * $atlantis apply$ * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: @@ -3005,11 +3076,10 @@ $$$ for _, verbose := range []bool{true, false} { t.Run(c.Description, func(t *testing.T) { s := r.Render(res, c.Command, c.SubCommand, "log", verbose, c.VCSHost) - expWithBackticks := strings.Replace(c.Expected, "$", "`", -1) if !verbose { - Equals(t, strings.TrimSpace(expWithBackticks), strings.TrimSpace(s)) + Equals(t, normalize(c.Expected), normalize(s)) } else { - Equals(t, expWithBackticks+"\n
Log\n

\n\n```\nlog```\n

", s) + Equals(t, normalize(c.Expected+"\n
Log\n

\n\n```\nlog```\n

"), normalize(s)) } }) } diff --git a/server/events/templates/multi_project_apply.tmpl b/server/events/templates/multi_project_apply.tmpl index 701d766971..50038555b3 100644 --- a/server/events/templates/multi_project_apply.tmpl +++ b/server/events/templates/multi_project_apply.tmpl @@ -6,5 +6,6 @@ --- {{ end -}} -{{- template "log" . -}} +{{ template "multiProjectApplyFooter" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/multi_project_apply_footer.tmpl b/server/events/templates/multi_project_apply_footer.tmpl new file mode 100644 index 0000000000..58299868ce --- /dev/null +++ b/server/events/templates/multi_project_apply_footer.tmpl @@ -0,0 +1,7 @@ +{{ define "multiProjectApplyFooter" -}} +{{ if (gt (len .Results) 1) -}} +### Apply Summary + +{{ len .Results }} projects, {{ .NumApplySuccesses }} successful, {{ .NumApplyFailures }} failed, {{ .NumApplyErrors }} errored +{{ end -}} +{{ end -}} diff --git a/server/events/templates/multi_project_plan.tmpl b/server/events/templates/multi_project_plan.tmpl index 456b0ecf61..9c3898ad48 100644 --- a/server/events/templates/multi_project_plan.tmpl +++ b/server/events/templates/multi_project_plan.tmpl @@ -7,17 +7,8 @@ ### {{ add $i 1 }}. {{ if $result.ProjectName }}project: `{{ $result.ProjectName }}` {{ end }}dir: `{{ $result.RepoRelDir }}` workspace: `{{ $result.Workspace }}` {{ $result.Rendered }} -{{ if ne $disableApplyAll true -}} --- {{ end -}} -{{ end -}} -{{ if ne .DisableApplyAll true -}} -{{ if and (gt (len .Results) 0) (not .PlansDeleted) -}} -* :fast_forward: To **apply** all unapplied plans from this pull request, comment: - * `{{ .ExecutableName }} apply` -* :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: - * `{{ .ExecutableName }} unlock` -{{ end -}} -{{ end -}} -{{- template "log" . -}} +{{ template "multiProjectPlanFooter" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/multi_project_plan_footer.tmpl b/server/events/templates/multi_project_plan_footer.tmpl new file mode 100644 index 0000000000..41683ab018 --- /dev/null +++ b/server/events/templates/multi_project_plan_footer.tmpl @@ -0,0 +1,13 @@ +{{ define "multiProjectPlanFooter" -}} +{{ if and (gt (len .Results) 0) -}} +### Plan Summary + +{{ len .Results }} projects, {{ .NumPlansWithChanges }} with changes, {{ .NumPlansWithNoChanges }} with no changes, {{ .NumPlanFailures }} failed +{{ if and (not .PlansDeleted) (ne .DisableApplyAll true) }} +* :fast_forward: To **apply** all unapplied plans from this pull request, comment: + * `{{ .ExecutableName }} apply` +* :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: + * `{{ .ExecutableName }} unlock` +{{ end -}} +{{ end -}} +{{ end -}} diff --git a/server/events/templates/multi_project_policy.tmpl b/server/events/templates/multi_project_policy.tmpl new file mode 100644 index 0000000000..c34c59f896 --- /dev/null +++ b/server/events/templates/multi_project_policy.tmpl @@ -0,0 +1,23 @@ +{{ define "multiProjectPolicy" -}} +{{ template "multiProjectHeader" . }} +{{ $disableApplyAll := .DisableApplyAll -}} +{{ $hideUnchangedPlans := .HideUnchangedPlanComments -}} +{{ range $i, $result := .Results -}} +{{ if (and $hideUnchangedPlans $result.NoChanges) }}{{continue}}{{end -}} +### {{ add $i 1 }}. {{ if $result.ProjectName }}project: `{{ $result.ProjectName }}` {{ end }}dir: `{{ $result.RepoRelDir }}` workspace: `{{ $result.Workspace }}` +{{ $result.Rendered }} + +{{ if ne $disableApplyAll true -}} +--- +{{ end -}} +{{ end -}} +{{ if ne .DisableApplyAll true -}} +{{ if and (gt (len .Results) 0) (not .PlansDeleted) -}} +* :fast_forward: To **apply** all unapplied plans from this pull request, comment: + * `{{ .ExecutableName }} apply` +* :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: + * `{{ .ExecutableName }} unlock` +{{ end -}} +{{ end -}} +{{ template "log" . -}} +{{ end -}} diff --git a/server/events/templates/single_project_apply.tmpl b/server/events/templates/single_project_apply.tmpl index a963641b81..173bb46847 100644 --- a/server/events/templates/single_project_apply.tmpl +++ b/server/events/templates/single_project_apply.tmpl @@ -3,5 +3,5 @@ Ran {{ .Command }} for {{ if $result.ProjectName }}project: `{{ $result.ProjectName }}` {{ end }}dir: `{{ $result.RepoRelDir }}` workspace: `{{ $result.Workspace }}` {{ $result.Rendered }} -{{- template "log" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/single_project_import_success.tmpl b/server/events/templates/single_project_import_success.tmpl index 7e0fbd65c1..e03b53de5e 100644 --- a/server/events/templates/single_project_import_success.tmpl +++ b/server/events/templates/single_project_import_success.tmpl @@ -3,5 +3,5 @@ Ran {{ .Command }} for {{ if $result.ProjectName }}project: `{{ $result.ProjectName }}` {{ end }}dir: `{{ $result.RepoRelDir }}` workspace: `{{ $result.Workspace }}` {{ $result.Rendered }} -{{- template "log" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/single_project_plan_success.tmpl b/server/events/templates/single_project_plan_success.tmpl index 46c1b6640a..afbe3d5701 100644 --- a/server/events/templates/single_project_plan_success.tmpl +++ b/server/events/templates/single_project_plan_success.tmpl @@ -10,5 +10,5 @@ Ran {{ .Command }} for {{ if $result.ProjectName }}project: `{{ $result.ProjectN * :put_litter_in_its_place: To **delete** all plans and locks for the PR, comment: * `{{ .ExecutableName }} unlock` {{ end -}} -{{- template "log" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/single_project_plan_unsuccessful.tmpl b/server/events/templates/single_project_plan_unsuccessful.tmpl index 45c5c54926..1dd0cd9643 100644 --- a/server/events/templates/single_project_plan_unsuccessful.tmpl +++ b/server/events/templates/single_project_plan_unsuccessful.tmpl @@ -3,5 +3,5 @@ Ran {{ .Command }} for dir: `{{ $result.RepoRelDir }}` workspace: `{{ $result.Workspace }}` {{ $result.Rendered }} -{{- template "log" . -}} +{{ template "log" . -}} {{ end -}} diff --git a/server/events/templates/unwrapped_err.tmpl b/server/events/templates/unwrapped_err.tmpl index 1be0a7ef29..37b201ab93 100644 --- a/server/events/templates/unwrapped_err.tmpl +++ b/server/events/templates/unwrapped_err.tmpl @@ -1,9 +1,9 @@ {{ define "unwrappedErr" -}} -**{{.Command}} Error** +**{{ .Command }} Error** ``` -{{.Error}} +{{ .Error }} ``` -{{- if ne .RenderedContext ""}} +{{ if ne .RenderedContext "" -}} {{ .RenderedContext }} -{{- end }} -{{- end }} +{{ end -}} +{{ end -}}