From 6718d079515415cec6790b3f0325bb754c24e90c Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Mon, 24 Aug 2026 16:12:52 +0000 Subject: [PATCH 1/4] acc: build CLI with FIPS toolchain so `go test` matches release Co-authored-by: Isaac --- acceptance/acceptance_test.go | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 69fd5a0258..c21d616db3 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -35,6 +35,7 @@ import ( "github.com/databricks/cli/libs/testdiff" "github.com/databricks/cli/libs/testserver" "github.com/stretchr/testify/require" + "go.yaml.in/yaml/v3" ) var ( @@ -1285,10 +1286,29 @@ func BuildCLI(t *testing.T, buildDir, coverDir, osName, arch string) string { args = append(args, "-buildvcs=false") } - RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch}) + // Build with the FIPS toolchain so `go test` ships the same binary the + // Taskfile and release pipeline do; otherwise acceptance/fips (which asserts + // the FIPS build settings) fails on a plain `go test` run. + RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + readGOFIPS140(t)}) return execPath } +// readGOFIPS140 returns the GOFIPS140 version pinned in the repo Taskfile, the +// single source of truth also used by the release pipeline. +func readGOFIPS140(t *testing.T) string { + data, err := os.ReadFile(filepath.Join("..", "Taskfile.yml")) + require.NoError(t, err) + + var taskfile struct { + Env struct { + GOFIPS140 string `yaml:"GOFIPS140"` + } `yaml:"env"` + } + require.NoError(t, yaml.Unmarshal(data, &taskfile)) + require.NotEmpty(t, taskfile.Env.GOFIPS140, "GOFIPS140 not set in Taskfile.yml") + return taskfile.Env.GOFIPS140 +} + // CreateReleaseArtifacts builds release artifacts for the given OS using amd64 and arm64 architectures, // archives them into zip files, and returns the directory containing the release artifacts. func CreateReleaseArtifacts(t *testing.T, cwd, coverDir, osName string) string { From a09a086dbd3fad933210d5c2f7e08d16b3fa6a10 Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Mon, 24 Aug 2026 17:15:58 +0000 Subject: [PATCH 2/4] acc: fix release-pipeline comment and thread repo root into readGOFIPS140 Co-authored-by: Isaac --- acceptance/acceptance_test.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index c21d616db3..659f46bfd4 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -1286,18 +1286,21 @@ func BuildCLI(t *testing.T, buildDir, coverDir, osName, arch string) string { args = append(args, "-buildvcs=false") } - // Build with the FIPS toolchain so `go test` ships the same binary the - // Taskfile and release pipeline do; otherwise acceptance/fips (which asserts - // the FIPS build settings) fails on a plain `go test` run. - RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + readGOFIPS140(t)}) + // Build with the FIPS toolchain so a plain `go test` produces the same FIPS + // binary as `task` and the release build; otherwise acceptance/fips (which + // asserts the FIPS build settings) fails outside `task`. + repoRoot := ".." + RunCommand(t, args, repoRoot, []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + readGOFIPS140(t, repoRoot)}) return execPath } -// readGOFIPS140 returns the GOFIPS140 version pinned in the repo Taskfile, the -// single source of truth also used by the release pipeline. -func readGOFIPS140(t *testing.T) string { - data, err := os.ReadFile(filepath.Join("..", "Taskfile.yml")) - require.NoError(t, err) +// readGOFIPS140 returns the GOFIPS140 version the Taskfile pins for `task` +// builds. The release pipeline pins the same value independently in +// .goreleaser.yaml. +func readGOFIPS140(t *testing.T, repoRoot string) string { + path := filepath.Join(repoRoot, "Taskfile.yml") + data, err := os.ReadFile(path) + require.NoError(t, err, "reading %s (acceptance tests must run with cwd=acceptance/)", path) var taskfile struct { Env struct { From d003d1899dadcee25682cf31dbc7186f95fe6940 Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Tue, 25 Aug 2026 10:46:10 +0000 Subject: [PATCH 3/4] acc: read GOFIPS140 once via sync.OnceValues Co-authored-by: Isaac --- acceptance/acceptance_test.go | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 659f46bfd4..863634cfbb 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -1289,28 +1289,37 @@ func BuildCLI(t *testing.T, buildDir, coverDir, osName, arch string) string { // Build with the FIPS toolchain so a plain `go test` produces the same FIPS // binary as `task` and the release build; otherwise acceptance/fips (which // asserts the FIPS build settings) fails outside `task`. - repoRoot := ".." - RunCommand(t, args, repoRoot, []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + readGOFIPS140(t, repoRoot)}) + version, err := gofips140Version() + require.NoError(t, err) + RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + version}) return execPath } -// readGOFIPS140 returns the GOFIPS140 version the Taskfile pins for `task` -// builds. The release pipeline pins the same value independently in -// .goreleaser.yaml. -func readGOFIPS140(t *testing.T, repoRoot string) string { - path := filepath.Join(repoRoot, "Taskfile.yml") +// gofips140Version returns the GOFIPS140 version the Taskfile pins for `task` +// builds; the release pipeline pins the same value independently in +// .goreleaser.yaml. Read once and cached, since BuildCLI runs per OS/arch and +// the value is constant within a run. The path is relative to the acceptance +// package dir, which is `go test`'s working directory. +var gofips140Version = sync.OnceValues(func() (string, error) { + path := filepath.Join("..", "Taskfile.yml") data, err := os.ReadFile(path) - require.NoError(t, err, "reading %s (acceptance tests must run with cwd=acceptance/)", path) + if err != nil { + return "", fmt.Errorf("reading %s (acceptance tests must run with cwd=acceptance/): %w", path, err) + } var taskfile struct { Env struct { GOFIPS140 string `yaml:"GOFIPS140"` } `yaml:"env"` } - require.NoError(t, yaml.Unmarshal(data, &taskfile)) - require.NotEmpty(t, taskfile.Env.GOFIPS140, "GOFIPS140 not set in Taskfile.yml") - return taskfile.Env.GOFIPS140 -} + if err := yaml.Unmarshal(data, &taskfile); err != nil { + return "", fmt.Errorf("parsing %s: %w", path, err) + } + if taskfile.Env.GOFIPS140 == "" { + return "", fmt.Errorf("GOFIPS140 not set in %s", path) + } + return taskfile.Env.GOFIPS140, nil +}) // CreateReleaseArtifacts builds release artifacts for the given OS using amd64 and arm64 architectures, // archives them into zip files, and returns the directory containing the release artifacts. From 49181032549ee489fe43a4b35ab2d8679e25774b Mon Sep 17 00:00:00 2001 From: Ilya Kuznetsov Date: Tue, 25 Aug 2026 11:24:10 +0000 Subject: [PATCH 4/4] acc: set GOFIPS140 via test env, read once in testAccept Co-authored-by: Isaac --- acceptance/acceptance_test.go | 39 ++++++++++++++--------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/acceptance/acceptance_test.go b/acceptance/acceptance_test.go index 863634cfbb..c62a0e3949 100644 --- a/acceptance/acceptance_test.go +++ b/acceptance/acceptance_test.go @@ -302,6 +302,12 @@ func testAccept(t *testing.T, inprocessMode bool, singleTest string) int { t.Logf("Writing coverage to %s", coverDir) } + // Build the CLI with the FIPS toolchain so a plain `go test` produces the + // same FIPS binary as `task` (which sets GOFIPS140 in its env) and the + // release pipeline; without it acceptance/fips fails outside `task`. The + // build below inherits os.Environ(), so setting it here is enough. + t.Setenv("GOFIPS140", readGOFIPS140(t, cwd)) + execPath := "" cliVersion := "" @@ -1286,40 +1292,27 @@ func BuildCLI(t *testing.T, buildDir, coverDir, osName, arch string) string { args = append(args, "-buildvcs=false") } - // Build with the FIPS toolchain so a plain `go test` produces the same FIPS - // binary as `task` and the release build; otherwise acceptance/fips (which - // asserts the FIPS build settings) fails outside `task`. - version, err := gofips140Version() - require.NoError(t, err) - RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch, "GOFIPS140=" + version}) + RunCommand(t, args, "..", []string{"GOOS=" + osName, "GOARCH=" + arch}) return execPath } -// gofips140Version returns the GOFIPS140 version the Taskfile pins for `task` +// readGOFIPS140 returns the GOFIPS140 version the Taskfile pins for `task` // builds; the release pipeline pins the same value independently in -// .goreleaser.yaml. Read once and cached, since BuildCLI runs per OS/arch and -// the value is constant within a run. The path is relative to the acceptance -// package dir, which is `go test`'s working directory. -var gofips140Version = sync.OnceValues(func() (string, error) { - path := filepath.Join("..", "Taskfile.yml") +// .goreleaser.yaml. +func readGOFIPS140(t *testing.T, cwd string) string { + path := filepath.Join(cwd, "..", "Taskfile.yml") data, err := os.ReadFile(path) - if err != nil { - return "", fmt.Errorf("reading %s (acceptance tests must run with cwd=acceptance/): %w", path, err) - } + require.NoError(t, err) var taskfile struct { Env struct { GOFIPS140 string `yaml:"GOFIPS140"` } `yaml:"env"` } - if err := yaml.Unmarshal(data, &taskfile); err != nil { - return "", fmt.Errorf("parsing %s: %w", path, err) - } - if taskfile.Env.GOFIPS140 == "" { - return "", fmt.Errorf("GOFIPS140 not set in %s", path) - } - return taskfile.Env.GOFIPS140, nil -}) + require.NoError(t, yaml.Unmarshal(data, &taskfile)) + require.NotEmpty(t, taskfile.Env.GOFIPS140, "GOFIPS140 not set in Taskfile.yml") + return taskfile.Env.GOFIPS140 +} // CreateReleaseArtifacts builds release artifacts for the given OS using amd64 and arm64 architectures, // archives them into zip files, and returns the directory containing the release artifacts.