From 8144638baba3bff4d01f8a643c6d844d30efbc83 Mon Sep 17 00:00:00 2001 From: Yusuke Kuoka Date: Thu, 22 Dec 2022 20:30:44 +0900 Subject: [PATCH] feat: Helmfile V1 mode (#594) * feat: Helmfile V1 mode We add a new "V1 mode" to Helmfile so that you can seemlessly upgrade Helmfile from the current v0.x to the upcoming v1.0. The idea is that we build both v0 and v1 binaries from the same tagged commit within the main branch, with different defaults for the "V1 mode"- the V1 mode is disabled by default for v0.x binaries, while it is enabled by default for v1.x binaries. The V1 mode can be overrode at runtime via envvar. That is, even after upgrading the binary to v1, you will not see any backward-incompatible changes while you explicitly set an envvar, `HELMFILE_V1MODE=true`, at runtime. Signed-off-by: Yusuke Kuoka Signed-off-by: yxxhero --- .github/workflows/publish_binaries.yaml | 4 +-- .github/workflows/publish_v1_binaries.yml | 33 ++++++++++++++++++++ .goreleaser.yml | 4 +++ Makefile | 4 +++ cmd/root.go | 3 +- pkg/envvar/const.go | 1 + pkg/runtime/runtime.go | 37 +++++++++++++++++++++++ 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/publish_v1_binaries.yml create mode 100644 pkg/runtime/runtime.go diff --git a/.github/workflows/publish_binaries.yaml b/.github/workflows/publish_binaries.yaml index 343f0e1a..aee35017 100644 --- a/.github/workflows/publish_binaries.yaml +++ b/.github/workflows/publish_binaries.yaml @@ -1,11 +1,11 @@ -name: Publish Binaries +name: Publish v0.x Binaries on: push: branches: - "!*" tags: - - "v*" + - "v0*" jobs: goreleaser: diff --git a/.github/workflows/publish_v1_binaries.yml b/.github/workflows/publish_v1_binaries.yml new file mode 100644 index 00000000..31567537 --- /dev/null +++ b/.github/workflows/publish_v1_binaries.yml @@ -0,0 +1,33 @@ +name: Publish v1.x Binaries + +on: + push: + branches: + - "!*" + tags: + - "v1*" + +env: + # This is referenced from .goreleaser.yml + HELMFILE_V1MODE: "true" + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - + name: Checkout + uses: actions/checkout@v1 + - + name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.19 + - + name: Run GoReleaser + uses: goreleaser/goreleaser-action@v1 + with: + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yml b/.goreleaser.yml index fd3724ea..cd8517af 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,4 +1,7 @@ project_name: helmfile +env: + # We default to non-v1 mode (=helmfile v0.x behavior) when HELMFILE_V1MODE is not set + - HELMFILE_V1MODE={{ if index .Env "HELMFILE_V1MODE" }}{{ .Env.HELMFILE_V1MODE }}{{ else }}false{{ end }} builds: - id: helmfile main: . @@ -11,6 +14,7 @@ builds: - -X go.szostok.io/version.commit={{.FullCommit}} - -X go.szostok.io/version.commitDate={{.CommitDate}} - -X go.szostok.io/version.dirtyBuild=false + - -X github.com/helmfile/helmfile/pkg/runtime.v1Mode={{.Env.HELMFILE_V1MODE}} goos: - darwin - linux diff --git a/Makefile b/Makefile index faca381b..f162687c 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,10 @@ build: go build -ldflags="$(GO_BUILD_VERSION_LDFLAGS)" ${TARGETS} .PHONY: build +build-v1: + go build -ldflags="$(GO_BUILD_VERSION_LDFLAGS) -X github.com/helmfile/helmfile/pkg/runtime.v1Mode=true" ${TARGETS} +.PHONY: build-v1 + generate: go generate ${PKGS} .PHONY: generate diff --git a/cmd/root.go b/cmd/root.go index a7d2d695..88e6cd30 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,10 +15,11 @@ import ( "github.com/helmfile/helmfile/pkg/envvar" "github.com/helmfile/helmfile/pkg/errors" "github.com/helmfile/helmfile/pkg/helmexec" + "github.com/helmfile/helmfile/pkg/runtime" ) var logger *zap.SugaredLogger -var globalUsage = "Declaratively deploy your Kubernetes manifests, Kustomize configs, and Charts as Helm releases in one shot" +var globalUsage = "Declaratively deploy your Kubernetes manifests, Kustomize configs, and Charts as Helm releases in one shot\n" + runtime.Info() func toCLIError(g *config.GlobalImpl, err error) error { if err != nil { diff --git a/pkg/envvar/const.go b/pkg/envvar/const.go index 3e4ea37e..d8ab2de5 100644 --- a/pkg/envvar/const.go +++ b/pkg/envvar/const.go @@ -9,4 +9,5 @@ const ( TempDir = "HELMFILE_TEMPDIR" Helm3 = "HELMFILE_HELM3" UpgradeNoticeDisabled = "HELMFILE_UPGRADE_NOTICE_DISABLED" + V1Mode = "HELMFILE_V1MODE" ) diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go new file mode 100644 index 00000000..7efda582 --- /dev/null +++ b/pkg/runtime/runtime.go @@ -0,0 +1,37 @@ +package runtime + +import ( + "fmt" + "os" + "strconv" + + "github.com/helmfile/helmfile/pkg/envvar" +) + +// V1Mode is false by default for Helmfile v0.x and +// true by default for Helmfile v1.x +var ( + V1Mode bool + + // We set this via ldflags at build-time so that we can use the + // value specified at the build time as the runtime default. + v1Mode string +) + +func Info() string { + return fmt.Sprintf("V1 mode = %v", V1Mode) +} + +func init() { + // You can toggle the V1 mode at runtime via an envvar: + // - Helmfile v1.x behaves like v0.x by running it with HELMFILE_V1MODE=false + // - Helmfile v0.x behaves like v1.x by with HELMFILE_V1MODE=true + switch os.Getenv(envvar.V1Mode) { + case "true": + V1Mode = true + case "false": + V1Mode = false + default: + V1Mode, _ = strconv.ParseBool(v1Mode) + } +}