Skip to content

Commit fcdc05f

Browse files
authored
fix: go-mod-validator filter errored deps (#1452)
* fix: go-mod-validator filter errored deps * fix: linting
1 parent 12206cd commit fcdc05f

5 files changed

Lines changed: 90 additions & 10 deletions

File tree

.changeset/grumpy-icons-joke.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"go-mod-validator": minor
3+
---
4+
5+
fix: filter out errored dependenies

apps/go-mod-validator/dist/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29681,7 +29681,15 @@ function lineForDependencyPathFinder() {
2968129681
};
2968229682
}
2968329683
function goModsToGoModules(goModFilePath, goMods, depPrefix) {
29684-
const goModules = goMods.map((d) => d.Replace || d).filter((d) => !d.Main && d.Path.startsWith(depPrefix)).map((d) => {
29684+
const goModules = goMods.map((d) => d.Replace || d).filter((d) => !d.Main && d.Path.startsWith(depPrefix)).filter((d) => {
29685+
if (d.Error && d.Error.Err) {
29686+
core.warning(
29687+
`Error loading module ${d.Path}: ${d.Error.Err}. This module will be skipped.`
29688+
);
29689+
return false;
29690+
}
29691+
return true;
29692+
}).map((d) => {
2968529693
const [_, owner, repo, ...subModulePathElements] = d.Path.split("/");
2968629694
const baseModule = {
2968729695
owner,

apps/go-mod-validator/src/deps.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,16 @@ export function goModsToGoModules(
292292
// `go list -m -json all` also lists the main package, avoid parsing it.
293293
// and only validate dependencies belonging to our org
294294
.filter((d) => !d.Main && d.Path.startsWith(depPrefix))
295+
// filter any modules that may have errored because they are private
296+
.filter((d) => {
297+
if (d.Error && d.Error.Err) {
298+
core.warning(
299+
`Error loading module ${d.Path}: ${d.Error.Err}. This module will be skipped.`,
300+
);
301+
return false;
302+
}
303+
return true;
304+
})
295305
.map((d: GoMod): GoModule => {
296306
// repo format github.com/smartcontractkit/chainlink
297307
const [_, owner, repo, ...subModulePathElements] = d.Path.split("/");

apps/go-mod-validator/test/deps.test.ts

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { execSync } from "child_process";
22
import { getDeps, getVersionType } from "../src/deps";
3-
import { describe, expect, it, vi, MockedObject } from "vitest";
3+
import { describe, expect, it, vi, MockedObject, beforeEach } from "vitest";
44
import * as glob from "@actions/glob";
55

66
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -23,13 +23,24 @@ vi.mock("@actions/core", async (importOriginal: any) => ({
2323
},
2424
}));
2525

26+
vi.mock("node:child_process", () => ({ execSync: vi.fn() }));
27+
vi.mock("@actions/glob", () => ({ create: vi.fn() }));
28+
2629
const mockedExecSync = vi.mocked(execSync);
27-
vi.mock("child_process");
28-
const mockedGlob = vi.mocked(glob);
29-
vi.mock("@actions/glob");
30+
const mockedCreate = vi.mocked(glob.create);
31+
32+
let getDeps: typeof import("../src/deps").getDeps;
3033
type MockedGlob = MockedObject<Awaited<ReturnType<typeof glob.create>>>;
3134

3235
describe("getDependenciesMap", () => {
36+
beforeEach(async () => {
37+
vi.resetModules(); // <- key: clears module-level caching
38+
vi.clearAllMocks();
39+
40+
// re-import AFTER resetModules so module-level singletons re-run
41+
({ getDeps } = await import("../src/deps"));
42+
});
43+
3344
it("should return a map of <go.mod files: dependencies in json>", async () => {
3445
const paths = ["/path/to/first/go.mod", "/path/to/second/go.mod"];
3546
const goList1 =
@@ -39,14 +50,17 @@ describe("getDependenciesMap", () => {
3950
const goList3 =
4051
'{"Path": "github.com/smartcontractkit/chainlink-protos/cre/go", "Version": "v1.0.0-beta"}';
4152

42-
mockedGlob.create.mockResolvedValueOnce({
53+
mockedCreate.mockResolvedValueOnce({
4354
glob: vi.fn().mockResolvedValue(paths),
4455
} as MockedGlob);
4556

4657
mockedExecSync.mockImplementationOnce(() => goList1);
4758
mockedExecSync.mockImplementationOnce(() => goList2 + "\n" + goList3);
4859

4960
const result = await getDeps("", "github.com/smartcontractkit");
61+
62+
expect(mockedExecSync).toHaveBeenCalledTimes(2);
63+
5064
expect(result).toMatchInlineSnapshot(`
5165
[
5266
{
@@ -80,18 +94,56 @@ describe("getDependenciesMap", () => {
8094
`);
8195
});
8296

97+
it("should skip dependencies with errors", async () => {
98+
const paths = ["/path/to/first/go.mod"];
99+
const goList1 =
100+
'{"Path": "github.com/smartcontractkit/go-plugin", "Version": "v0.0.0-20240208201424-b3b91517de16"}';
101+
const goList2 = `
102+
{
103+
"Path": "github.com/smartcontractkit/private-dep",
104+
"Version": "v0.0.0-20260224170222-a43bd3ff9dd5",
105+
"Error": {
106+
"Err": "github.com/smartcontractkit/private-dep@v0.0.0-20260224170222-a43bd3ff9dd5: invalid version: git ls-remote -q --end-of-options https://github.com/smartcontractkit/private-dep in /go/pkg/mod/cache/vcs/94d9727765b1ab36ed05d10c5d35ca726794e132cb25bee11cb34a7d6107b004: exit status 128:\\n\\tfatal: could not read Username for 'https://github.com': terminal prompts disabled\\nConfirm the import path was entered correctly.\\nIf this is a private repository, see https://golang.org/doc/faq#git_https for additional information."
107+
}
108+
}`;
109+
110+
mockedCreate.mockResolvedValueOnce({
111+
glob: vi.fn().mockResolvedValue(paths),
112+
} as MockedGlob);
113+
114+
mockedExecSync.mockImplementationOnce(() => goList1 + "\n" + goList2);
115+
116+
const result = await getDeps("", "github.com/smartcontractkit");
117+
118+
expect(mockedExecSync).toHaveBeenCalledTimes(1);
119+
120+
expect(result).toMatchInlineSnapshot(`
121+
[
122+
{
123+
"commitSha": "b3b91517de16",
124+
"goModFilePath": "/path/to/first/go.mod",
125+
"name": "github.com/smartcontractkit/go-plugin@v0.0.0-20240208201424-b3b91517de16",
126+
"owner": "smartcontractkit",
127+
"path": "github.com/smartcontractkit/go-plugin",
128+
"repo": "go-plugin",
129+
"version": "v0.0.0-20240208201424-b3b91517de16",
130+
},
131+
]
132+
`);
133+
});
134+
83135
it("should handle no go.mod files found", async () => {
84136
const paths: string[] = [];
85137

86-
mockedGlob.create.mockResolvedValue({
138+
mockedCreate.mockResolvedValue({
87139
glob: vi.fn().mockResolvedValue(paths),
88140
} as MockedGlob);
89141

90142
await expect(getDeps("", "")).rejects.toThrow("no go.mod files found");
91143
});
92144

93145
it("should handle glob search failure", async () => {
94-
mockedGlob.create.mockRejectedValue(new Error("Glob error"));
146+
mockedCreate.mockRejectedValue(new Error("Glob error"));
95147
await expect(getDeps("", "")).rejects.toThrow("Glob error");
96148
});
97149
});

apps/go-mod-validator/test/github.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,13 @@ describe("isGoModReferencingBranch", () => {
156156
const errMsg = "not found";
157157
mockOctokit.rest.git.getRef.mockRejectedValue(errMsg);
158158

159-
const result = isGoModReferencingBranch(mockOctokit, goMod, "main", {});
160-
expect(result).resolves.toEqual({
159+
const result = await isGoModReferencingBranch(
160+
mockOctokit,
161+
goMod,
162+
"main",
163+
{},
164+
);
165+
expect(result).toEqual({
161166
isInBranch: "unknown",
162167
commitSha: "",
163168
reason: errMsg,

0 commit comments

Comments
 (0)