Skip to content

Commit 9b9b397

Browse files
authored
Merge pull request #5027 from camilamacedo86/docs-alpha-update
✨ Add plugin for Alpha Update Command
2 parents 6e00113 + 2697198 commit 9b9b397

File tree

16 files changed

+587
-9
lines changed

16 files changed

+587
-9
lines changed

cmd/cmd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang"
3333
deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1"
3434
golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4"
35+
autoupdatev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha"
3536
grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
3637
helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
3738
)
@@ -74,6 +75,7 @@ func Run() {
7475
&deployimagev1alpha1.Plugin{},
7576
&grafanav1alpha1.Plugin{},
7677
&helmv1alpha1.Plugin{},
78+
&autoupdatev1alpha1.Plugin{},
7779
),
7880
cli.WithPlugins(externalPlugins...),
7981
cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle),

docs/book/src/SUMMARY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@
120120
- [Plugins][plugins]
121121

122122
- [Available Plugins](./plugins/available-plugins.md)
123+
- [autoupdate/v1-alpha](./plugins/available/autoupdate-v1-alpha.md)
124+
- [deploy-image/v1-alpha](./plugins/available/deploy-image-plugin-v1-alpha.md)
123125
- [go/v4](./plugins/available/go-v4-plugin.md)
124126
- [grafana/v1-alpha](./plugins/available/grafana-v1-alpha.md)
125-
- [deploy-image/v1-alpha](./plugins/available/deploy-image-plugin-v1-alpha.md)
126127
- [helm/v1-alpha](./plugins/available/helm-v1-alpha.md)
127128
- [kustomize/v2](./plugins/available/kustomize-v2.md)
128129
- [Extending](./plugins/extending.md)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# AutoUpdate (`autoupdate/v1-alpha`)
2+
3+
Keeping your Kubebuilder project up to date with the latest improvements shouldn’t be a chore.
4+
With a small amount of setup, you can receive **automatic Pull Request** suggestions whenever a new
5+
Kubebuilder release is available — keeping your project **maintained, secure, and aligned with ecosystem changes**.
6+
7+
This automation uses the [`kubebuilder alpha update`][alpha-update-command] command with a **3-way merge strategy** to
8+
refresh your project scaffold, and wraps it in a GitHub Actions workflow that opens an **Issue** with a **Pull Request compare link** so you can create the PR and review it.
9+
10+
## When to Use It
11+
12+
- When you don’t deviate too much from the default scaffold — ensure that you see the note about customization [here](https://book.kubebuilder.io/versions_compatibility_supportability#project-customizations).
13+
- When you want to reduce the burden of keeping the project updated and well-maintained.
14+
15+
## How to Use It
16+
17+
0 If you want to add the `autoupdate` plugin to your project:
18+
19+
```shell
20+
kubebuilder edit --plugins="autoupdate.kubebuilder.io/v1-alpha"
21+
```
22+
23+
- If you want to create a new project with the `autoupdate` plugin:
24+
25+
```shell
26+
kubebuilder init --plugins=go/v4,autoupdate/v1-alpha
27+
```
28+
29+
## How It Works
30+
31+
This will scaffold and GitHub Actions workflow that runs the [kubebuilder alpha update][alpha-update-command] command.
32+
Then, whenever a new Kubebuilder release is available, it will open an Issue with a
33+
Pull Request compare link so you can create the PR and review it, such as:
34+
35+
<img width="638" height="482" alt="Example Issue" src="https://github.com/user-attachments/assets/589fd16b-7709-4cd5-b169-fd53d69790d4" />
36+
37+
The workflow will check once a week for new releases, and if there are any, it will create an Issue with a Pull Request compare link so you can create the PR and review it.
38+
The command called by the workflow is:
39+
40+
```shell
41+
# More info: https://kubebuilder.io/reference/commands/alpha_update
42+
- name: Run kubebuilder alpha update
43+
run: |
44+
# Executes the update command with specified flags.
45+
# --force: Completes the merge even if conflicts occur, leaving conflict markers.
46+
# --push: Automatically pushes the resulting output branch to the 'origin' remote.
47+
# --restore-path: Preserves specified paths (e.g., CI workflow files) when squashing.
48+
# --open-gh-issue: Creates a GitHub issue with a link to the generated PR for review.
49+
kubebuilder alpha update \
50+
--force \
51+
--push \
52+
--restore-path .github/workflows \
53+
--open-gh-issue
54+
```
55+
56+
<aside class="warning">
57+
<h1>Protect your branches</h1>
58+
59+
This workflow by default **only** creates and pushes the merged files to a branch
60+
called `kubebuilder-update-from-<from-version>-to-<to-version>`.
61+
62+
To keep your codebase safe, use branch protection rules to ensure that
63+
changes aren't pushed or merged without proper review.
64+
65+
</aside>
66+
67+
[alpha-update-command]: ./../../reference/commands/alpha_update.md

docs/book/src/plugins/to-add-optional-features.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
The following plugins are useful to generate code and take advantage of optional features
44

5-
| Plugin | Key | Description |
6-
|---------------------------------------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
7-
| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
8-
| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |
9-
| [helm.kubebuilder.io/v1-alpha][helm] | `helm/v1-alpha` | Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory |
5+
| Plugin | Key | Description |
6+
|-----------------------------------------------------|-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
7+
| [autoupdate.kubebuilder.io/v1-alpha][autoupdate] | `autoupdate/v1-alpha` | Optional helper which scaffolds a scheduled worker that helps keep your project updated with changes in the ecosystem, significantly reducing the burden of manual maintenance. |
8+
| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |
9+
| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
10+
| [helm.kubebuilder.io/v1-alpha][helm] | `helm/v1-alpha` | Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory |
1011

1112
[grafana]: ./available/grafana-v1-alpha.md
1213
[deploy]: ./available/deploy-image-plugin-v1-alpha.md
13-
[helm]: ./available/helm-v1-alpha.md
14+
[helm]: ./available/helm-v1-alpha.md
15+
[autoupdate]: ./available/autoupdate-v1-alpha.md

docs/book/src/reference/commands/alpha_update.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ not re-applying your code.
99
By default, the final result is **squashed into a single commit** on a dedicated output branch.
1010
If you prefer to keep the full history (no squash), use `--show-commits`.
1111

12+
<aside class="note">
13+
<h1>Automate your Updates</h1>
14+
15+
You can reduce the burden of keeping your project up to date by using the
16+
[`autoupdate.kubebuilder.io/v1-alpha`][autoupdate-plugin] plugin which
17+
automates the process of running `kubebuilder alpha update` on a schedule
18+
workflow when new Kubebuilder releases are available.
19+
20+
</aside>
21+
1222
## When to Use It
1323

1424
Use this command when you:
@@ -207,6 +217,10 @@ so the current behavior may differ slightly from what is shown in the demo.
207217

208218
## Further Resources
209219

210-
- WIP: Design proposal for update automation — https://github.com/kubernetes-sigs/kubebuilder/pull/4302
220+
- [AutoUpdate Plugin][autoupdate-plugin]
221+
- [Design proposal for update automation][design-proposal]
222+
- [Project configuration reference][project-config]
211223

212224
[project-config]: ../../reference/project-config.md
225+
[autoupdate-plugin]: ./../../plugins/available/autoupdate-v1-alpha.md
226+
[design-proposal]: ./../../../../../designs/update_action.md

pkg/cli/alpha/internal/generate.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
3232
"sigs.k8s.io/kubebuilder/v4/pkg/plugin/util"
3333
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1"
34+
autoupdate "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha"
3435
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
3536
hemlv1alpha "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
3637
)
@@ -106,6 +107,10 @@ func (opts *Generate) Generate() error {
106107
return fmt.Errorf("error migrating Grafana plugin: %w", err)
107108
}
108109

