• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubernetes-sigs / kubebuilder / 21778493952

07 Feb 2026 10:13AM UTC coverage: 73.863% (-0.09%) from 73.954%
21778493952

Pull #5448

github

camilamacedo86
fix(CLI/API) prevent --help from being validated as plugin name

- Add PersistentPreRunE hook to detect help flags in plugin values
- Filter help flags before plugin validation
- Show plugin descriptions instead of project versions
- Use short plugin keys (go/v4 vs go.kubebuilder.io/v4)
- Filter plugins by subcommand (init/edit/create)
- Hide deprecated plugins from help output
- Add documentation links for each plugin
- Improve root help wording for better getting-started experience

Generate-by: Cursour/Claude
Pull Request #5448: 🐛 fix(CLI/API) prevent --help from being validated as plugin name

174 of 227 new or added lines in 15 files covered. (76.65%)

1 existing line in 1 file now uncovered.

6887 of 9324 relevant lines covered (73.86%)

43.55 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

17.65
/pkg/plugins/optional/autoupdate/v1alpha/plugin.go
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
        "errors"
21
        "fmt"
22

23
        "sigs.k8s.io/kubebuilder/v4/pkg/config"
24
        cfgv3 "sigs.k8s.io/kubebuilder/v4/pkg/config/v3"
25
        "sigs.k8s.io/kubebuilder/v4/pkg/model/stage"
26
        "sigs.k8s.io/kubebuilder/v4/pkg/plugin"
27
        "sigs.k8s.io/kubebuilder/v4/pkg/plugins"
28
)
29

30
//nolint:lll
31
const metaDataDescription = `This plugin scaffolds a GitHub Action that helps you keep your project aligned with the latest Kubebuilder improvements. With a tiny amount of setup, you'll receive **automatic issue notifications** whenever a new Kubebuilder release is available. Each issue includes a **compare link** so you can open a Pull Request with one click and review the changes safely.
32

33
Under the hood, the workflow runs 'kubebuilder alpha update' using a **3-way merge strategy** to refresh your scaffold while preserving your code. It creates and pushes an update branch, then opens a GitHub **Issue** containing the PR URL you can use to review and merge.
34

35
### How to set it up
36

37
1) **Add the plugin**: Use the Kubebuilder CLI to scaffold the automation into your repo.
38
2) **Review the workflow**: The file '.github/workflows/auto_update.yml' runs on a schedule to check for updates.
39
3) **Permissions required** (via the built-in 'GITHUB_TOKEN'):
40
   - **contents: write** — needed to create and push the update branch.
41
   - **issues: write** — needed to create the tracking Issue with the PR link.
42
   - **models: read** (optional) — only required if using --use-gh-models flag for AI-generated summaries.
43
4) **Protect your branches**: Enable **branch protection rules** so automated changes **cannot** be pushed directly. All updates must go through a Pull Request for review.
44

45
### Optional: GitHub Models AI Summary
46

47
By default, the workflow does NOT use GitHub Models. To enable AI-generated summaries in GitHub issues:
48
  - Ensure your repository/organization has permissions to use GitHub Models.
49
  - Re-run: kubebuilder edit --plugins="autoupdate/v1-alpha" --use-gh-models
50

51
Without this flag, the workflow will still work but won't include AI summaries (avoiding 403 Forbidden errors).`
52

53
const pluginName = "autoupdate." + plugins.DefaultNameQualifier
54

55
var (
56
        pluginVersion            = plugin.Version{Number: 1, Stage: stage.Alpha}
57
        supportedProjectVersions = []config.Version{cfgv3.Version}
58
)
59

60
// Plugin implements the plugin.Full interface
61
type Plugin struct {
62
        editSubcommand
63
        initSubcommand
64
}
65

66
var _ plugin.Init = Plugin{}
67

68
// PluginConfig defines the structure that will be used to track the data
69
type PluginConfig struct {
70
        UseGHModels bool `json:"useGHModels,omitempty"`
71
}
72

73
// Name returns the name of the plugin
74
func (Plugin) Name() string { return pluginName }
12✔
75

76
// Version returns the version of the Helm plugin
77
func (Plugin) Version() plugin.Version { return pluginVersion }
18✔
78

79
// SupportedProjectVersions returns an array with all project versions supported by the plugin
80
func (Plugin) SupportedProjectVersions() []config.Version { return supportedProjectVersions }
1✔
81

82
// GetEditSubcommand will return the subcommand which is responsible for adding and/or edit a autoupdate
83
func (p Plugin) GetEditSubcommand() plugin.EditSubcommand { return &p.editSubcommand }
×
84

85
// GetInitSubcommand will return the subcommand which is responsible for init autoupdate plugin
86
func (p Plugin) GetInitSubcommand() plugin.InitSubcommand { return &p.initSubcommand }
×
87

88
// Description returns a short description of the plugin
NEW
89
func (Plugin) Description() string {
×
NEW
90
        return "Keep your project updated with low effort"
×
NEW
91
}
×
92

93
// DeprecationWarning define the deprecation message or return empty when plugin is not deprecated
94
func (p Plugin) DeprecationWarning() string {
1✔
95
        return ""
1✔
96
}
1✔
97

98
// insertPluginMetaToConfig will insert the metadata to the plugin configuration
99
func insertPluginMetaToConfig(target config.Config, cfg PluginConfig) error {
×
100
        key := plugin.GetPluginKeyForConfig(target.GetPluginChain(), Plugin{})
×
101
        canonicalKey := plugin.KeyFor(Plugin{})
×
102

×
103
        if err := target.DecodePluginConfig(key, &cfg); err != nil {
×
104
                switch {
×
105
                case errors.As(err, &config.UnsupportedFieldError{}):
×
106
                        return nil
×
107
                case errors.As(err, &config.PluginKeyNotFoundError{}):
×
108
                        if key != canonicalKey {
×
109
                                if err2 := target.DecodePluginConfig(canonicalKey, &cfg); err2 != nil {
×
110
                                        if errors.As(err2, &config.UnsupportedFieldError{}) {
×
111
                                                return nil
×
112
                                        }
×
113
                                        if !errors.As(err2, &config.PluginKeyNotFoundError{}) {
×
114
                                                return fmt.Errorf("error decoding plugin configuration: %w", err2)
×
115
                                        }
×
116
                                }
117
                        }
118
                default:
×
119
                        return fmt.Errorf("error decoding plugin configuration: %w", err)
×
120
                }
121
        }
122

123
        if err := target.EncodePluginConfig(key, cfg); err != nil {
×
124
                return fmt.Errorf("error encoding plugin configuration: %w", err)
×
125
        }
×
126

127
        return nil
×
128
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc