From 7f0bc2ada24753f54eda098b3a83d2e8264cbee0 Mon Sep 17 00:00:00 2001
From: Hidde Beydals <hello@hidde.co>
Date: Mon, 29 Mar 2021 14:21:23 +0200
Subject: [PATCH] Provide option to add appendix to commit messages

Using the `--commit-message-appendix` flag a string can be added to the
commit messages made by the bootstrapper process to for example skip CI
actions from executing using e.g. `[skip ci]`.

Signed-off-by: Hidde Beydals <hello@hidde.co>
---
 cmd/flux/bootstrap.go                     |  4 ++++
 cmd/flux/bootstrap_git.go                 |  1 +
 cmd/flux/bootstrap_github.go              |  1 +
 cmd/flux/bootstrap_gitlab.go              |  1 +
 docs/cmd/flux_bootstrap.md                |  1 +
 docs/cmd/flux_bootstrap_git.md            |  1 +
 docs/cmd/flux_bootstrap_github.md         |  1 +
 docs/cmd/flux_bootstrap_gitlab.md         |  1 +
 internal/bootstrap/bootstrap_plain_git.go | 15 ++++++++++++---
 internal/bootstrap/options.go             | 14 ++++++++++++++
 10 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go
index 46d7fe38..05139ab4 100644
--- a/cmd/flux/bootstrap.go
+++ b/cmd/flux/bootstrap.go
@@ -65,6 +65,8 @@ type bootstrapFlags struct {
 
 	authorName  string
 	authorEmail string
+
+	commitMessageAppendix string
 }
 
 const (
@@ -113,6 +115,8 @@ func init() {
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.authorName, "author-name", "Flux", "author name for Git commits")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.authorEmail, "author-email", "", "author email for Git commits")
 
+	bootstrapCmd.PersistentFlags().StringVar(&bootstrapArgs.commitMessageAppendix, "commit-message-appendix", "", "string to add to the commit messages, e.g. '[ci skip]'")
+
 	bootstrapCmd.PersistentFlags().Var(&bootstrapArgs.arch, "arch", bootstrapArgs.arch.Description())
 	bootstrapCmd.PersistentFlags().MarkDeprecated("arch", "multi-arch container image is now available for AMD64, ARMv7 and ARM64")
 	bootstrapCmd.PersistentFlags().MarkHidden("manifests")
diff --git a/cmd/flux/bootstrap_git.go b/cmd/flux/bootstrap_git.go
index 0774d1d9..fa8eb584 100644
--- a/cmd/flux/bootstrap_git.go
+++ b/cmd/flux/bootstrap_git.go
@@ -196,6 +196,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
 		bootstrap.WithRepositoryURL(gitArgs.url),
 		bootstrap.WithBranch(bootstrapArgs.branch),
 		bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
+		bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
 		bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
 		bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
 		bootstrap.WithLogger(logger),
diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go
index 747d9829..81238331 100644
--- a/cmd/flux/bootstrap_github.go
+++ b/cmd/flux/bootstrap_github.go
@@ -219,6 +219,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
 		bootstrap.WithBranch(bootstrapArgs.branch),
 		bootstrap.WithBootstrapTransportType("https"),
 		bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
+		bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
 		bootstrap.WithProviderTeamPermissions(mapTeamSlice(githubArgs.teams, ghDefaultPermission)),
 		bootstrap.WithReadWriteKeyPermissions(githubArgs.readWriteKey),
 		bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go
index 48768c80..6be6c6f5 100644
--- a/cmd/flux/bootstrap_gitlab.go
+++ b/cmd/flux/bootstrap_gitlab.go
@@ -228,6 +228,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
 		bootstrap.WithBranch(bootstrapArgs.branch),
 		bootstrap.WithBootstrapTransportType("https"),
 		bootstrap.WithAuthor(bootstrapArgs.authorName, bootstrapArgs.authorEmail),
+		bootstrap.WithCommitMessageAppendix(bootstrapArgs.commitMessageAppendix),
 		bootstrap.WithProviderTeamPermissions(mapTeamSlice(gitlabArgs.teams, glDefaultPermission)),
 		bootstrap.WithReadWriteKeyPermissions(gitlabArgs.readWriteKey),
 		bootstrap.WithKubeconfig(rootArgs.kubeconfig, rootArgs.kubecontext),
diff --git a/docs/cmd/flux_bootstrap.md b/docs/cmd/flux_bootstrap.md
index d6ca280a..7d944dbd 100644
--- a/docs/cmd/flux_bootstrap.md
+++ b/docs/cmd/flux_bootstrap.md
@@ -17,6 +17,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
       --branch string                          default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --ca-file string                         path to TLS CA file used for validating self-signed certificates
       --cluster-domain string                  internal cluster domain (default "cluster.local")
+      --commit-message-appendix string         string to add to the commit messages, e.g. '[ci skip]'
       --components strings                     list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --components-extra strings               list of components in addition to those supplied or defaulted, accepts comma-separated values
   -h, --help                                   help for bootstrap
