Skip to content

Commit

Permalink
feat: support skipping no changes
Browse files Browse the repository at this point in the history
  • Loading branch information
suzuki-shunsuke committed May 9, 2023
1 parent eba4d0e commit a2cbf87
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 47 deletions.
4 changes: 4 additions & 0 deletions pkg/cli/app.go
Expand Up @@ -72,6 +72,10 @@ func New(flags *LDFlags) *cli.App {
Name: "patch",
Usage: "update an existing comment instead of creating a new comment. If there is no existing comment, a new comment is created.",
},
&cli.BoolFlag{
Name: "skip-no-changes",
Usage: "If there is no change tfcmt updates a label but doesn't post a comment",
},
},
},
{
Expand Down
4 changes: 4 additions & 0 deletions pkg/cli/var.go
Expand Up @@ -62,6 +62,10 @@ func parseOpts(ctx *cli.Context, cfg *config.Config, envs []string) error {
cfg.Output = output
}

if ctx.IsSet("skip-no-changes") {
cfg.Terraform.Plan.WhenNoChanges.DisableComment = ctx.Bool("skip-no-changes")
}

vars := ctx.StringSlice("var")
vm := make(map[string]string, len(vars))
if err := parseVars(vars, envs, vm); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions pkg/config/config.go
Expand Up @@ -74,9 +74,10 @@ type WhenDestroy struct {

// WhenNoChanges is a configuration to add a label when the plan result contains no change
type WhenNoChanges struct {
Label string
Color string `yaml:"label_color"`
DisableLabel bool `yaml:"disable_label"`
Label string
Color string `yaml:"label_color"`
DisableLabel bool `yaml:"disable_label"`
DisableComment bool `yaml:"disable_comment"`
}

// WhenPlanError is a configuration to notify the plan result returns an error
Expand Down
1 change: 1 addition & 0 deletions pkg/controller/controller.go
Expand Up @@ -169,6 +169,7 @@ func (ctrl *Controller) getNotifier(ctx context.Context) (notifier.Notifier, err
EmbeddedVarNames: ctrl.Config.EmbeddedVarNames,
Templates: ctrl.Config.Templates,
Patch: ctrl.Config.PlanPatch,
SkipNoChanges: ctrl.Config.Terraform.Plan.WhenNoChanges.DisableComment,
})
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions pkg/notifier/github/client.go
Expand Up @@ -56,6 +56,7 @@ type Config struct {
Templates map[string]string
UseRawOutput bool
Patch bool
SkipNoChanges bool
}

// PullRequest represents GitHub Pull Request metadata
Expand Down
97 changes: 53 additions & 44 deletions pkg/notifier/github/plan.go
Expand Up @@ -11,71 +11,32 @@ import (
// Plan posts comment optimized for notifications
func (g *NotifyService) Plan(ctx context.Context, param *notifier.ParamExec) (int, error) { //nolint:cyclop
cfg := g.client.Config
parser := g.client.Config.Parser
template := g.client.Config.Template
var errMsgs []string

if cfg.PR.Number == 0 && cfg.PR.Revision != "" {
if prNumber, err := g.client.Commits.PRNumber(ctx, cfg.PR.Revision, PullRequestStateOpen); err == nil {
cfg.PR.Number = prNumber
}
}

result := parser.Parse(param.CombinedOutput)
result := g.client.Config.Parser.Parse(param.CombinedOutput)
result.ExitCode = param.ExitCode
if result.HasParseError {
template = g.client.Config.ParseErrorTemplate
} else {
if result.Error != nil {
return result.ExitCode, result.Error
}
if result.Result == "" {
return result.ExitCode, result.Error
}
if !result.HasParseError && (result.Error != nil || result.Result == "") {
return result.ExitCode, result.Error
}

var errMsgs []string
if cfg.PR.IsNumber() && cfg.ResultLabels.HasAnyLabelDefined() {
errMsgs = append(errMsgs, g.updateLabels(ctx, result)...)
}

template.SetValue(terraform.CommonTemplate{
Result: result.Result,
ChangedResult: result.ChangedResult,
ChangeOutsideTerraform: result.OutsideTerraform,
Warning: result.Warning,
HasDestroy: result.HasDestroy,
Link: cfg.CI,
UseRawOutput: cfg.UseRawOutput,
Vars: cfg.Vars,
Templates: cfg.Templates,
Stdout: param.Stdout,
Stderr: param.Stderr,
CombinedOutput: param.CombinedOutput,
ExitCode: param.ExitCode,
ErrorMessages: errMsgs,
CreatedResources: result.CreatedResources,
UpdatedResources: result.UpdatedResources,
DeletedResources: result.DeletedResources,
ReplacedResources: result.ReplacedResources,
})
body, err := template.Execute()
if err != nil {
return result.ExitCode, err
}

logE := logrus.WithFields(logrus.Fields{
"program": "tfcmt",
})

embeddedComment, err := getEmbeddedComment(cfg, param.CIName, true)
body, err := g.buildBody(logE, &result, param, errMsgs)
if err != nil {
return result.ExitCode, err
}
logE.WithFields(logrus.Fields{
"comment": embeddedComment,
}).Debug("embedded HTML comment")
// embed HTML tag to hide old comments
body += embeddedComment

if cfg.Patch && cfg.PR.Number != 0 {
logE.Debug("try patching")
Expand Down Expand Up @@ -105,6 +66,11 @@ func (g *NotifyService) Plan(ctx context.Context, param *notifier.ParamExec) (in
}
}

if result.HasNoChanges {
logE.Debug("skip posting a comment because there is no change")
return result.ExitCode, nil
}

logE.Debug("create a comment")
if err := g.client.Comment.Post(ctx, body, &PostOptions{
Number: cfg.PR.Number,
Expand All @@ -114,3 +80,46 @@ func (g *NotifyService) Plan(ctx context.Context, param *notifier.ParamExec) (in
}
return result.ExitCode, nil
}

func (g *NotifyService) buildBody(logE *logrus.Entry, result *terraform.ParseResult, param *notifier.ParamExec, errMsgs []string) (string, error) {
template := g.client.Config.Template
if result.HasParseError {
template = g.client.Config.ParseErrorTemplate
}
cfg := g.client.Config
template.SetValue(terraform.CommonTemplate{
Result: result.Result,
ChangedResult: result.ChangedResult,
ChangeOutsideTerraform: result.OutsideTerraform,
Warning: result.Warning,
HasDestroy: result.HasDestroy,
Link: cfg.CI,
UseRawOutput: cfg.UseRawOutput,
Vars: cfg.Vars,
Templates: cfg.Templates,
Stdout: param.Stdout,
Stderr: param.Stderr,
CombinedOutput: param.CombinedOutput,
ExitCode: param.ExitCode,
ErrorMessages: errMsgs,
CreatedResources: result.CreatedResources,
UpdatedResources: result.UpdatedResources,
DeletedResources: result.DeletedResources,
ReplacedResources: result.ReplacedResources,
})
body, err := template.Execute()
if err != nil {
return "", err
}

embeddedComment, err := getEmbeddedComment(cfg, param.CIName, true)
if err != nil {
return "", err
}
logE.WithFields(logrus.Fields{
"comment": embeddedComment,
}).Debug("embedded HTML comment")
// embed HTML tag to hide old comments
body += embeddedComment
return body, nil
}

0 comments on commit a2cbf87

Please sign in to comment.