From 74a9317c83685100ee5496f6aa552366a0f63eee Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Sat, 4 Nov 2023 01:59:25 +0000 Subject: [PATCH] fix: properly handle multi-module projects with a go.work file closes #4379 --- internal/pipe/gomod/gomod.go | 5 ++- internal/pipe/gomod/gomod_test.go | 39 +++++++++++++++++++++ www/docs/customization/verifiable_builds.md | 7 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/internal/pipe/gomod/gomod.go b/internal/pipe/gomod/gomod.go index 8d474652211..4fb99bfb901 100644 --- a/internal/pipe/gomod/gomod.go +++ b/internal/pipe/gomod/gomod.go @@ -48,6 +48,9 @@ func (Pipe) Run(ctx *context.Context) error { return fmt.Errorf("failed to get module path: %w: %s", err, string(out)) } - ctx.ModulePath = result + // Splits and use the first line in case a `go.work` file exists with multiple modules. + // The first module is/should be `.` in the `go.work` file, so this should be correct. + // Running `go work sync` also always puts `.` as the first line in `use`. + ctx.ModulePath = strings.Split(result, "\n")[0] return nil } diff --git a/internal/pipe/gomod/gomod_test.go b/internal/pipe/gomod/gomod_test.go index f6c59d2ea03..61e2f87af0a 100644 --- a/internal/pipe/gomod/gomod_test.go +++ b/internal/pipe/gomod/gomod_test.go @@ -2,7 +2,9 @@ package gomod import ( "os" + "os/exec" "path/filepath" + "strings" "testing" "github.com/goreleaser/goreleaser/internal/testctx" @@ -18,6 +20,43 @@ func TestRun(t *testing.T) { require.Equal(t, "github.com/goreleaser/goreleaser", ctx.ModulePath) } +func TestRunGoWork(t *testing.T) { + dir := testlib.Mktmp(t) + require.NoError(t, os.WriteFile( + filepath.Join(dir, "main.go"), + []byte("package main\nfunc main() {println(0)}"), + 0o666, + )) + require.NoError(t, os.WriteFile( + filepath.Join(dir, "go.mod"), + []byte("module a"), + 0o666, + )) + require.NoError(t, os.Mkdir(filepath.Join(dir, "b"), 0o755)) + require.NoError(t, os.WriteFile( + filepath.Join(dir, "b", "main.go"), + []byte("package main\nfunc main() {println(1)}"), + 0o666, + )) + require.NoError(t, os.WriteFile( + filepath.Join(dir, "b", "go.mod"), + []byte("module a/b"), + 0o666, + )) + require.NoError(t, os.WriteFile( + filepath.Join(dir, "go.work"), + []byte("use (\n\t.\n\tb\n)"), + 0o666, + )) + out, err := exec.Command("go", "list", "-m").CombinedOutput() + require.NoError(t, err) + require.Equal(t, "a\na/b", strings.TrimSpace(string(out))) + ctx := testctx.New() + require.NoError(t, Pipe{}.Default(ctx)) + require.NoError(t, Pipe{}.Run(ctx)) + require.Equal(t, "a", ctx.ModulePath) +} + func TestRunCustomMod(t *testing.T) { ctx := testctx.NewWithCfg(config.Project{ GoMod: config.GoMod{ diff --git a/www/docs/customization/verifiable_builds.md b/www/docs/customization/verifiable_builds.md index fea3753d022..a2e7c9fc928 100644 --- a/www/docs/customization/verifiable_builds.md +++ b/www/docs/customization/verifiable_builds.md @@ -40,11 +40,18 @@ gomod: ``` !!! tip + You can use `debug.ReadBuildInfo()` to get the version/checksum/dependencies of the module. !!! warning + VCS Info will not be embedded in the binary, as in practice it is not being built from the source, but from the Go Mod Proxy. +!!! warning + + If you have a `go.work` file, make sure to run `go work sync`, so the main + module (`.`) is the first line inside the `use` block. + [vgo]: https://research.swtch.com/vgo-repro