110+
if err = migrateAutoUpdatePlugin(projectConfig); err != nil {
111+
return fmt.Errorf("error migrating AutoUpdate plugin: %w", err)
112+
}
113+
109114
if hasHelmPlugin(projectConfig) {
110115
if err = kubebuilderHelmEdit(); err != nil {
111116
return fmt.Errorf("error editing Helm plugin: %w", err)
@@ -233,6 +238,23 @@ func migrateGrafanaPlugin(s store.Store, src, des string) error {
233238
return kubebuilderGrafanaEdit()
234239
}
235240

241+
func migrateAutoUpdatePlugin(s store.Store) error {
242+
var autoUpdatePlugin struct{}
243+
err := s.Config().DecodePluginConfig(plugin.KeyFor(autoupdate.Plugin{}), autoUpdatePlugin)
244+
if errors.As(err, &config.PluginKeyNotFoundError{}) {
245+
log.Info("Auto Update plugin not found, skipping migration")
246+
return nil
247+
} else if err != nil {
248+
return fmt.Errorf("failed to decode autoupdate plugin config: %w", err)
249+
}
250+
251+
args := []string{"edit", "--plugins", plugin.KeyFor(v1alpha.Plugin{})}
252+
if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
253+
return fmt.Errorf("failed to run edit subcommand for Auto plugin: %w", err)
254+
}
255+
return nil
256+
}
257+
236258
// Migrates the Deploy Image plugin.
237259
func migrateDeployImagePlugin(s store.Store) error {
238260
var deployImagePlugin v1alpha1.PluginConfig

pkg/cli/alpha/internal/update/update.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Create a Pull Request using the URL below to review the changes:
126126
127127
## Next steps
128128
129-
Verify the changes
129+
**Verify the changes**
130130
- Build the project
131131
- Run tests
132132
- Confirm everything still works
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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 v1alpha
18+
19+
import (
20+
"fmt"
21+
22+
"sigs.k8s.io/kubebuilder/v4/pkg/config"
23+
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
24+
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
25+
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha/scaffolds"
26+
)
27+
28+
var _ plugin.EditSubcommand = &editSubcommand{}
29+
30+
type editSubcommand struct {
31+
config config.Config
32+
}
33+
34+
func (p *editSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
35+
subcmdMeta.Description = metaDataDescription
36+
37+
subcmdMeta.Examples = fmt.Sprintf(` # Edit a common project with this plugin
38+
%[1]s edit --plugins=%[2]s
39+
`, cliMeta.CommandName, pluginKey)
40+
}
41+
42+
func (p *editSubcommand) InjectConfig(c config.Config) error {
43+
p.config = c
44+
return nil
45+
}
46+
47+
func (p *editSubcommand) PreScaffold(machinery.Filesystem) error {
48+
if len(p.config.GetCliVersion()) == 0 {
49+
return fmt.Errorf(
50+
"you must manually upgrade your project to a version that records the CLI version in PROJECT (`cliVersion`) " +
51+
"to allow the `alpha update` command to work properly before using this plugin.\n" +
52+
"More info: https://book.kubebuilder.io/migrations",
53+
)
54+
}
55+
return nil
56+
}
57+
58+
func (p *editSubcommand) Scaffold(fs machinery.Filesystem) error {
59+
if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil {
60+
return fmt.Errorf("error inserting project plugin meta to configuration: %w", err)
61+
}
62+
63+
scaffolder := scaffolds.NewInitScaffolder()
64+
scaffolder.InjectFS(fs)
65+
if err := scaffolder.Scaffold(); err != nil {
66+
return fmt.Errorf("error scaffolding edit subcommand: %w", err)
67+
}
68+
69+
return nil
70+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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 v1alpha
18+
19+
import (
20+
"fmt"
21+
22+
"sigs.k8s.io/kubebuilder/v4/pkg/config"
23+
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
24+
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
25+
"sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/autoupdate/v1alpha/scaffolds"
26+
)
27+
28+
var _ plugin.InitSubcommand = &initSubcommand{}
29+
30+
type initSubcommand struct {
31+
config config.Config
32+
}
33+
34+
func (p *initSubcommand) UpdateMetadata(cliMeta plugin.CLIMetadata, subcmdMeta *plugin.SubcommandMetadata) {
35+
subcmdMeta.Description = metaDataDescription
36+
37+
subcmdMeta.Examples = fmt.Sprintf(` # Initialize a common project with this plugin
38+
%[1]s init --plugins=%[2]s
39+
`, cliMeta.CommandName, pluginKey)
40+
}
41+
42+
func (p *initSubcommand) InjectConfig(c config.Config) error {
43+
p.config = c
44+
return nil
45+
}
46+
47+
func (p *initSubcommand) Scaffold(fs machinery.Filesystem) error {
48+
if err := insertPluginMetaToConfig(p.config, pluginConfig{}); err != nil {
49+
return fmt.Errorf("error inserting project plugin meta to configuration: %w", err)
50+
}
51+
52+
scaffolder := scaffolds.NewInitScaffolder()
53+
scaffolder.InjectFS(fs)
54+
if err := scaffolder.Scaffold(); err != nil {
55+
return fmt.Errorf("error scaffolding init subcommand: %w", err)
56+
}
57+
58+
return nil
59+
}

0 commit comments

Comments
 (0)