-
Notifications
You must be signed in to change notification settings - Fork 4
/
setup-binary.ts
131 lines (106 loc) · 3.6 KB
/
setup-binary.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
import * as core from "@actions/core";
import * as hc from "@hashicorp/js-releases";
import * as io from "@actions/io";
import * as cache from "@actions/tool-cache";
import * as semver from "semver";
import os from "os";
import cp from "child_process";
import path from "path";
import { ok } from "assert";
export async function setupBinary(binaryName: string, version: string) {
let userAgent = `setup-${binaryName} (GitHub Actions)`;
let binaryPath = await fetchBinary(binaryName, version, userAgent);
core.addPath(binaryPath);
core.info(`${binaryName}:${version} added to path`);
let binary = await io.which(binaryName);
let binaryVersion = (cp.execSync(`${binary} version`) || "").toString();
core.setOutput("version", parseVersion(binaryVersion));
}
async function fetchBinary(
binaryName: string,
version: string,
userAgent: string,
): Promise<string> {
const osPlatform = getPlatform();
const osArch = getArch();
const tmpDir = getTempDir();
let binaryPath: string;
core.debug(`Finding release that matches ${version}.`);
const isValidVersion = semver.validRange(version);
if (!isValidVersion && version !== "latest") {
throw new Error(
"Invalid version, only valid SemVer versions or 'latest' are allowed",
);
}
let release = await hc.getRelease(binaryName, version, userAgent);
const nameAndVersion = binaryName + ` ` + version;
const nameAndPlatform = binaryName + `_${osPlatform}`;
core.debug(`Found ${nameAndVersion}.`);
core.debug(`Checking cache for ${nameAndVersion}.`);
core.debug(`Cache binary: ${nameAndPlatform}`);
binaryPath = cache.find(nameAndPlatform, version);
if (binaryPath) {
core.debug(`Found ${nameAndVersion} in cache at ${binaryPath}.`);
return binaryPath;
}
core.debug(`${nameAndVersion} not found in cache.`);
core.debug(`Getting download URL for ${nameAndVersion}.`);
let build = release.getBuild(osPlatform, osArch);
core.debug(`Download URL: ${build.url}`);
core.info(`Downloading ${build.filename}.`);
let downloadPath = path.join(tmpDir, build.filename);
core.debug(`Download path: ${downloadPath}`);
await release.download(build.url, downloadPath, userAgent);
core.debug(`Verifying ${build.filename}.`);
await release.verify(downloadPath, build.filename);
core.debug(`Extracting ${build.filename}.`);
const extractedPath = await cache.extractZip(downloadPath);
core.debug(`Extracted path: ${extractedPath}`);
binaryPath = await cache.cacheDir(extractedPath, nameAndPlatform, version);
core.debug(`Cached ${nameAndVersion} at ${binaryPath}.`);
return binaryPath;
}
export function parseVersion(version: string): string {
return version.split("\n")[0].split(" ")[1];
}
function getTempDir(): string {
const tmpDir = process.env["RUNNER_TEMP"] || "";
ok(tmpDir, "Expected RUNNER_TEMP to be defined");
return tmpDir;
}
function getPlatform(): string {
const platform = os.platform();
switch (platform) {
case "darwin":
return "darwin";
case "freebsd":
return "freebsd";
case "linux":
return "linux";
case "openbsd":
return "openbsd";
case "win32":
return "windows";
default:
throw new Error(`Unsupported operating system platform: ${platform}`);
}
}
function getArch(): string {
const arch = os.arch();
switch (arch) {
case "arm":
return "arm";
case "arm64":
return "arm64";
case "x32":
return "386";
case "x64":
return "amd64";
default:
throw new Error(`Unsupported operating system architecture: ${arch}`);
}
}