Skip to content

Commit e88eaf7

Browse files
authored
fix: tool-cache does not work (browser-actions#533)
The tool-cache package does not work for the Chromium version. It works only for the server format. The chrome has a four-part version like `120.0.6099.109`, and the tool-cache does not retrieve the cached version. This pull request replaces the standard tool-cache package with the cache that supports the chrome version format, four-part, release channel name, snapshot number, and `latest`. Close browser-actions#504
1 parent 20e34f7 commit e88eaf7

12 files changed

+596
-303
lines changed

__test__/cache.test.ts

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { cacheDir, find } from "../src/cache";
2+
import * as fs from "fs";
3+
import * as os from "os";
4+
import * as path from "path";
5+
6+
const mkdir = (dir: string) => fs.promises.mkdir(dir, { recursive: true });
7+
const touch = (file: string) => fs.promises.writeFile(file, "");
8+
const expectDir = async (dir: string) =>
9+
expect((await fs.promises.stat(dir)).isDirectory()).toBeTruthy();
10+
const expectFile = async (file: string) =>
11+
expect((await fs.promises.stat(file)).isFile()).toBeTruthy();
12+
13+
describe("find", () => {
14+
let tempToolCacheDir: string;
15+
beforeEach(async () => {
16+
tempToolCacheDir = await fs.promises.mkdtemp(
17+
path.join(os.tmpdir(), "setup-chrome-"),
18+
);
19+
process.env.RUNNER_TOOL_CACHE = tempToolCacheDir;
20+
});
21+
22+
afterEach(async () => {
23+
await fs.promises.rm(tempToolCacheDir, { recursive: true });
24+
});
25+
26+
describe("when several versions are cached", () => {
27+
beforeEach(async () => {
28+
const caches = [
29+
["100.0.1.0", "x64"],
30+
["100.1.0.0", "x64"],
31+
["100.1.1.0", "x64"],
32+
["100.2.0.0", "x64"],
33+
["latest", "x64"],
34+
["canary", "x64"],
35+
["123456", "x64"],
36+
["200000", "x64"],
37+
["300000", "arm64"],
38+
];
39+
for (const [version, arch] of caches) {
40+
const dir = path.join(
41+
tempToolCacheDir,
42+
"setup-chrome",
43+
"chrome",
44+
version,
45+
arch,
46+
);
47+
await mkdir(dir);
48+
await touch(`${dir}.complete`);
49+
}
50+
});
51+
52+
test.each`
53+
version | arch | subdir
54+
${"100.0.1.0"} | ${"x64"} | ${"100.0.1.0/x64"}
55+
${"100.1"} | ${"x64"} | ${"100.1.1.0/x64"}
56+
${"100"} | ${"x64"} | ${"100.2.0.0/x64"}
57+
${"latest"} | ${"x64"} | ${"latest/x64"}
58+
${"canary"} | ${"x64"} | ${"canary/x64"}
59+
${"123456"} | ${"x64"} | ${"123456/x64"}
60+
${"300000"} | ${"arm64"} | ${"300000/arm64"}
61+
${"200"} | ${"x64"} | ${undefined}
62+
${"stable"} | ${"x64"} | ${undefined}
63+
`("finds a tool in the cache", async ({ version, arch, subdir }) => {
64+
expect(await find("chrome", version, arch)).toBe(
65+
subdir && path.join(tempToolCacheDir, "setup-chrome", "chrome", subdir),
66+
);
67+
});
68+
});
69+
70+
describe("when cache is empty", () => {
71+
test("cache is not found", async () => {
72+
expect(await find("chrome", "100", "x64")).toBeUndefined();
73+
});
74+
});
75+
76+
describe("when cache includes corrupted cache", () => {
77+
beforeEach(async () => {
78+
const dir = path.join(tempToolCacheDir, "setup-chrome", "chrome");
79+
await mkdir(path.join(dir, "100.0.0.0", "x64"));
80+
await mkdir(path.join(dir, "100.0.0.0", "x64") + ".complete");
81+
await mkdir(path.join(dir, "100.1.0.0", "x64"));
82+
await mkdir(path.join(dir, "100.1.0.0", "x64") + ".complete");
83+
await mkdir(path.join(dir, "100.2.0.0", "x64"));
84+
});
85+
86+
test("cache is not found", async () => {
87+
expect(await find("chrome", "100.2.0.0", "x64")).toBeUndefined();
88+
});
89+
90+
test("corrupted cache is ignored", async () => {
91+
expect(await find("chrome", "100", "x64")).toBe(
92+
path.join(
93+
tempToolCacheDir,
94+
"setup-chrome",
95+
"chrome",
96+
"100.1.0.0",
97+
"x64",
98+
),
99+
);
100+
});
101+
});
102+
});
103+
104+
describe("cacheDir", () => {
105+
let tempToolCacheDir: string;
106+
let workspaceDir: string;
107+
beforeEach(async () => {
108+
tempToolCacheDir = await fs.promises.mkdtemp(
109+
path.join(os.tmpdir(), "setup-chrome-"),
110+
);
111+
workspaceDir = await fs.promises.mkdtemp(
112+
path.join(os.tmpdir(), "setup-chrome-"),
113+
);
114+
process.env.RUNNER_TOOL_CACHE = tempToolCacheDir;
115+
});
116+
117+
afterEach(async () => {
118+
await fs.promises.rm(workspaceDir, { recursive: true });
119+
await fs.promises.rm(tempToolCacheDir, { recursive: true });
120+
});
121+
122+
test("saves a tool in the cache", async () => {
123+
const caches = [
124+
["100.0.0.0", "x64"],
125+
["100.1.0.0", "arm64"],
126+
["latest", "x64"],
127+
];
128+
for (const [version, arch] of caches) {
129+
const src = path.join(workspaceDir, version);
130+
await mkdir(src);
131+
await touch(path.join(src, "file"));
132+
133+
await cacheDir(src, "chrome", version, arch);
134+
}
135+
136+
const prefix = path.join(tempToolCacheDir, "setup-chrome", "chrome");
137+
await expectDir(path.join(prefix, "100.0.0.0", "x64"));
138+
await expectFile(path.join(prefix, "100.0.0.0", "x64", "file"));
139+
await expectFile(path.join(prefix, "100.0.0.0", "x64") + ".complete");
140+
await expectDir(path.join(prefix, "100.1.0.0", "arm64"));
141+
await expectFile(path.join(prefix, "100.1.0.0", "arm64", "file"));
142+
await expectFile(path.join(prefix, "100.1.0.0", "arm64") + ".complete");
143+
await expectDir(path.join(prefix, "latest", "x64"));
144+
await expectFile(path.join(prefix, "latest", "x64", "file"));
145+
});
146+
});

__test__/version.test.ts

Lines changed: 78 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,106 @@
1-
import { StaticVersion, VersionSpec } from "../src/version";
1+
import { parse, isReleaseChannelName } from "../src/version";
22

3-
describe("StaticVersion", () => {
4-
describe("constructor", () => {
5-
test("new instance", () => {
6-
const version = new StaticVersion({
7-
major: 119,
8-
minor: 0,
9-
build: 6045,
10-
patch: 123,
11-
});
12-
13-
expect(version.major).toBe(119);
14-
expect(version.minor).toBe(0);
15-
expect(version.build).toBe(6045);
16-
expect(version.patch).toBe(123);
17-
});
18-
19-
test("parse", () => {
20-
const version = new StaticVersion("119.0.6045.123");
21-
22-
expect([
23-
version.major,
24-
version.minor,
25-
version.build,
26-
version.patch,
27-
]).toEqual([119, 0, 6045, 123]);
28-
});
29-
30-
test.each([
31-
["119.0.6045.123.456"],
32-
["119.0.6045.-123"],
33-
["119.0.6045.beta"],
34-
["119.0.6045"],
35-
])("throw an error for %s", (version) => {
36-
expect(() => new StaticVersion(version)).toThrow(
37-
`Invalid version: ${version}`,
38-
);
39-
});
3+
describe("isReleaseChannelName", () => {
4+
test("return true if the version is a release channel name", () => {
5+
expect(isReleaseChannelName("stable")).toBe(true);
6+
expect(isReleaseChannelName("beta")).toBe(true);
7+
expect(isReleaseChannelName("dev")).toBe(true);
8+
expect(isReleaseChannelName("canary")).toBe(true);
9+
expect(isReleaseChannelName("latest")).toBe(false);
10+
expect(isReleaseChannelName("unknown")).toBe(false);
4011
});
12+
});
4113

42-
describe("compare", () => {
43-
test.each`
44-
a | b | equals | greaterThan | lessThan | greaterThanOrEqual | lessThanOrEqual
45-
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${true} | ${false} | ${false} | ${true} | ${true}
46-
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
47-
${"119.0.6045.123"} | ${"119.0.6045.200"} | ${false} | ${false} | ${true} | ${false} | ${true}
48-
${"119.0.6045.123"} | ${"119.0.7000.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
49-
${"119.0.6045.123"} | ${"119.0.5000.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
50-
${"119.0.6045.123"} | ${"119.1.6045.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
51-
${"119.0.6045.123"} | ${"120.0.6045.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
52-
${"119.0.6045.123"} | ${"118.0.6045.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
53-
${"119.0.6045.123"} | ${"119.0.6045.122"} | ${false} | ${true} | ${false} | ${false} | ${true}
54-
`('compare "$a" and "$b"', ({ a, b, equals, greaterThan, lessThan }) => {
55-
const v1 = new StaticVersion(a);
56-
const v2 = new StaticVersion(b);
57-
expect(v1.equals(v2)).toBe(equals);
58-
expect(v1.greaterThan(v2)).toBe(greaterThan);
59-
expect(v1.lessThan(v2)).toBe(lessThan);
60-
expect(v1.greaterThanOrEqual(v2)).toBe(greaterThan || equals);
61-
expect(v1.lessThanOrEqual(v2)).toBe(lessThan || equals);
62-
});
14+
describe("parse", () => {
15+
test.each([
16+
[
17+
"119.0.6045.123",
18+
{ type: "four-parts", major: 119, minor: 0, build: 6045, patch: 123 },
19+
],
20+
["119.0.6045", { type: "four-parts", major: 119, minor: 0, build: 6045 }],
21+
["119.0", { type: "four-parts", major: 119, minor: 0 }],
22+
["119", { type: "four-parts", major: 119 }],
23+
["119.0.6045.x", { type: "four-parts", major: 119, minor: 0, build: 6045 }],
24+
["119.0.x", { type: "four-parts", major: 119, minor: 0 }],
25+
["119.x", { type: "four-parts", major: 119 }],
26+
["latest", { type: "latest" }],
27+
["beta", { type: "channel", channel: "beta" }],
28+
["stable", { type: "channel", channel: "stable" }],
29+
["canary", { type: "channel", channel: "canary" }],
30+
["123456", { type: "snapshot", snapshot: 123456 }],
31+
])("parse %s", (version, expected) => {
32+
const v = parse(version);
33+
expect(v.value).toEqual(expected);
6334
});
6435

65-
describe("toString", () => {
66-
test("return stringified version", () => {
67-
const v = new StaticVersion("119.0.6045.123");
68-
expect(v.toString()).toBe("119.0.6045.123");
69-
});
36+
test.each([
37+
["119.0.6045.beta"],
38+
["119.0.x.123"],
39+
["x"],
40+
["119.0.6045.123.456"],
41+
["119.0.6045.-123"],
42+
[""],
43+
["invalid"],
44+
])("throw an error for %s", (version) => {
45+
expect(() => parse(version)).toThrow(`Invalid version: ${version}`);
7046
});
7147
});
7248

7349
describe("VersionSpec", () => {
74-
describe("constructor", () => {
75-
test("new instance", () => {
76-
const version = new VersionSpec({
77-
major: 119,
78-
minor: 0,
79-
build: 6045,
80-
patch: 123,
81-
});
82-
83-
expect(version.major).toBe(119);
84-
expect(version.minor).toBe(0);
85-
expect(version.build).toBe(6045);
86-
expect(version.patch).toBe(123);
87-
});
88-
89-
test.each([
90-
["119.0.6045.123", [119, 0, 6045, 123]],
91-
["119.0.6045", [119, 0, 6045]],
92-
["119.0", [119, 0]],
93-
["119", [119]],
94-
["119.0.6045.x", [119, 0, 6045]],
95-
["119.0.x", [119, 0]],
96-
["119.x", [119]],
97-
])("parse %s", (version, expected) => {
98-
const v = new VersionSpec(version);
99-
expect([v.major, v.minor, v.build, v.patch]).toEqual(expected);
100-
});
101-
102-
test.each([
103-
["119.0.6045.beta"],
104-
["119.0.x.123"],
105-
["x"],
106-
["119.0.6045.123.456"],
107-
["119.0.6045.-123"],
108-
[""],
109-
])("throw an error for %s", (version) => {
110-
expect(() => new VersionSpec(version)).toThrow(
111-
`Invalid version: ${version}`,
112-
);
113-
});
114-
});
115-
11650
describe("toString", () => {
11751
test.each([
11852
["119.0.6045.123", "119.0.6045.123"],
11953
["119", "119"],
120-
])("return %s for %s", (expected, version) => {
121-
const v = new VersionSpec(version);
54+
["latest", "latest"],
55+
["123456", "123456"],
56+
])("return %s for %s", (spec, expected) => {
57+
const v = parse(spec);
12258
expect(v.toString()).toBe(expected);
12359
});
12460
});
12561

12662
describe("satisfies", () => {
12763
test.each`
128-
spec | version | satisfies
64+
spec | target | satisfies
12965
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${true}
13066
${"119.0.6045"} | ${"119.0.6045.123"} | ${true}
13167
${"119"} | ${"119.0.6045.123"} | ${true}
13268
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${false}
13369
${"119.0.6000"} | ${"119.0.6045.100"} | ${false}
13470
${"120"} | ${"119.0.6045.100"} | ${false}
135-
`("return if $spec satisfies $version", ({ spec, version, satisfies }) => {
136-
const s = new VersionSpec(spec);
137-
const v = new StaticVersion(version);
138-
expect(s.satisfies(v)).toBe(satisfies);
71+
${"latest"} | ${"119.0.6045.100"} | ${false}
72+
${"latest"} | ${"latest"} | ${true}
73+
${"123456"} | ${"123456"} | ${true}
74+
${"123456"} | ${"123457"} | ${false}
75+
`("return if $spec satisfies $target", ({ spec, target, satisfies }) => {
76+
const v = parse(spec);
77+
expect(v.satisfies(target)).toBe(satisfies);
78+
});
79+
});
80+
81+
describe("compare", () => {
82+
test.each`
83+
a | b | gt | lt
84+
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${false} | ${false}
85+
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${true} | ${false}
86+
${"119.0.6045.123"} | ${"119.0.6045.200"} | ${false} | ${true}
87+
${"119.0.6045.123"} | ${"119.0.7000.100"} | ${false} | ${true}
88+
${"119.0.6045.123"} | ${"119.0.5000.100"} | ${true} | ${false}
89+
${"119.0.6045.123"} | ${"119.1.6045.100"} | ${false} | ${true}
90+
${"119.0.6045.123"} | ${"120.0.6045.100"} | ${false} | ${true}
91+
${"119.0.6045.123"} | ${"118.0.6045.100"} | ${true} | ${false}
92+
${"119.0.6045.123"} | ${"119.0.6045.122"} | ${true} | ${false}
93+
${"119"} | ${"119.0.6045.123"} | ${false} | ${false}
94+
${"123456"} | ${"123456"} | ${false} | ${false}
95+
${"123456"} | ${"123457"} | ${false} | ${true}
96+
${"latest"} | ${"latest"} | ${false} | ${false}
97+
${"latest"} | ${"stable"} | ${false} | ${false}
98+
${"119.0.6045.123"} | ${"latest"} | ${false} | ${false}
99+
`('compare "$a" and "$b"', ({ a, b, gt, lt }) => {
100+
const v1 = parse(a);
101+
102+
expect(v1.gt(b)).toBe(gt);
103+
expect(v1.lt(b)).toBe(lt);
139104
});
140105
});
141106
});

0 commit comments

Comments
 (0)