Some general tidying up

This commit is contained in:
Ross MacArthur
2020-05-05 17:48:17 +02:00
parent 713cba579c
commit 7c60a53271
2 changed files with 86 additions and 45 deletions
+1 -1
View File
File diff suppressed because one or more lines are too long
+85 -44
View File
@@ -3,49 +3,72 @@ import * as tc from "@actions/tool-cache";
import * as semver from "semver"; import * as semver from "semver";
import { Octokit } from "@octokit/rest"; import { Octokit } from "@octokit/rest";
/**
* @returns {string} the Rust target specifier for the current platform.
*/
function getTarget(): string { function getTarget(): string {
if (process.arch == "x64") { const { arch, platform } = process;
if (process.platform == "linux") { if (arch == "x64") {
if (platform == "linux") {
return "x86_64-unknown-linux-musl"; return "x86_64-unknown-linux-musl";
} else if (process.platform == "darwin") { } else if (platform == "darwin") {
return "x86_64-apple-darwin"; return "x86_64-apple-darwin";
} else if (process.platform == "win32") { } else if (platform == "win32") {
return "x86_64-pc-windows-msvc"; return "x86_64-pc-windows-msvc";
} }
} }
throw new Error( throw new Error(
`failed to determine current target; arch = ${process.arch}, platform = ${process.platform}` `failed to determine current target; arch = ${arch}, platform = ${platform}`
); );
} }
class Release { /**
version: string; * Represents a tool to install from GitHub.
downloadUrl: string; */
interface Tool {
constructor(version: string, downloadUrl: string) { /** The GitHub owner (username or organization). */
this.version = version; owner: string;
this.downloadUrl = downloadUrl; /** The name of the tool and the GitHub repo name. */
} name: string;
/** A valid semantic version specifier for the tool. */
versionSpec?: string;
} }
async function getRelease( /**
versionSpec: string | null, * Represents a single release for a {@link Tool}.
target: string */
): Promise<Release | undefined> { interface Release {
/** The exact release tag. */
version: string;
/** The asset download URL. */
downloadUrl: string;
}
/**
* Fetch the latest matching release for the given tool.
*
* @param tool the tool to fetch a release for.
* @param target the Rust target specifier that should be included in the GitHub
* release asset.
*
* @returns {Promise<Release>} a single GitHub release.
*/
async function getRelease(tool: Tool, target: string): Promise<Release> {
const { owner, name, versionSpec } = tool;
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
return octokit return octokit
.paginate( .paginate(
octokit.repos.listReleases, octokit.repos.listReleases,
{ owner: "casey", repo: "just" }, { owner, repo: name },
(response, done) => { (response, done) => {
const releases = response.data const releases = response.data
.map((rel) => { .map((rel) => {
const asset = rel.assets.find((ass) => ass.name.includes(target)); const asset = rel.assets.find((ass) => ass.name.includes(target));
if (asset) { if (asset) {
return new Release( return {
rel.tag_name.replace(/^v/, ""), version: rel.tag_name.replace(/^v/, ""),
asset.browser_download_url downloadUrl: asset.browser_download_url,
); };
} }
}) })
.filter((rel) => .filter((rel) =>
@@ -59,53 +82,71 @@ async function getRelease(
return releases; return releases;
} }
) )
.then((releases) => releases.find(Boolean)); .then((releases) => {
const release = releases.find((release) => release != null);
if (release === undefined) {
throw new Error(
`no release for ${name} matching version specifier ${versionSpec}`
);
}
return release;
});
} }
async function checkOrInstallTool( /**
toolName: string, * Checks the tool cache for the tool, and if it is missing fetches it from
versionSpec: string | null, * GitHub releases.
target: string *
): Promise<string> { * @param tool the tool to check or install.
* @param target the Rust target specifier that should be included in the GitHub
* release asset.
*
* @returns the directory containing the tool binary.
*/
async function checkOrInstallTool(tool: Tool, target: string): Promise<string> {
const { name, versionSpec } = tool;
// first check if we have previously donwloaded the tool // first check if we have previously donwloaded the tool
const cache = tc.find(toolName, versionSpec || "*"); const cache = tc.find(name, versionSpec || "*");
if (cache) { if (cache) {
core.info( core.info(
`${toolName} matching version spec ${versionSpec} found in cache` `${name} matching version specifier ${versionSpec} found in cache`
); );
return cache; return cache;
} }
// find the latest release by querying GitHub API // find the latest release by querying GitHub API
const release = await getRelease(versionSpec, target); const { version, downloadUrl } = await getRelease(tool, target);
if (release === undefined) {
throw new Error(
`no release for ${toolName} matching version spec ${versionSpec}`
);
}
// download, extract and cache the tool // download, extract, and cache the tool
core.info(`Download from "${release.downloadUrl}"`); core.info(`Download from "${downloadUrl}"`);
const artifact = await tc.downloadTool(release.downloadUrl); const artifact = await tc.downloadTool(downloadUrl);
core.info("Extract downloaded archive"); core.info("Extract downloaded archive");
const dir = `./just-${release.version}`; const dir = `./${name}-${version}`;
let extractDir; let extractDir;
if (release.downloadUrl.endsWith(".zip")) { if (downloadUrl.endsWith(".zip")) {
extractDir = await tc.extractZip(artifact, dir); extractDir = await tc.extractZip(artifact, dir);
} else { } else {
extractDir = await tc.extractTar(artifact, dir); extractDir = await tc.extractTar(artifact, dir);
} }
return tc.cacheDir(extractDir, "just", release.version); return tc.cacheDir(extractDir, name, version);
} }
async function main() { async function main() {
try { try {
const version = core.getInput("just-version"); const versionSpec = core.getInput("just-version");
const target = getTarget(); const target = getTarget();
const cacheDir = await checkOrInstallTool("just", version, target); const cacheDir = await checkOrInstallTool(
{
owner: "casey",
name: "just",
versionSpec,
},
target
);
core.addPath(cacheDir); core.addPath(cacheDir);
} catch (err) { } catch (err) {
core.setFailed(err.message); core.setFailed(err.message);