Skip to content

Commit f794819

Browse files
authored
Merge pull request #79 from fwal/keypool
Use a pool of gpg key servers
2 parents c8d751c + 3937e50 commit f794819

File tree

3 files changed

+101
-18
lines changed

3 files changed

+101
-18
lines changed

__tests__/gpg.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import * as exec from "@actions/exec";
2+
import { setupKeys, verify, refreshKeys } from "../src/gpg";
3+
4+
jest.mock("@actions/exec");
5+
6+
const mockExec = exec.exec as jest.Mock;
7+
8+
describe("gpg", () => {
9+
afterEach(() => {
10+
mockExec.mockClear();
11+
});
12+
13+
it("uses the first responding keyserver in the pool", async () => {
14+
mockExec.mockImplementation(() => Promise.resolve(0));
15+
await refreshKeys();
16+
expect(mockExec).toBeCalledTimes(1);
17+
});
18+
19+
it("uses the next keyserver in the pool if the previous fails", async () => {
20+
const failingServers = 3;
21+
let testedServers = 0;
22+
23+
mockExec.mockImplementation(() => {
24+
testedServers++;
25+
if (testedServers >= failingServers) {
26+
return Promise.resolve(0);
27+
} else {
28+
return Promise.resolve(1);
29+
}
30+
});
31+
32+
await refreshKeys();
33+
expect(mockExec).toBeCalledTimes(3);
34+
});
35+
36+
it("throws an error if all servers in the pool fails", async () => {
37+
mockExec.mockImplementation(() => Promise.resolve(1));
38+
39+
try {
40+
await refreshKeys();
41+
} catch (e) {
42+
expect(e).toEqual(
43+
new Error("Failed to refresh keys from any server in the pool.")
44+
);
45+
}
46+
});
47+
});

src/gpg.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { exec } from "@actions/exec";
2+
import * as core from "@actions/core";
3+
import * as toolCache from "@actions/tool-cache";
4+
5+
export async function setupKeys() {
6+
core.debug("Fetching verification keys");
7+
let path = await toolCache.downloadTool(
8+
"https://swift.org/keys/all-keys.asc"
9+
);
10+
11+
core.debug("Importing verification keys");
12+
await exec(`gpg --import "${path}"`);
13+
14+
core.debug("Refreshing keys");
15+
await refreshKeys();
16+
}
17+
18+
export async function verify(signaturePath: string, packagePath: string) {
19+
core.debug("Verifying signature");
20+
await exec("gpg", ["--verify", signaturePath, packagePath]);
21+
}
22+
23+
export async function refreshKeys() {
24+
const pool = [
25+
"hkp://pool.sks-keyservers.net",
26+
"ha.pool.sks-keyservers.net",
27+
"keyserver.ubuntu.com",
28+
"hkp://keyserver.ubuntu.com",
29+
"pgp.mit.edu",
30+
];
31+
32+
for (const server of pool) {
33+
core.debug(`Refreshing keys from ${server}`);
34+
if (await refreshKeysFromServer(server)) {
35+
core.debug(`Refresh successful`);
36+
return;
37+
}
38+
core.debug(`Refresh failed`);
39+
}
40+
41+
throw new Error("Failed to refresh keys from any server in the pool.");
42+
}
43+
44+
function refreshKeysFromServer(server: string): Promise<boolean> {
45+
return exec(`gpg --keyserver ${server} --refresh-keys Swift`)
46+
.then((code) => code === 0)
47+
.catch((error) => {
48+
core.warning(
49+
`An error occurred when trying to refresh keys from ${server}: ${error}`
50+
);
51+
return false;
52+
});
53+
}

src/linux-install.ts

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as core from "@actions/core";
55
import * as toolCache from "@actions/tool-cache";
66
import { System } from "./os";
77
import { swiftPackage, Package } from "./swift-versions";
8+
import { setupKeys, verify } from "./gpg";
89

910
export async function install(version: string, system: System) {
1011
if (os.platform() !== "linux") {
@@ -66,21 +67,3 @@ async function unpack(
6667
core.debug("Package cached");
6768
return cachedPath;
6869
}
69-
70-
async function setupKeys() {
71-
core.debug("Fetching verification keys");
72-
let path = await toolCache.downloadTool(
73-
"https://swift.org/keys/all-keys.asc"
74-
);
75-
core.debug("Importing verification keys");
76-
await exec(`gpg --import "${path}"`);
77-
core.debug("Refreshing keys");
78-
await exec(
79-
"gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift"
80-
);
81-
}
82-
83-
async function verify(signaturePath: string, packagePath: string) {
84-
core.debug("Verifying signature");
85-
await exec("gpg", ["--verify", signaturePath, packagePath]);
86-
}

0 commit comments

Comments
 (0)