fix(cli): recognize build/bake/builder aliasing before cloud help check

docker --cloud build rejected every BuildKit-only flag (--secret, --ssh,
--push, --output, ...) because cloudHelpRequest parsed remaining args
against the legacy build command's flag set before processAliases
rewrites build into a buildx invocation. Treat build/bake/builder/image
build the same as plugin commands: only recognize --help/-h immediately
after the resolved command path instead of validating flags.

Fixes #7350

Signed-off-by: Nick Sieger <nick@nicksieger.com>
This commit is contained in:
Nick Sieger
2026-10-02 16:52:51 -05:00
parent 48988f5c12
commit 6cb63efe6f
2 changed files with 22 additions and 1 deletions
+17 -1
View File
@@ -199,7 +199,17 @@ func cloudHelpRequest(rootCmd *cobra.Command, args []string) (bool, error) {
if err != nil || cmd == rootCmd || pluginmanager.IsPluginCommand(cmd) {
// Plugin flags are opaque. Only recognize help immediately after the
// plugin name; deeper help is available through "docker help PLUGIN".
return len(args) > 1 && (args[1] == "--help" || args[1] == "-h" || args[1] == "--help=true"), nil
return len(args) > 1 && isHelpFlag(args[1]), nil
}
// "build", "bake", "builder", and "image build" are builtin commands that
// processAliases may still rewrite into a call to the builder plugin
// (buildx) after cloud resolution runs, so their flag set here is only the
// legacy builder's and does not reflect what will actually parse the
// remaining args. Treat them like a plugin command above: only recognize
// help immediately after the resolved command path.
if _, _, _, forwarded := forwardBuilder(builderDefaultPlugin, args, args); forwarded {
return len(remaining) > 0 && isHelpFlag(remaining[0]), nil
}
cmd.InitDefaultHelpFlag()
@@ -226,6 +236,12 @@ func cloudHelpRequest(rootCmd *cobra.Command, args []string) (bool, error) {
return help, nil
}
// isHelpFlag reports whether arg requests help, in any of the forms pflag
// accepts for a boolean flag.
func isHelpFlag(arg string) bool {
return arg == "--help" || arg == "-h" || arg == "--help=true"
}
// cloudPluginArgs only rewrites the global prefix, leaving subcommand arguments
// untouched. Parsing also distinguishes --cloud from another flag's value.
func cloudPluginArgs(cmd *cobra.Command, osArgs []string, contextName string) ([]string, error) {
+5
View File
@@ -62,6 +62,11 @@ func TestCloudHelpRequest(t *testing.T) {
{name: "container help", args: []string{"run", "alpine", "--help"}},
{name: "flag value", args: []string{"run", "--name", "--help", "alpine"}},
{name: "help disabled", args: []string{"run", "--help=false", "alpine"}},
{name: "build help", args: []string{"build", "--help"}, help: true},
{name: "build buildkit-only flag", args: []string{"build", "--secret", "id=s,src=./s", "."}},
{name: "image build buildkit-only flag", args: []string{"image", "build", "--push", "."}},
{name: "builder build buildkit-only flag", args: []string{"builder", "build", "--ssh", "default", "."}},
{name: "bake help", args: []string{"bake", "--help"}, help: true},
} {
t.Run(tc.name, func(t *testing.T) {
dockerCli, err := command.NewDockerCli()