Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions __tests__/gpg.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as exec from "@actions/exec";
import { setupKeys, verify, refreshKeys } from "../src/gpg";

jest.mock("@actions/exec");

const mockExec = exec.exec as jest.Mock;

describe("gpg", () => {
afterEach(() => {
mockExec.mockClear();
});

it("uses the first responding keyserver in the pool", async () => {
mockExec.mockImplementation(() => Promise.resolve(0));
await refreshKeys();
expect(mockExec).toBeCalledTimes(1);
});

it("uses the next keyserver in the pool if the previous fails", async () => {
const failingServers = 3;
let testedServers = 0;

mockExec.mockImplementation(() => {
testedServers++;
if (testedServers >= failingServers) {
return Promise.resolve(0);
} else {
return Promise.resolve(1);
}
});

await refreshKeys();
expect(mockExec).toBeCalledTimes(3);
});

it("throws an error if all servers in the pool fails", async () => {
mockExec.mockImplementation(() => Promise.resolve(1));

try {
await refreshKeys();
} catch (e) {
expect(e).toEqual(
new Error("Failed to refresh keys from any server in the pool.")
);
}
});
});
53 changes: 53 additions & 0 deletions src/gpg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { exec } from "@actions/exec";
import * as core from "@actions/core";
import * as toolCache from "@actions/tool-cache";

export async function setupKeys() {
core.debug("Fetching verification keys");
let path = await toolCache.downloadTool(
"https://swift.org/keys/all-keys.asc"
);

core.debug("Importing verification keys");
await exec(`gpg --import "${path}"`);

core.debug("Refreshing keys");
await refreshKeys();
}

export async function verify(signaturePath: string, packagePath: string) {
core.debug("Verifying signature");
await exec("gpg", ["--verify", signaturePath, packagePath]);
}

export async function refreshKeys() {
const pool = [
"hkp://pool.sks-keyservers.net",
"ha.pool.sks-keyservers.net",
"keyserver.ubuntu.com",
"hkp://keyserver.ubuntu.com",
"pgp.mit.edu",
];

for (const server of pool) {
core.debug(`Refreshing keys from ${server}`);
if (await refreshKeysFromServer(server)) {
core.debug(`Refresh successful`);
return;
}
core.debug(`Refresh failed`);
}

throw new Error("Failed to refresh keys from any server in the pool.");
}

function refreshKeysFromServer(server: string): Promise<boolean> {
return exec(`gpg --keyserver ${server} --refresh-keys Swift`)
.then((code) => code === 0)
.catch((error) => {
core.warning(
`An error occurred when trying to refresh keys from ${server}: ${error}`
);
return false;
});
}
19 changes: 1 addition & 18 deletions src/linux-install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as core from "@actions/core";
import * as toolCache from "@actions/tool-cache";
import { System } from "./os";
import { swiftPackage, Package } from "./swift-versions";
import { setupKeys, verify } from "./gpg";

export async function install(version: string, system: System) {
if (os.platform() !== "linux") {
Expand Down Expand Up @@ -66,21 +67,3 @@ async function unpack(
core.debug("Package cached");
return cachedPath;
}

async function setupKeys() {
core.debug("Fetching verification keys");
let path = await toolCache.downloadTool(
"https://swift.org/keys/all-keys.asc"
);
core.debug("Importing verification keys");
await exec(`gpg --import "${path}"`);
core.debug("Refreshing keys");
await exec(
"gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift"
);
}

async function verify(signaturePath: string, packagePath: string) {
core.debug("Verifying signature");
await exec("gpg", ["--verify", signaturePath, packagePath]);
}