Skip to content

Commit dc5cd4d

Browse files
Merge pull request #127 from 1Password/vzt/delete-op-cli-installer-dependency
Use op-cli-installer as local package
2 parents c96389a + b4962e1 commit dc5cd4d

25 files changed

+8431
-9805
lines changed

dist/index.js

Lines changed: 7701 additions & 9777 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 2 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
"@1password/op-js": "^0.1.11",
4444
"@actions/core": "^1.10.1",
4545
"@actions/exec": "^1.1.1",
46-
"dotenv": "^17.2.2",
47-
"op-cli-installer": "github:1Password/op-cli-installer#e6c1c758bc3339e5fe9b06255728039f688f73fa"
46+
"@actions/tool-cache": "^2.0.2",
47+
"dotenv": "^17.2.2"
4848
},
4949
"devDependencies": {
5050
"@1password/eslint-config": "^4.3.1",

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import dotenv from "dotenv";
12
import * as core from "@actions/core";
23
import { validateCli } from "@1password/op-js";
3-
import { installCliOnGithubActionRunner } from "op-cli-installer";
4-
import dotenv from "dotenv";
4+
import { installCliOnGithubActionRunner } from "./op-cli-installer";
55
import { loadSecrets, unsetPrevious, validateAuth } from "./utils";
66
import { envFilePath } from "./constants";
77

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import os from "os";
2+
3+
import * as core from "@actions/core";
4+
import * as tc from "@actions/tool-cache";
5+
6+
export type SupportedPlatform = Extract<
7+
NodeJS.Platform,
8+
"linux" | "darwin" | "win32"
9+
>;
10+
11+
// maps OS architecture names to 1Password CLI installer architecture names
12+
export const archMap: Record<string, string> = {
13+
ia32: "386",
14+
x64: "amd64",
15+
arm: "arm",
16+
arm64: "arm64",
17+
};
18+
19+
// Builds the download URL for the 1Password CLI based on the platform and version.
20+
export const cliUrlBuilder: Record<
21+
SupportedPlatform,
22+
(version: string, arch?: string) => string
23+
> = {
24+
linux: (version, arch) =>
25+
`https://cache.agilebits.com/dist/1P/op2/pkg/${version}/op_linux_${arch}_${version}.zip`,
26+
darwin: (version) =>
27+
`https://cache.agilebits.com/dist/1P/op2/pkg/${version}/op_apple_universal_${version}.pkg`,
28+
win32: (version, arch) =>
29+
`https://cache.agilebits.com/dist/1P/op2/pkg/${version}/op_windows_${arch}_${version}.zip`,
30+
};
31+
32+
export class CliInstaller {
33+
public readonly version: string;
34+
public readonly arch: string;
35+
36+
public constructor(version: string) {
37+
this.version = version;
38+
this.arch = this.getArch();
39+
}
40+
41+
public async install(url: string): Promise<void> {
42+
console.info(`Downloading 1Password CLI from: ${url}`);
43+
const downloadPath = await tc.downloadTool(url);
44+
console.info("Installing 1Password CLI");
45+
const extractedPath = await tc.extractZip(downloadPath);
46+
core.addPath(extractedPath);
47+
core.info("1Password CLI installed");
48+
}
49+
50+
private getArch(): string {
51+
const arch = archMap[os.arch()];
52+
if (!arch) {
53+
throw new Error("Unsupported architecture");
54+
}
55+
56+
return arch;
57+
}
58+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { type Installer, newCliInstaller } from "./installer";
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import os from "os";
2+
3+
import { newCliInstaller } from "./installer";
4+
import { LinuxInstaller } from "./linux";
5+
import { MacOsInstaller } from "./macos";
6+
import { WindowsInstaller } from "./windows";
7+
8+
afterEach(() => {
9+
jest.restoreAllMocks();
10+
});
11+
12+
describe("newCliInstaller", () => {
13+
const version = "1.0.0";
14+
15+
afterEach(() => {
16+
jest.resetAllMocks();
17+
});
18+
19+
it("should return LinuxInstaller for linux platform", () => {
20+
jest.spyOn(os, "platform").mockReturnValue("linux");
21+
const installer = newCliInstaller(version);
22+
expect(installer).toBeInstanceOf(LinuxInstaller);
23+
});
24+
25+
it("should return MacOsInstaller for darwin platform", () => {
26+
jest.spyOn(os, "platform").mockReturnValue("darwin");
27+
const installer = newCliInstaller(version);
28+
expect(installer).toBeInstanceOf(MacOsInstaller);
29+
});
30+
31+
it("should return WindowsInstaller for win32 platform", () => {
32+
jest.spyOn(os, "platform").mockReturnValue("win32");
33+
const installer = newCliInstaller(version);
34+
expect(installer).toBeInstanceOf(WindowsInstaller);
35+
});
36+
37+
it("should throw error for unsupported platform", () => {
38+
jest.spyOn(os, "platform").mockReturnValue("sunos");
39+
expect(() => newCliInstaller(version)).toThrow(
40+
"Unsupported platform: sunos",
41+
);
42+
});
43+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os from "os";
2+
3+
import { LinuxInstaller } from "./linux";
4+
import { MacOsInstaller } from "./macos";
5+
import { WindowsInstaller } from "./windows";
6+
7+
export interface Installer {
8+
installCli(): Promise<void>;
9+
}
10+
11+
export const newCliInstaller = (version: string): Installer => {
12+
const platform = os.platform();
13+
switch (platform) {
14+
case "linux":
15+
return new LinuxInstaller(version);
16+
case "darwin":
17+
return new MacOsInstaller(version);
18+
case "win32":
19+
return new WindowsInstaller(version);
20+
default:
21+
throw new Error(`Unsupported platform: ${platform}`);
22+
}
23+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import os from "os";
2+
3+
import {
4+
archMap,
5+
CliInstaller,
6+
cliUrlBuilder,
7+
type SupportedPlatform,
8+
} from "./cli-installer";
9+
import { LinuxInstaller } from "./linux";
10+
11+
afterEach(() => {
12+
jest.restoreAllMocks();
13+
});
14+
15+
describe("LinuxInstaller", () => {
16+
const version = "1.2.3";
17+
const arch: NodeJS.Architecture = "arm64";
18+
19+
it("should construct with given version and architecture", () => {
20+
jest.spyOn(os, "arch").mockReturnValue(arch);
21+
const installer = new LinuxInstaller(version);
22+
expect(installer.version).toEqual(version);
23+
expect(installer.arch).toEqual(archMap[arch]);
24+
});
25+
26+
it("should call install with correct URL", async () => {
27+
const installer = new LinuxInstaller(version);
28+
const installMock = jest
29+
.spyOn(CliInstaller.prototype, "install")
30+
.mockResolvedValue();
31+
32+
await installer.installCli();
33+
34+
const builder = cliUrlBuilder["linux" as SupportedPlatform];
35+
const url = builder(version, installer.arch);
36+
expect(installMock).toHaveBeenCalledWith(url);
37+
});
38+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {
2+
CliInstaller,
3+
cliUrlBuilder,
4+
type SupportedPlatform,
5+
} from "./cli-installer";
6+
import type { Installer } from "./installer";
7+
8+
export class LinuxInstaller extends CliInstaller implements Installer {
9+
private readonly platform: SupportedPlatform = "linux"; // Node.js platform identifier for Linux
10+
11+
public constructor(version: string) {
12+
super(version);
13+
}
14+
15+
public async installCli(): Promise<void> {
16+
const urlBuilder = cliUrlBuilder[this.platform];
17+
await super.install(urlBuilder(this.version, this.arch));
18+
}
19+
}

0 commit comments

Comments
 (0)