diff --git a/docs/cmd/flux_bootstrap_git.md b/docs/cmd/flux_bootstrap_git.md
index 63819939..0587e536 100644
--- a/docs/cmd/flux_bootstrap_git.md
+++ b/docs/cmd/flux_bootstrap_git.md
@@ -49,6 +49,7 @@ flux bootstrap git [flags]
       --branch string                          default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --ca-file string                         path to TLS CA file used for validating self-signed certificates
       --cluster-domain string                  internal cluster domain (default "cluster.local")
+      --commit-message-appendix string         string to add to the commit messages, e.g. '[ci skip]'
       --components strings                     list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --components-extra strings               list of components in addition to those supplied or defaulted, accepts comma-separated values
       --context string                         kubernetes context to use
diff --git a/docs/cmd/flux_bootstrap_github.md b/docs/cmd/flux_bootstrap_github.md
index cde0605d..05dbe90e 100644
--- a/docs/cmd/flux_bootstrap_github.md
+++ b/docs/cmd/flux_bootstrap_github.md
@@ -68,6 +68,7 @@ flux bootstrap github [flags]
       --branch string                          default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --ca-file string                         path to TLS CA file used for validating self-signed certificates
       --cluster-domain string                  internal cluster domain (default "cluster.local")
+      --commit-message-appendix string         string to add to the commit messages, e.g. '[ci skip]'
       --components strings                     list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --components-extra strings               list of components in addition to those supplied or defaulted, accepts comma-separated values
       --context string                         kubernetes context to use
diff --git a/docs/cmd/flux_bootstrap_gitlab.md b/docs/cmd/flux_bootstrap_gitlab.md
index 3d0b9c43..a3a6823f 100644
--- a/docs/cmd/flux_bootstrap_gitlab.md
+++ b/docs/cmd/flux_bootstrap_gitlab.md
@@ -65,6 +65,7 @@ flux bootstrap gitlab [flags]
       --branch string                          default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --ca-file string                         path to TLS CA file used for validating self-signed certificates
       --cluster-domain string                  internal cluster domain (default "cluster.local")
+      --commit-message-appendix string         string to add to the commit messages, e.g. '[ci skip]'
       --components strings                     list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
       --components-extra strings               list of components in addition to those supplied or defaulted, accepts comma-separated values
       --context string                         kubernetes context to use
diff --git a/internal/bootstrap/bootstrap_plain_git.go b/internal/bootstrap/bootstrap_plain_git.go
index b293b78b..8119e79a 100644
--- a/internal/bootstrap/bootstrap_plain_git.go
+++ b/internal/bootstrap/bootstrap_plain_git.go
@@ -48,7 +48,8 @@ type PlainGitBootstrapper struct {
 	url    string
 	branch string
 
-	author git.Author
+	author                git.Author
+	commitMessageAppendix string
 
 	kubeconfig  string
 	kubecontext string
@@ -126,9 +127,13 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
 	}
 
 	// Git commit generated
+	commitMsg := fmt.Sprintf("Add Flux %s component manifests", options.Version)
+	if b.commitMessageAppendix != "" {
+		commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
+	}
 	commit, err := b.git.Commit(git.Commit{
 		Author:  b.author,
-		Message: fmt.Sprintf("Add Flux %s component manifests", options.Version),
+		Message: commitMsg,
 	})
 	if err != nil && err != git.ErrNoStagedFiles {
 		return fmt.Errorf("failed to commit sync manifests: %w", err)
@@ -245,9 +250,13 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
 	b.logger.Successf("generated sync manifests")
 
 	// Git commit generated
+	commitMsg := fmt.Sprintf("Add Flux sync manifests")
+	if b.commitMessageAppendix != "" {
+		commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
+	}
 	commit, err := b.git.Commit(git.Commit{
 		Author:  b.author,
-		Message: fmt.Sprintf("Add Flux sync manifests"),
+		Message: commitMsg,
 	})
 	if err != nil && err != git.ErrNoStagedFiles {
 		return fmt.Errorf("failed to commit sync manifests: %w", err)
diff --git a/internal/bootstrap/options.go b/internal/bootstrap/options.go
index 9f737771..88972c1e 100644
--- a/internal/bootstrap/options.go
+++ b/internal/bootstrap/options.go
@@ -62,6 +62,20 @@ func (o authorOption) applyGitProvider(b *GitProviderBootstrapper) {
 	o.applyGit(b.PlainGitBootstrapper)
 }
 
+func WithCommitMessageAppendix(appendix string) Option {
+	return commitMessageAppendixOption(appendix)
+}
+
+type commitMessageAppendixOption string
+
+func (o commitMessageAppendixOption) applyGit(b *PlainGitBootstrapper) {
+	b.commitMessageAppendix = string(o)
+}
+
+func (o commitMessageAppendixOption) applyGitProvider(b *GitProviderBootstrapper) {
+	o.applyGit(b.PlainGitBootstrapper)
+}
+
 func WithKubeconfig(kubeconfig, kubecontext string) Option {
 	return kubeconfigOption{
 		kubeconfig:  kubeconfig,
-- 
GitLab