Skip to content

Commit 4e36984

Browse files
committed
feat(helm): remove helm from init command
The helm-plugin is meant to extend an existing go project. For a correct rendering of the helm-chart some information (like the project name) from the go project is needed. Signed-off-by: Mario Constanti <[email protected]>
1 parent 1f774a5 commit 4e36984

File tree

7 files changed

+259
-69
lines changed

7 files changed

+259
-69
lines changed

docs/book/src/plugins/available/helm-v1-alpha.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ under the [testdata][testdata] directory on the root directory of the Kubebuilde
4141

4242
### Basic Usage
4343

44-
The Helm plugin is attached to the `init` subcommand and the `edit` subcommand:
44+
The Helm plugin is attached to the `edit` subcommand as the `helm/v1-alpha` plugin
45+
relies on the Go project being scaffolded first.
4546

4647
```sh
4748

48-
# Initialize a new project with helm chart
49-
kubebuilder init --plugins=helm/v1-alpha
49+
# Initialize a new project
50+
kubebuilder init
5051

5152
# Enable or Update the helm chart via the helm plugin to an existing project
5253
# Before run the edit command, run `make manifests` to generate the manifest under `config/`
@@ -80,8 +81,6 @@ The Helm plugin implements the following subcommands:
8081

8182
- edit (`$ kubebuilder edit [OPTIONS]`)
8283

83-
- init (`$ kubebuilder init [OPTIONS]`)
84-
8584
## Affected files
8685

8786
The following scaffolds will be created or updated by this plugin:

pkg/plugin/util/util_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,62 @@ var _ = Describe("Cover plugin util helpers", func() {
101101
Expect(lines).To(Equal([]string{"noemptylines"}))
102102
})
103103
})
104+
105+
Describe("HasFileContentWith", Ordered, func() {
106+
107+
const (
108+
path = "testdata/PROJECT"
109+
content = `# Code generated by tool. DO NOT EDIT.
110+
# This file is used to track the info used to scaffold your project
111+
# and allow the plugins properly work.
112+
# More info: https://book.kubebuilder.io/reference/project-config.html
113+
domain: example.org
114+
layout:
115+
- go.kubebuilder.io/v4
116+
- helm.kubebuilder.io/v1-alpha
117+
plugins:
118+
helm.kubebuilder.io/v1-alpha: {}
119+
repo: github.com/example/repo
120+
version: "3"
121+
`
122+
)
123+
124+
BeforeAll(func() {
125+
err := os.MkdirAll("testdata", 0o755)
126+
Expect(err).NotTo(HaveOccurred())
127+
128+
if _, err = os.Stat(path); os.IsNotExist(err) {
129+
err = os.WriteFile(path, []byte(content), 0o644)
130+
Expect(err).NotTo(HaveOccurred())
131+
}
132+
})
133+
134+
AfterAll(func() {
135+
err := os.RemoveAll("testdata")
136+
Expect(err).NotTo(HaveOccurred())
137+
})
138+
139+
It("should return true when file contains the expected content", func() {
140+
content := "repo: github.com/example/repo"
141+
found, err := HasFileContentWith(path, content)
142+
Expect(err).NotTo(HaveOccurred())
143+
Expect(found).To(BeTrue())
144+
})
145+
146+
It("should return true when file contains multiline expected content", func() {
147+
content := `plugins:
148+
helm.kubebuilder.io/v1-alpha: {}`
149+
found, err := HasFileContentWith(path, content)
150+
Expect(err).NotTo(HaveOccurred())
151+
Expect(found).To(BeTrue())
152+
})
153+
154+
It("should return false when file does not contain the expected content", func() {
155+
content := "nonExistentContent"
156+
found, err := HasFileContentWith(path, content)
157+
Expect(err).NotTo(HaveOccurred())
158+
Expect(found).To(BeFalse())
159+
})
160+
161+
})
104162
})

pkg/plugins/optional/helm/v1alpha/init.go

Lines changed: 0 additions & 59 deletions
This file was deleted.

pkg/plugins/optional/helm/v1alpha/plugin.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ var (
3434

3535
// Plugin implements the plugin.Full interface
3636
type Plugin struct {
37-
initSubcommand
3837
editSubcommand
3938
}
4039

4140
var (
42-
_ plugin.Init = Plugin{}
4341
_ plugin.Edit = Plugin{}
4442
)
4543

@@ -54,9 +52,6 @@ func (Plugin) Version() plugin.Version { return pluginVersion }
5452
// SupportedProjectVersions returns an array with all project versions supported by the plugin
5553
func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions }
5654

57-
// GetInitSubcommand will return the subcommand which is responsible for initializing and scaffolding helm manifests
58-
func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand }
59-
6055
// GetEditSubcommand will return the subcommand which is responsible for adding and/or edit a helm chart
6156
func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand }
6257

test/e2e/helm/e2e_suite_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
14+
package helm
15+
16+
import (
17+
"fmt"
18+
"testing"
19+
20+
. "github.com/onsi/ginkgo/v2"
21+
. "github.com/onsi/gomega"
22+
)
23+
24+
// Run e2e tests using the Ginkgo runner.
25+
func TestE2E(t *testing.T) {
26+
RegisterFailHandler(Fail)
27+
_, _ = fmt.Fprintf(GinkgoWriter, "Starting helm plugin kubebuilder suite\n")
28+
RunSpecs(t, "Kubebuilder helm plugin e2e suite")
29+
}

test/e2e/helm/generate_test.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package helm
18+
19+
import (
20+
"path/filepath"
21+
22+
pluginutil "sigs.k8s.io/kubebuilder/v4/pkg/plugin/util"
23+
24+
. "github.com/onsi/ginkgo/v2"
25+
26+
. "github.com/onsi/gomega"
27+
28+
"sigs.k8s.io/kubebuilder/v4/test/e2e/utils"
29+
)
30+
31+
var _ = Describe("kubebuilder", func() {
32+
Context("plugin helm/v1-alpha", func() {
33+
var kbc *utils.TestContext
34+
35+
BeforeEach(func() {
36+
var err error
37+
kbc, err = utils.NewTestContext(pluginutil.KubebuilderBinName, "GO111MODULE=on")
38+
Expect(err).NotTo(HaveOccurred())
39+
Expect(kbc.Prepare()).To(Succeed())
40+
})
41+
42+
AfterEach(func() {
43+
kbc.Destroy()
44+
})
45+
46+
It("should extend a runnable project with helm plugin", func() {
47+
initTheProject(kbc)
48+
generateProject(kbc)
49+
})
50+
51+
It("should extend a runnable project with helm plugin and webhooks", func() {
52+
initTheProject(kbc)
53+
generateProject(kbc)
54+
extendProjectWithWebhooks(kbc)
55+
56+
By("re-edit the project after creating webhooks")
57+
err := kbc.Edit(
58+
"--plugins", "helm.kubebuilder.io/v1-alpha", "--force",
59+
)
60+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
61+
62+
fileContainsExpr, err := pluginutil.HasFileContentWith(
63+
filepath.Join(kbc.Dir, "dist", "chart", "values.yaml"),
64+
`webhook:
65+
enable: true`)
66+
Expect(err).NotTo(HaveOccurred(), "Failed to read values.yaml file")
67+
Expect(fileContainsExpr).To(BeTrue(), "Failed to get enabled webhook value from values.yaml file")
68+
})
69+
70+
// Without --force, the webhooks should not be enabled in the values.yaml file.
71+
It("should extend a runnable project with helm plugin but not running with --force", func() {
72+
initTheProject(kbc)
73+
generateProject(kbc)
74+
extendProjectWithWebhooks(kbc)
75+
76+
By("re-edit the project after creating webhooks without --force")
77+
err := kbc.Edit(
78+
"--plugins", "helm.kubebuilder.io/v1-alpha",
79+
)
80+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
81+
82+
fileContainsExpr, err := pluginutil.HasFileContentWith(
83+
filepath.Join(kbc.Dir, "dist", "chart", "values.yaml"),
84+
`webhook:
85+
enable: true`)
86+
Expect(err).NotTo(HaveOccurred(), "Failed to read values.yaml file")
87+
Expect(fileContainsExpr).To(BeFalse(), "Failed to get enabled webhook value from values.yaml file")
88+
})
89+
90+
})
91+
})
92+
93+
// generateProject implements a helm/v1(-alpha) plugin project defined by a TestContext.
94+
func generateProject(kbc *utils.TestContext) {
95+
var err error
96+
97+
By("editing a project")
98+
err = kbc.Edit(
99+
"--plugins", "helm.kubebuilder.io/v1-alpha",
100+
)
101+
Expect(err).NotTo(HaveOccurred(), "Failed to edit the project")
102+
103+
fileContainsExpr, err := pluginutil.HasFileContentWith(
104+
filepath.Join(kbc.Dir, "PROJECT"),
105+
`helm.kubebuilder.io/v1-alpha: {}`)
106+
Expect(err).NotTo(HaveOccurred(), "Failed to read PROJECT file")
107+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find helm plugin in PROJECT file")
108+
109+
fileContainsExpr, err = pluginutil.HasFileContentWith(
110+
filepath.Join(kbc.Dir, "PROJECT"),
111+
"projectName: e2e-"+kbc.TestSuffix)
112+
Expect(err).NotTo(HaveOccurred(), "Failed to read PROJECT file")
113+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find projectName in PROJECT file")
114+
115+
fileContainsExpr, err = pluginutil.HasFileContentWith(
116+
filepath.Join(kbc.Dir, "dist", "chart", "Chart.yaml"),
117+
"name: e2e-"+kbc.TestSuffix)
118+
Expect(err).NotTo(HaveOccurred(), "Failed to read Chart.yaml file")
119+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find name in Chart.yaml file")
120+
121+
fileContainsExpr, err = pluginutil.HasFileContentWith(
122+
filepath.Join(kbc.Dir, "dist", "chart", "templates", "manager", "manager.yaml"),
123+
`metadata:
124+
name: e2e-`+kbc.TestSuffix)
125+
Expect(err).NotTo(HaveOccurred(), "Failed to read manager.yaml file")
126+
Expect(fileContainsExpr).To(BeTrue(), "Failed to find name in helm template manager.yaml file")
127+
}
128+
129+
// extendProjectWithWebhooks is creating API and scaffolding webhooks in the project
130+
func extendProjectWithWebhooks(kbc *utils.TestContext) {
131+
By("creating API definition")
132+
err := kbc.CreateAPI(
133+
"--group", kbc.Group,
134+
"--version", kbc.Version,
135+
"--kind", kbc.Kind,
136+
"--namespaced",
137+
"--resource",
138+
"--controller",
139+
"--make=false",
140+
)
141+
Expect(err).NotTo(HaveOccurred(), "Failed to create API")
142+
143+
By("scaffolding mutating and validating webhooks")
144+
err = kbc.CreateWebhook(
145+
"--group", kbc.Group,
146+
"--version", kbc.Version,
147+
"--kind", kbc.Kind,
148+
"--defaulting",
149+
"--programmatic-validation",
150+
"--make=false",
151+
)
152+
Expect(err).NotTo(HaveOccurred(), "Failed to scaffolding mutating webhook")
153+
154+
By("run make manifests")
155+
Expect(kbc.Make("manifests")).To(Succeed())
156+
}
157+
158+
// initTheProject initializes a project with the go/v4 plugin and sets the domain.
159+
func initTheProject(kbc *utils.TestContext) {
160+
By("initializing a project")
161+
err := kbc.Init(
162+
"--plugins", "go/v4",
163+
"--project-version", "3",
164+
"--domain", kbc.Domain,
165+
)
166+
Expect(err).NotTo(HaveOccurred(), "Failed to initialize project")
167+
}

test/e2e/setup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ function test_cluster {
6565
kind load docker-image --name $KIND_CLUSTER busybox:1.36.1
6666

6767
go test $(dirname "$0")/grafana $flags -timeout 30m
68+
go test $(dirname "$0")/helm $flags -timeout 30m
6869
go test $(dirname "$0")/deployimage $flags -timeout 30m
6970
go test $(dirname "$0")/v4 $flags -timeout 30m
7071
go test $(dirname "$0")/alphagenerate $flags -timeout 30m

0 commit comments

Comments
 (0)