Merge pull request #3832 from crazy-max/bake-policy-flag

bake: global policy evaluation options
This commit is contained in:
Tõnis Tiigi
2026-05-11 10:58:38 -07:00
committed by GitHub
3 changed files with 71 additions and 2 deletions
+40
View File
@@ -57,6 +57,7 @@ type bakeOptions struct {
sbom string
provenance string
policy []string
allow []string
builder string
@@ -120,6 +121,14 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
if in.provenance != "" {
overrides = append(overrides, fmt.Sprintf("*.attest=%s", buildflags.CanonicalizeAttest("provenance", in.provenance)))
}
policyOverrides, disablePolicy, err := bakePolicyOverrides(in.policy)
if err != nil {
return err
} else if len(policyOverrides) > 0 {
overrides = append(overrides, policyOverrides...)
}
contextPathHash, _ := os.Getwd()
ent, err := bake.ParseEntitlements(in.allow)
@@ -241,6 +250,12 @@ func runBake(ctx context.Context, dockerCli command.Cli, targets []string, in ba
if err != nil {
return err
}
if disablePolicy {
policy := buildflags.PolicyConfigs{{Disabled: true}}
for _, t := range tgts {
t.Policy = slices.Clone(policy)
}
}
var sourceDateEpoch *string
for _, t := range tgts {
@@ -526,6 +541,7 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
flags.BoolVar(&options.exportPush, "push", false, `Shorthand for "--set=*.output=type=registry". Conditional.`)
flags.StringVar(&options.sbom, "sbom", "", `Shorthand for "--set=*.attest=type=sbom"`)
flags.StringVar(&options.provenance, "provenance", "", `Shorthand for "--set=*.attest=type=provenance"`)
flags.StringArrayVar(&options.policy, "policy", []string{}, `Global policy evaluation options (format: "[disabled=true|false][,strict=true|false][,log-level=level]")`)
flags.StringArrayVar(&options.overrides, "set", nil, `Override target value (e.g., "targetpattern.key=value")`)
flags.StringArrayVar(&options.vars, "var", nil, `Set a variable value (e.g., "name=value")`)
flags.StringVar(&options.callFunc, "call", "build", `Set method for evaluating build ("check", "outline", "targets")`)
@@ -550,6 +566,30 @@ func bakeCmd(dockerCli command.Cli, rootOpts *rootOptions) *cobra.Command {
return cmd
}
func bakePolicyOverrides(in []string) ([]string, bool, error) {
configs, err := buildflags.ParsePolicyConfigs(in)
if err != nil {
return nil, false, err
}
overrides := make([]string, 0, len(in))
for i, cfg := range configs {
if len(cfg.Files) > 0 {
return nil, false, errors.New(`--policy does not accept filename; define policy files in the bake definition`)
}
if cfg.Reset {
return nil, false, errors.New(`--policy does not accept reset; define policy composition in the bake definition`)
}
if cfg.Disabled {
if cfg.Strict != nil || cfg.LogLevel != nil || len(configs) > 1 {
return nil, false, errors.New("disabled policy cannot be combined with other policy flags")
}
return nil, true, nil
}
overrides = append(overrides, "*.policy+="+in[i])
}
return overrides, false, nil
}
func bakeEnvFiles(lookup func(string string) (string, bool)) ([]string, error) {
sep, _ := lookup(bakeEnvFileSeparator)
if sep == "" {
+1
View File
@@ -25,6 +25,7 @@ Build from a file
| [`--load`](#load) | `bool` | | Shorthand for `--set=*.output=type=docker`. Conditional. |
| [`--metadata-file`](#metadata-file) | `string` | | Write build result metadata to a file |
| [`--no-cache`](#no-cache) | `bool` | | Do not use cache when building the image |
| `--policy` | `stringArray` | | Global policy evaluation options (format: `[disabled=true\|false][,strict=true\|false][,log-level=level]`) |
| [`--print`](#print) | `bool` | | Print the options without building |
| [`--progress`](#progress) | `string` | `auto` | Set type of progress output (`auto`, `none`, `plain`, `quiet`, `rawjson`, `tty`). Use plain to show container output |
| [`--provenance`](#provenance) | `string` | | Shorthand for `--set=*.attest=type=provenance` |
+30 -2
View File
@@ -126,6 +126,7 @@ target "disabled-combined" {
cases := []struct {
name string
target string
policyArgs []string
wantErrContains string
}{
{
@@ -160,15 +161,42 @@ target "disabled-combined" {
target: "disabled-combined",
wantErrContains: "disabled policy cannot be combined with other policy flags",
},
{
name: "global-disabled-skips-target-policies",
target: "fail-extra",
policyArgs: []string{"--policy", "disabled=true"},
},
{
name: "global-policy-rejects-filename",
target: "pass-both",
policyArgs: []string{"--policy", "filename=extra.rego"},
wantErrContains: "--policy does not accept filename",
},
{
name: "global-policy-rejects-reset",
target: "pass-both",
policyArgs: []string{"--policy", "reset=true"},
wantErrContains: "--policy does not accept reset",
},
{
name: "global-disabled-cannot-combine",
target: "pass-both",
policyArgs: []string{"--policy", "disabled=true,strict=true"},
wantErrContains: "disabled policy cannot be combined with other policy flags",
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
cmd := buildxCmd(sb, withDir(dir), withArgs(
args := []string{
"bake",
"--progress=plain",
"--file", "docker-bake.hcl",
tc.target,
}
args = append(args, tc.policyArgs...)
args = append(args, tc.target)
cmd := buildxCmd(sb, withDir(dir), withArgs(
args...,
))
out, err := cmd.CombinedOutput()
if tc.wantErrContains == "" {