From 9fc8ad86562d9ed30c5501ee33e0b63b64de00de Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Mon, 29 Apr 2024 17:37:42 +0300 Subject: [PATCH 01/11] Add support for incremental stamping --- gitops/digester/BUILD | 20 +++++++++ gitops/digester/digester.go | 74 ++++++++++++++++++++++++++++++++ gitops/git/git.go | 29 +++++++++++++ gitops/prer/BUILD | 2 + gitops/prer/create_gitops_prs.go | 49 +++++++++++++++++++++ skylib/k8s.bzl | 11 ++++- skylib/kustomize/kustomize.bzl | 10 ++++- 7 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 gitops/digester/BUILD create mode 100644 gitops/digester/digester.go diff --git a/gitops/digester/BUILD b/gitops/digester/BUILD new file mode 100644 index 00000000..419188dd --- /dev/null +++ b/gitops/digester/BUILD @@ -0,0 +1,20 @@ +# Copyright 2024 Adobe. All rights reserved. +# This file is licensed to you under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. You may obtain a copy +# of the License at http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software distributed under +# the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +# OF ANY KIND, either express or implied. See the License for the specific language +# governing permissions and limitations under the License. + +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +licenses(["notice"]) # Apache 2.0 + +go_library( + name = "go_default_library", + srcs = ["digester.go"], + importpath = "github.com/adobe/rules_gitops/gitops/digester", + visibility = ["//visibility:public"], +) diff --git a/gitops/digester/digester.go b/gitops/digester/digester.go new file mode 100644 index 00000000..8cad5958 --- /dev/null +++ b/gitops/digester/digester.go @@ -0,0 +1,74 @@ +/* +Copyright 2024 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ +package digester + +import ( + "crypto/sha256" + "encoding/hex" + "errors" + "io" + "log" + "os" +) + +// CalculateDigest calculates the SHA256 digest of a file specified by the given path +func CalculateDigest(path string) string { + if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { + return "" + } + + fi, err := os.Open(path) + if err != nil { + log.Fatal(err) + } + defer fi.Close() + + h := sha256.New() + if _, err := io.Copy(h, fi); err != nil { + log.Fatal(err) + } + + return hex.EncodeToString(h.Sum(nil)) +} + +// GetDigest retrieves the digest of a file from a file with the same name but with a ".digest" extension +func GetDigest(path string) string { + digestPath := path + ".digest" + + if _, err := os.Stat(digestPath); errors.Is(err, os.ErrNotExist) { + return "" + } + + digest, err := os.ReadFile(digestPath) + if err != nil { + log.Fatal(err) + } + + return string(digest) +} + +// VerifyDigest verifies the integrity of a file by comparing its calculated digest with the stored digest +func VerifyDigest(path string) bool { + return CalculateDigest(path) == GetDigest(path) +} + +// SaveDigest calculates the digest of a file at the given path and saves it to a file with the same name but with a ".digest" extension. +func SaveDigest(path string) { + digest := CalculateDigest(path) + + digestPath := path + ".digest" + + err := os.WriteFile(digestPath, []byte(digest), 0666) + if err != nil { + log.Fatal(err) + } +} diff --git a/gitops/git/git.go b/gitops/git/git.go index 78181649..54877ec2 100644 --- a/gitops/git/git.go +++ b/gitops/git/git.go @@ -18,6 +18,7 @@ import ( "os" oe "os/exec" "path/filepath" + "strings" "github.com/adobe/rules_gitops/gitops/exec" ) @@ -103,6 +104,34 @@ func (r *Repo) Commit(message, gitopsPath string) bool { return true } +// RemoveDiff removes the changes made to a specific file in the repository +func (r *Repo) RemoveDiff(fileName string) { + exec.Mustex(r.Dir, "git", "checkout", "--", fileName) +} + +// split by newline and ignore empty strings +func SplitFunc(c rune) bool { + return c == '\n' +} + +// GetChangedFiles returns a list of files that have been changed in the repository +func (r *Repo) GetChangedFiles() []string { + files, err := exec.Ex(r.Dir, "git", "diff", "--name-only") + if err != nil { + log.Fatalf("ERROR: %s", err) + } + return strings.FieldsFunc(files, SplitFunc) +} + +// GetCommitSha returns the SHA of the current commit +func (r *Repo) GetCommitSha() string { + commit, err := exec.Ex(r.Dir, "git", "rev-parse", "HEAD") + if err != nil { + log.Fatalf("ERROR: %s", err) + } + return strings.TrimSpace(commit) +} + // IsClean returns true if there is no local changes (nothing to commit) func (r *Repo) IsClean() bool { cmd := oe.Command("git", "status", "--porcelain") diff --git a/gitops/prer/BUILD b/gitops/prer/BUILD index d40371ad..71640f2b 100644 --- a/gitops/prer/BUILD +++ b/gitops/prer/BUILD @@ -21,11 +21,13 @@ go_library( "//gitops/analysis:go_default_library", "//gitops/bazel:go_default_library", "//gitops/commitmsg:go_default_library", + "//gitops/digester:go_default_library", "//gitops/exec:go_default_library", "//gitops/git:go_default_library", "//gitops/git/bitbucket:go_default_library", "//gitops/git/github:go_default_library", "//gitops/git/gitlab:go_default_library", + "//templating/fasttemplate:go_default_library", "//vendor/github.com/golang/protobuf/proto:go_default_library", ], ) diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index 512d409e..cb8326ed 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -25,11 +25,13 @@ import ( "github.com/adobe/rules_gitops/gitops/analysis" "github.com/adobe/rules_gitops/gitops/bazel" "github.com/adobe/rules_gitops/gitops/commitmsg" + "github.com/adobe/rules_gitops/gitops/digester" "github.com/adobe/rules_gitops/gitops/exec" "github.com/adobe/rules_gitops/gitops/git" "github.com/adobe/rules_gitops/gitops/git/bitbucket" "github.com/adobe/rules_gitops/gitops/git/github" "github.com/adobe/rules_gitops/gitops/git/gitlab" + "github.com/adobe/rules_gitops/templating/fasttemplate" proto "github.com/golang/protobuf/proto" ) @@ -71,6 +73,7 @@ var ( gitopsRuleName SliceFlags gitopsRuleAttr SliceFlags dryRun = flag.Bool("dry_run", false, "Do not create PRs, just print what would be done") + stamp = flag.Bool("stamp", false, "Stamp results of gitops targets with volatile information") ) func init() { @@ -100,6 +103,40 @@ func bazelQuery(query string) *analysis.CqueryResult { return qr } +func getContext(workdir *git.Repo, branchName string) map[string]interface{} { + commitSha := workdir.GetCommitSha() + + utcDate, err := exec.Ex("", "date", "-u") + if err != nil { + log.Fatal(err) + } + utcDate = strings.TrimSpace(utcDate) + + ctx := map[string]interface{}{ + "GIT_REVISION": commitSha, + "UTC_DATE": utcDate, + "GIT_BRANCH": branchName, + } + + return ctx +} + +func stampFile(fullPath string, workdir *git.Repo, branchName string) { + template, err := os.ReadFile(fullPath) + if err != nil { + log.Fatal(err) + } + + ctx := getContext(workdir, branchName) + + stampedTemplate := fasttemplate.ExecuteString(string(template), "{{", "}}", ctx) + + err = os.WriteFile(fullPath, []byte(stampedTemplate), 0666) + if err != nil { + log.Fatal(err) + } +} + func main() { flag.Parse() if *workspace != "" { @@ -185,6 +222,18 @@ func main() { bin := bazel.TargetToExecutable(target) exec.Mustex("", bin, "--nopush", "--nobazel", "--deployment_root", gitopsdir) } + if *stamp { + changedFiles := workdir.GetChangedFiles() + for _, filePath := range changedFiles { + fullPath := gitopsdir + "/" + filePath + if digester.VerifyDigest(fullPath) { + workdir.RemoveDiff(fullPath) + } else { + digester.SaveDigest(fullPath) + stampFile(fullPath, workdir, *branchName) + } + } + } if workdir.Commit(fmt.Sprintf("GitOps for release branch %s from %s commit %s\n%s", *releaseBranch, *branchName, *gitCommit, commitmsg.Generate(targets)), *gitopsPath) { log.Println("branch", branch, "has changes, push is required") updatedGitopsTargets = append(updatedGitopsTargets, targets...) diff --git a/skylib/k8s.bzl b/skylib/k8s.bzl index 8391fa94..81a2c437 100644 --- a/skylib/k8s.bzl +++ b/skylib/k8s.bzl @@ -28,14 +28,21 @@ def _runfiles(ctx, f): def _show_impl(ctx): script_content = "#!/usr/bin/env bash\nset -e\n" + variables = "--variable=NAMESPACE={namespace}".format( + namespace = ctx.attr.namespace, + ) + variables += " --variable=GIT_REVISION=\"$(git rev-parse HEAD)\"" + variables += " --variable=UTC_DATE=\"$(date -u)\"" + variables += " --variable=GIT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD)\"" + kustomize_outputs = [] - script_template = "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file}\n" + script_template = "{template_engine} --template={infile} {variables} --stamp_info_file={info_file}\n" for dep in ctx.attr.src.files.to_list(): kustomize_outputs.append(script_template.format( infile = dep.short_path, template_engine = ctx.executable._template_engine.short_path, - namespace = ctx.attr.namespace, info_file = ctx.file._info_file.short_path, + variables = variables, )) # ensure kustomize outputs are separated by '---' delimiters diff --git a/skylib/kustomize/kustomize.bzl b/skylib/kustomize/kustomize.bzl index 7e2c5ee0..c2104d43 100644 --- a/skylib/kustomize/kustomize.bzl +++ b/skylib/kustomize/kustomize.bzl @@ -539,10 +539,17 @@ def _kubectl_impl(ctx): transitive = depset(transitive = [obj.default_runfiles.files for obj in trans_img_pushes]) transitive_runfiles += [exe[DefaultInfo].default_runfiles for exe in trans_img_pushes] + variables = "--variable=NAMESPACE={namespace}".format( + namespace = ctx.attr.namespace, + ) + variables += " --variable=GIT_REVISION=\"$(git rev-parse HEAD)\"" + variables += " --variable=UTC_DATE=\"$(date -u)\"" + variables += " --variable=GIT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD)\"" + namespace = ctx.attr.namespace for inattr in ctx.attr.srcs: for infile in inattr.files.to_list(): - statements += "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file} | kubectl --cluster=\"{cluster}\" --user=\"{user}\" {kubectl_command} -f -\n".format( + statements += "{template_engine} --template={infile} {variables} --stamp_info_file={info_file} | kubectl --cluster=\"{cluster}\" --user=\"{user}\" {kubectl_command} -f -\n".format( infile = infile.short_path, cluster = cluster_arg, user = user_arg, @@ -550,6 +557,7 @@ def _kubectl_impl(ctx): template_engine = "${RUNFILES}/%s" % _get_runfile_path(ctx, ctx.executable._template_engine), namespace = namespace, info_file = ctx.file._info_file.short_path, + variables = variables, ) ctx.actions.expand_template( From 8edf71cd21435dce20e211090d1c82743f92af1c Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Mon, 29 Apr 2024 17:57:19 +0300 Subject: [PATCH 02/11] Reuse namespace variable --- skylib/kustomize/kustomize.bzl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/skylib/kustomize/kustomize.bzl b/skylib/kustomize/kustomize.bzl index c2104d43..8bf2e2d7 100644 --- a/skylib/kustomize/kustomize.bzl +++ b/skylib/kustomize/kustomize.bzl @@ -539,14 +539,15 @@ def _kubectl_impl(ctx): transitive = depset(transitive = [obj.default_runfiles.files for obj in trans_img_pushes]) transitive_runfiles += [exe[DefaultInfo].default_runfiles for exe in trans_img_pushes] + namespace = ctx.attr.namespace + variables = "--variable=NAMESPACE={namespace}".format( - namespace = ctx.attr.namespace, + namespace = namespace, ) variables += " --variable=GIT_REVISION=\"$(git rev-parse HEAD)\"" variables += " --variable=UTC_DATE=\"$(date -u)\"" variables += " --variable=GIT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD)\"" - namespace = ctx.attr.namespace for inattr in ctx.attr.srcs: for infile in inattr.files.to_list(): statements += "{template_engine} --template={infile} {variables} --stamp_info_file={info_file} | kubectl --cluster=\"{cluster}\" --user=\"{user}\" {kubectl_command} -f -\n".format( @@ -555,7 +556,6 @@ def _kubectl_impl(ctx): user = user_arg, kubectl_command = kubectl_command_arg, template_engine = "${RUNFILES}/%s" % _get_runfile_path(ctx, ctx.executable._template_engine), - namespace = namespace, info_file = ctx.file._info_file.short_path, variables = variables, ) From b825973653915f373ba0ad8ea7ba07f0921791aa Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 15:05:48 +0300 Subject: [PATCH 03/11] Refactor remove diff function --- gitops/git/git.go | 4 ++-- gitops/prer/create_gitops_prs.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gitops/git/git.go b/gitops/git/git.go index 54877ec2..32837792 100644 --- a/gitops/git/git.go +++ b/gitops/git/git.go @@ -104,8 +104,8 @@ func (r *Repo) Commit(message, gitopsPath string) bool { return true } -// RemoveDiff removes the changes made to a specific file in the repository -func (r *Repo) RemoveDiff(fileName string) { +// RestoreFile restores the specified file in the repository to its original state +func (r *Repo) RestoreFile(fileName string) { exec.Mustex(r.Dir, "git", "checkout", "--", fileName) } diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index cb8326ed..69c3b733 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -227,7 +227,7 @@ func main() { for _, filePath := range changedFiles { fullPath := gitopsdir + "/" + filePath if digester.VerifyDigest(fullPath) { - workdir.RemoveDiff(fullPath) + workdir.RestoreFile(fullPath) } else { digester.SaveDigest(fullPath) stampFile(fullPath, workdir, *branchName) From ae3b54f73ebc228089f42519d1961e0c5ec8c6b2 Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 15:27:17 +0300 Subject: [PATCH 04/11] Refactor get changed files function --- gitops/git/git.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/gitops/git/git.go b/gitops/git/git.go index 32837792..b52eb53e 100644 --- a/gitops/git/git.go +++ b/gitops/git/git.go @@ -12,6 +12,7 @@ governing permissions and limitations under the License. package git import ( + "bufio" "fmt" "io/ioutil" "log" @@ -109,18 +110,21 @@ func (r *Repo) RestoreFile(fileName string) { exec.Mustex(r.Dir, "git", "checkout", "--", fileName) } -// split by newline and ignore empty strings -func SplitFunc(c rune) bool { - return c == '\n' -} - // GetChangedFiles returns a list of files that have been changed in the repository func (r *Repo) GetChangedFiles() []string { - files, err := exec.Ex(r.Dir, "git", "diff", "--name-only") + s, err := exec.Ex(r.Dir, "git", "diff", "--name-only") if err != nil { log.Fatalf("ERROR: %s", err) } - return strings.FieldsFunc(files, SplitFunc) + var files []string + sc := bufio.NewScanner(strings.NewReader(s)) + for sc.Scan() { + files = append(files, sc.Text()) + } + if err := sc.Err(); err != nil { + log.Fatalf("ERROR: %s", err) + } + return files } // GetCommitSha returns the SHA of the current commit From df89ffc3f56aa540c517ca8bc82c537fca64ea4f Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 15:30:27 +0300 Subject: [PATCH 05/11] Set dry run as last argument --- gitops/prer/create_gitops_prs.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index 69c3b733..a06d2b43 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -72,8 +72,8 @@ var ( gitopsKind SliceFlags gitopsRuleName SliceFlags gitopsRuleAttr SliceFlags - dryRun = flag.Bool("dry_run", false, "Do not create PRs, just print what would be done") stamp = flag.Bool("stamp", false, "Stamp results of gitops targets with volatile information") + dryRun = flag.Bool("dry_run", false, "Do not create PRs, just print what would be done") ) func init() { From 45169cd31878af85803b454b1b3595c1bd0888d6 Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 16:21:42 +0300 Subject: [PATCH 06/11] Refactor get context function name --- gitops/prer/create_gitops_prs.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index a06d2b43..3be8f487 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -103,7 +103,7 @@ func bazelQuery(query string) *analysis.CqueryResult { return qr } -func getContext(workdir *git.Repo, branchName string) map[string]interface{} { +func getGitStatusDict(workdir *git.Repo, branchName string) map[string]interface{} { commitSha := workdir.GetCommitSha() utcDate, err := exec.Ex("", "date", "-u") @@ -127,7 +127,7 @@ func stampFile(fullPath string, workdir *git.Repo, branchName string) { log.Fatal(err) } - ctx := getContext(workdir, branchName) + ctx := getGitStatusDict(workdir, branchName) stampedTemplate := fasttemplate.ExecuteString(string(template), "{{", "}}", ctx) From 5f6cb0e2e3c51fdb7ac8cbda5390a4abaf810fcf Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 16:43:09 +0300 Subject: [PATCH 07/11] Refactor stamp file to use execute --- gitops/prer/create_gitops_prs.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index 3be8f487..ee8e0320 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -129,9 +129,13 @@ func stampFile(fullPath string, workdir *git.Repo, branchName string) { ctx := getGitStatusDict(workdir, branchName) - stampedTemplate := fasttemplate.ExecuteString(string(template), "{{", "}}", ctx) + outf, err := os.OpenFile(fullPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + log.Fatal(err) + } + defer outf.Close() - err = os.WriteFile(fullPath, []byte(stampedTemplate), 0666) + _, err = fasttemplate.Execute(string(template), "{{", "}}", outf, ctx) if err != nil { log.Fatal(err) } From 50872a18d57b2c4e5ae406cc4b8a111b2d95a823 Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Tue, 30 Apr 2024 17:29:47 +0300 Subject: [PATCH 08/11] Update docs with stamp parameter --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index 0494cbd8..a2bd2b0b 100644 --- a/README.md +++ b/README.md @@ -464,6 +464,16 @@ As a result of the setup above the `create_gitops_prs` tool will open up to 2 po The GitOps pull request is only created (or new commits added) if the `gitops` target changes the state for the target deployment branch. The source pull request will remain open (and keep accumulation GitOps results) until the pull request is merged and source branch is deleted. +The `--stamp` parameter allows for the replacement of certain placeholders, but only when the `gitops` target changes the output's digest compared to the one already saved. The new digest of the unstamped data is also saved with the manifest. The digest is kept in a file in the same location as the YAML file, with a `.digest` extension added to its name. This is helpful when the manifests have volatile information that shouldn't be the only factor causing changes in the target deployment branch. + +Here are the placeholders that can be replaced: + +| Placeholder | Replacement | +|------------------|-------------------------------------------------| +| `{{GIT_REVISION}}` | Result of `git rev-parse HEAD` | +| `{{UTC_DATE}}` | Result of `date -u` | +| `{{GIT_BRANCH}}` | The `branch_name` argument given to `create_gitops_prs` | + `--dry_run` parameter can be used to test the tool without creating any pull requests. The tool will print the list of the potential pull requests. It is recommended to run the tool in the dry run mode as a part of the CI test suite to verify that the tool is configured correctly. From c423c37c4c4d8d6f80dd6ce071a1400fd76746f0 Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Thu, 2 May 2024 11:29:41 +0300 Subject: [PATCH 09/11] Restore changes to apply and show verbs --- skylib/k8s.bzl | 11 ++--------- skylib/kustomize/kustomize.bzl | 12 ++---------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/skylib/k8s.bzl b/skylib/k8s.bzl index 81a2c437..8391fa94 100644 --- a/skylib/k8s.bzl +++ b/skylib/k8s.bzl @@ -28,21 +28,14 @@ def _runfiles(ctx, f): def _show_impl(ctx): script_content = "#!/usr/bin/env bash\nset -e\n" - variables = "--variable=NAMESPACE={namespace}".format( - namespace = ctx.attr.namespace, - ) - variables += " --variable=GIT_REVISION=\"$(git rev-parse HEAD)\"" - variables += " --variable=UTC_DATE=\"$(date -u)\"" - variables += " --variable=GIT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD)\"" - kustomize_outputs = [] - script_template = "{template_engine} --template={infile} {variables} --stamp_info_file={info_file}\n" + script_template = "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file}\n" for dep in ctx.attr.src.files.to_list(): kustomize_outputs.append(script_template.format( infile = dep.short_path, template_engine = ctx.executable._template_engine.short_path, + namespace = ctx.attr.namespace, info_file = ctx.file._info_file.short_path, - variables = variables, )) # ensure kustomize outputs are separated by '---' delimiters diff --git a/skylib/kustomize/kustomize.bzl b/skylib/kustomize/kustomize.bzl index 8bf2e2d7..7e2c5ee0 100644 --- a/skylib/kustomize/kustomize.bzl +++ b/skylib/kustomize/kustomize.bzl @@ -540,24 +540,16 @@ def _kubectl_impl(ctx): transitive_runfiles += [exe[DefaultInfo].default_runfiles for exe in trans_img_pushes] namespace = ctx.attr.namespace - - variables = "--variable=NAMESPACE={namespace}".format( - namespace = namespace, - ) - variables += " --variable=GIT_REVISION=\"$(git rev-parse HEAD)\"" - variables += " --variable=UTC_DATE=\"$(date -u)\"" - variables += " --variable=GIT_BRANCH=\"$(git rev-parse --abbrev-ref HEAD)\"" - for inattr in ctx.attr.srcs: for infile in inattr.files.to_list(): - statements += "{template_engine} --template={infile} {variables} --stamp_info_file={info_file} | kubectl --cluster=\"{cluster}\" --user=\"{user}\" {kubectl_command} -f -\n".format( + statements += "{template_engine} --template={infile} --variable=NAMESPACE={namespace} --stamp_info_file={info_file} | kubectl --cluster=\"{cluster}\" --user=\"{user}\" {kubectl_command} -f -\n".format( infile = infile.short_path, cluster = cluster_arg, user = user_arg, kubectl_command = kubectl_command_arg, template_engine = "${RUNFILES}/%s" % _get_runfile_path(ctx, ctx.executable._template_engine), + namespace = namespace, info_file = ctx.file._info_file.short_path, - variables = variables, ) ctx.actions.expand_template( From 958f48a7f6116b9d7f102fc770294c31b7ff8c71 Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Thu, 2 May 2024 18:43:51 +0300 Subject: [PATCH 10/11] Optimise calls to get git status dict --- gitops/prer/create_gitops_prs.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index ee8e0320..adc269ff 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -121,14 +121,12 @@ func getGitStatusDict(workdir *git.Repo, branchName string) map[string]interface return ctx } -func stampFile(fullPath string, workdir *git.Repo, branchName string) { +func stampFile(fullPath string, ctx map[string]interface{}) { template, err := os.ReadFile(fullPath) if err != nil { log.Fatal(err) } - ctx := getGitStatusDict(workdir, branchName) - outf, err := os.OpenFile(fullPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { log.Fatal(err) @@ -228,13 +226,16 @@ func main() { } if *stamp { changedFiles := workdir.GetChangedFiles() - for _, filePath := range changedFiles { - fullPath := gitopsdir + "/" + filePath - if digester.VerifyDigest(fullPath) { - workdir.RestoreFile(fullPath) - } else { - digester.SaveDigest(fullPath) - stampFile(fullPath, workdir, *branchName) + if len(changedFiles) > 0 { + ctx := getGitStatusDict(workdir, *branchName) + for _, filePath := range changedFiles { + fullPath := gitopsdir + "/" + filePath + if digester.VerifyDigest(fullPath) { + workdir.RestoreFile(fullPath) + } else { + digester.SaveDigest(fullPath) + stampFile(fullPath, ctx) + } } } } From 8d6d022f4a4ef497656195d1df1772305861f91a Mon Sep 17 00:00:00 2001 From: Rares Andrei Date: Mon, 8 Jul 2024 16:54:00 +0300 Subject: [PATCH 11/11] Use git commit argument instead of function --- gitops/git/git.go | 9 --------- gitops/prer/create_gitops_prs.go | 8 +++----- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/gitops/git/git.go b/gitops/git/git.go index 90756820..190ca0d0 100644 --- a/gitops/git/git.go +++ b/gitops/git/git.go @@ -138,15 +138,6 @@ func (r *Repo) GetChangedFiles() []string { return files } -// GetCommitSha returns the SHA of the current commit -func (r *Repo) GetCommitSha() string { - commit, err := exec.Ex(r.Dir, "git", "rev-parse", "HEAD") - if err != nil { - log.Fatalf("ERROR: %s", err) - } - return strings.TrimSpace(commit) -} - // IsClean returns true if there is no local changes (nothing to commit) func (r *Repo) IsClean() bool { cmd := oe.Command("git", "status", "--porcelain") diff --git a/gitops/prer/create_gitops_prs.go b/gitops/prer/create_gitops_prs.go index d9afe0c6..0d53e004 100644 --- a/gitops/prer/create_gitops_prs.go +++ b/gitops/prer/create_gitops_prs.go @@ -104,9 +104,7 @@ func bazelQuery(query string) *analysis.CqueryResult { return qr } -func getGitStatusDict(workdir *git.Repo, branchName string) map[string]interface{} { - commitSha := workdir.GetCommitSha() - +func getGitStatusDict(workdir *git.Repo, gitCommit, branchName string) map[string]interface{} { utcDate, err := exec.Ex("", "date", "-u") if err != nil { log.Fatal(err) @@ -114,7 +112,7 @@ func getGitStatusDict(workdir *git.Repo, branchName string) map[string]interface utcDate = strings.TrimSpace(utcDate) ctx := map[string]interface{}{ - "GIT_REVISION": commitSha, + "GIT_REVISION": gitCommit, "UTC_DATE": utcDate, "GIT_BRANCH": branchName, } @@ -229,7 +227,7 @@ func main() { if *stamp { changedFiles := workdir.GetChangedFiles() if len(changedFiles) > 0 { - ctx := getGitStatusDict(workdir, *branchName) + ctx := getGitStatusDict(workdir, *gitCommit, *branchName) for _, filePath := range changedFiles { fullPath := gitopsdir + "/" + filePath if digester.VerifyDigest(fullPath) {