diff --git a/continuous_delivery_scripts/plugins/golang.py b/continuous_delivery_scripts/plugins/golang.py index 918ce2a..a23022f 100644 --- a/continuous_delivery_scripts/plugins/golang.py +++ b/continuous_delivery_scripts/plugins/golang.py @@ -44,7 +44,9 @@ ENVVAR_GORELEASER_GIT_TOKEN = "GITHUB_TOKEN" ENVVAR_GORELEASER_CUSTOMISED_TAG = "GORELEASER_CURRENT_TAG" ENVVAR_GO_MOD = "GO111MODULE" +ENVVAR_GO_WORK = "GOWORK" GO_MOD_ON_VALUE = "on" +GO_WORK_OFF_VALUE = "off" # go-licenses report --template receives Name, Version, LicenseURL and LicenseName for each library. # https://github.com/google/go-licenses/blob/master/README.md#reports-with-custom-templates GO_LICENSES_TEMPLATE = "{{range .}}{{.Name}}\t{{.Version}}\t{{.LicenseURL}}\t{{.LicenseName}}\n{{end}}" @@ -131,7 +133,12 @@ def _go_licence_module_directories() -> List[Path]: def _go_module_name(module_dir: Path, env: MutableMapping[str, str]) -> str: """Read the import path declared by a Go module.""" - module = json.loads(check_output(["go", "list", "-m", "-json"], cwd=module_dir, env=env, encoding="utf8")) + # `go list -m -json` emits one JSON document per main module when a go.work + # workspace is active. Disable workspace mode here so CDS always reads the + # module declared by `module_dir` rather than the whole workspace. + module_env = dict(env) + module_env[ENVVAR_GO_WORK] = GO_WORK_OFF_VALUE + module = json.loads(check_output(["go", "list", "-m", "-json"], cwd=module_dir, env=module_env, encoding="utf8")) return str(module["Path"]) diff --git a/news/20261002184611823000000.bugfix b/news/20261002184611823000000.bugfix new file mode 100644 index 0000000..32398f2 --- /dev/null +++ b/news/20261002184611823000000.bugfix @@ -0,0 +1 @@ +:bug: Fix Go workspace licence compliance checks by resolving each module path with `GOWORK=off` so multi-module repositories do not fail JSON parsing. diff --git a/tests/plugin/test_go_licensing.py b/tests/plugin/test_go_licensing.py index 20dda28..27b5fc5 100644 --- a/tests/plugin/test_go_licensing.py +++ b/tests/plugin/test_go_licensing.py @@ -101,6 +101,20 @@ def test_reports_workspace_modules(self, workspace_modules): with mock.patch.object(golang, "ROOT_DIR", root), mock.patch.object(golang, "SRC_DIR", root): self.assertEqual(golang._go_licence_module_directories(), modules) + @mock.patch.object(golang, "check_output", return_value='{"Path": "example.com/acme"}') + def test_go_module_name_disables_go_work_to_scope_metadata_to_one_module(self, check_output): + env = {"GO111MODULE": "on", "GOWORK": "auto"} + + name = golang._go_module_name(Path("module"), env) + + self.assertEqual(name, "example.com/acme") + check_output.assert_called_once_with( + ["go", "list", "-m", "-json"], + cwd=Path("module"), + env={"GO111MODULE": "on", "GOWORK": "off"}, + encoding="utf8", + ) + def test_parses_licences_and_keeps_unknown_for_shared_policy(self): packages = golang._parse_go_licences( "github.com/acme/dep\tv1.2.3\thttps://github.com/acme/dep/blob/v1.2.3/LICENSE\tMIT\n"