Only try zstd for specified version ranges of tar
This commit is contained in:
parent
cf64c3e3a3
commit
ffa1b05b27
6 changed files with 201 additions and 48 deletions
19
lib/setup-codeql.js
generated
19
lib/setup-codeql.js
generated
|
|
@ -48,6 +48,7 @@ const api = __importStar(require("./api-client"));
|
|||
// creation scripts. Ensure that any changes to the format of this file are compatible with both of
|
||||
// these dependents.
|
||||
const defaults = __importStar(require("./defaults.json"));
|
||||
const tar = __importStar(require("./tar"));
|
||||
const util = __importStar(require("./util"));
|
||||
const util_1 = require("./util");
|
||||
var ToolsSource;
|
||||
|
|
@ -397,7 +398,7 @@ const downloadCodeQL = async function (codeqlURL, maybeBundleVersion, maybeCliVe
|
|||
logger.debug(`Finished downloading CodeQL bundle to ${archivedBundlePath} (${downloadDurationMs} ms).`);
|
||||
logger.debug("Extracting CodeQL bundle.");
|
||||
const extractionStart = perf_hooks_1.performance.now();
|
||||
const { extractedBundlePath, compressionMethod } = await extractBundle(archivedBundlePath);
|
||||
const { compressionMethod, outputPath: extractedBundlePath } = await tar.extract(archivedBundlePath);
|
||||
const extractionDurationMs = Math.round(perf_hooks_1.performance.now() - extractionStart);
|
||||
logger.debug(`Finished extracting CodeQL bundle to ${extractedBundlePath} (${extractionDurationMs} ms).`);
|
||||
await cleanUpGlob(archivedBundlePath, "CodeQL bundle archive", logger);
|
||||
|
|
@ -514,20 +515,4 @@ async function cleanUpGlob(glob, name, logger) {
|
|||
logger.warning(`Failed to clean up ${name}: ${e}.`);
|
||||
}
|
||||
}
|
||||
async function extractBundle(archivedBundlePath) {
|
||||
if (archivedBundlePath.endsWith(".tar.gz")) {
|
||||
return {
|
||||
compressionMethod: "gzip",
|
||||
// While we could also ask tar to autodetect the compression method,
|
||||
// we defensively keep the gzip call identical as requesting a gzipped
|
||||
// bundle will soon be a fallback option.
|
||||
extractedBundlePath: await toolcache.extractTar(archivedBundlePath),
|
||||
};
|
||||
}
|
||||
return {
|
||||
compressionMethod: "zstd",
|
||||
// tar will autodetect the compression method
|
||||
extractedBundlePath: await toolcache.extractTar(archivedBundlePath, undefined, "x"),
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=setup-codeql.js.map
|
||||
File diff suppressed because one or more lines are too long
102
lib/tar.js
generated
Normal file
102
lib/tar.js
generated
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isZstdAvailable = isZstdAvailable;
|
||||
exports.extract = extract;
|
||||
const toolrunner_1 = require("@actions/exec/lib/toolrunner");
|
||||
const toolcache = __importStar(require("@actions/tool-cache"));
|
||||
const safe_which_1 = require("@chrisgavin/safe-which");
|
||||
const util_1 = require("./util");
|
||||
const MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3";
|
||||
const MIN_REQUIRED_GNU_TAR_VERSION = "1.31";
|
||||
async function getTarVersion() {
|
||||
const tar = await (0, safe_which_1.safeWhich)("tar");
|
||||
let stdout = "";
|
||||
const exitCode = await new toolrunner_1.ToolRunner(tar, ["--version"], {
|
||||
listeners: {
|
||||
stdout: (data) => {
|
||||
stdout += data.toString();
|
||||
},
|
||||
},
|
||||
}).exec();
|
||||
if (exitCode !== 0) {
|
||||
throw new Error("Failed to call tar --version");
|
||||
}
|
||||
// Return whether this is GNU tar or BSD tar, and the version number
|
||||
if (stdout.includes("GNU tar")) {
|
||||
const match = stdout.match(/tar \(GNU tar\) ([0-9.]+)/);
|
||||
if (!match || !match[1]) {
|
||||
throw new Error("Failed to parse output of tar --version.");
|
||||
}
|
||||
return { type: "gnu", version: match[1] };
|
||||
}
|
||||
else if (stdout.includes("bsdtar")) {
|
||||
const match = stdout.match(/bsdtar ([0-9.]+)/);
|
||||
if (!match || !match[1]) {
|
||||
throw new Error("Failed to parse output of tar --version.");
|
||||
}
|
||||
return { type: "bsd", version: match[1] };
|
||||
}
|
||||
else {
|
||||
throw new Error("Unknown tar version");
|
||||
}
|
||||
}
|
||||
async function isZstdAvailable(logger) {
|
||||
try {
|
||||
const { type, version } = await getTarVersion();
|
||||
logger.info(`Found ${type} tar version ${version}.`);
|
||||
switch (type) {
|
||||
case "gnu":
|
||||
return version >= MIN_REQUIRED_GNU_TAR_VERSION;
|
||||
case "bsd":
|
||||
return version >= MIN_REQUIRED_BSD_TAR_VERSION;
|
||||
default:
|
||||
(0, util_1.assertNever)(type);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
logger.error("Failed to determine tar version, therefore will assume zstd may not be available. " +
|
||||
`The underlying error was: ${e}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async function extract(path) {
|
||||
if (path.endsWith(".tar.gz")) {
|
||||
return {
|
||||
compressionMethod: "gzip",
|
||||
// While we could also ask tar to autodetect the compression method,
|
||||
// we defensively keep the gzip call identical as requesting a gzipped
|
||||
// bundle will soon be a fallback option.
|
||||
outputPath: await toolcache.extractTar(path),
|
||||
};
|
||||
}
|
||||
return {
|
||||
compressionMethod: "zstd",
|
||||
// By specifying only the "x" flag, we ask tar to autodetect the compression
|
||||
// method.
|
||||
outputPath: await toolcache.extractTar(path, undefined, "x"),
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=tar.js.map
|
||||
1
lib/tar.js.map
Normal file
1
lib/tar.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"tar.js","sourceRoot":"","sources":["../src/tar.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -17,6 +17,7 @@ import * as api from "./api-client";
|
|||
import * as defaults from "./defaults.json";
|
||||
import { CodeQLDefaultVersionInfo } from "./feature-flags";
|
||||
import { Logger } from "./logging";
|
||||
import * as tar from "./tar";
|
||||
import * as util from "./util";
|
||||
import { isGoodVersion } from "./util";
|
||||
|
||||
|
|
@ -461,10 +462,8 @@ export async function tryGetFallbackToolcacheVersion(
|
|||
return fallbackVersion;
|
||||
}
|
||||
|
||||
type CompressionMethod = "gzip" | "zstd";
|
||||
|
||||
export interface ToolsDownloadStatusReport {
|
||||
compressionMethod: CompressionMethod;
|
||||
compressionMethod: tar.CompressionMethod;
|
||||
downloadDurationMs: number;
|
||||
extractionDurationMs: number;
|
||||
}
|
||||
|
|
@ -529,9 +528,8 @@ export const downloadCodeQL = async function (
|
|||
|
||||
logger.debug("Extracting CodeQL bundle.");
|
||||
const extractionStart = performance.now();
|
||||
const { extractedBundlePath, compressionMethod } = await extractBundle(
|
||||
archivedBundlePath,
|
||||
);
|
||||
const { compressionMethod, outputPath: extractedBundlePath } =
|
||||
await tar.extract(archivedBundlePath);
|
||||
const extractionDurationMs = Math.round(performance.now() - extractionStart);
|
||||
logger.debug(
|
||||
`Finished extracting CodeQL bundle to ${extractedBundlePath} (${extractionDurationMs} ms).`,
|
||||
|
|
@ -706,27 +704,3 @@ async function cleanUpGlob(glob: string, name: string, logger: Logger) {
|
|||
logger.warning(`Failed to clean up ${name}: ${e}.`);
|
||||
}
|
||||
}
|
||||
|
||||
async function extractBundle(archivedBundlePath: string): Promise<{
|
||||
compressionMethod: CompressionMethod;
|
||||
extractedBundlePath: string;
|
||||
}> {
|
||||
if (archivedBundlePath.endsWith(".tar.gz")) {
|
||||
return {
|
||||
compressionMethod: "gzip",
|
||||
// While we could also ask tar to autodetect the compression method,
|
||||
// we defensively keep the gzip call identical as requesting a gzipped
|
||||
// bundle will soon be a fallback option.
|
||||
extractedBundlePath: await toolcache.extractTar(archivedBundlePath),
|
||||
};
|
||||
}
|
||||
return {
|
||||
compressionMethod: "zstd",
|
||||
// tar will autodetect the compression method
|
||||
extractedBundlePath: await toolcache.extractTar(
|
||||
archivedBundlePath,
|
||||
undefined,
|
||||
"x",
|
||||
),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
91
src/tar.ts
Normal file
91
src/tar.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { ToolRunner } from "@actions/exec/lib/toolrunner";
|
||||
import * as toolcache from "@actions/tool-cache";
|
||||
import { safeWhich } from "@chrisgavin/safe-which";
|
||||
|
||||
import { Logger } from "./logging";
|
||||
import { assertNever } from "./util";
|
||||
|
||||
const MIN_REQUIRED_BSD_TAR_VERSION = "3.4.3";
|
||||
const MIN_REQUIRED_GNU_TAR_VERSION = "1.31";
|
||||
|
||||
type TarVersion = {
|
||||
type: "gnu" | "bsd";
|
||||
version: string;
|
||||
};
|
||||
|
||||
async function getTarVersion(): Promise<TarVersion> {
|
||||
const tar = await safeWhich("tar");
|
||||
let stdout = "";
|
||||
const exitCode = await new ToolRunner(tar, ["--version"], {
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
stdout += data.toString();
|
||||
},
|
||||
},
|
||||
}).exec();
|
||||
if (exitCode !== 0) {
|
||||
throw new Error("Failed to call tar --version");
|
||||
}
|
||||
// Return whether this is GNU tar or BSD tar, and the version number
|
||||
if (stdout.includes("GNU tar")) {
|
||||
const match = stdout.match(/tar \(GNU tar\) ([0-9.]+)/);
|
||||
if (!match || !match[1]) {
|
||||
throw new Error("Failed to parse output of tar --version.");
|
||||
}
|
||||
|
||||
return { type: "gnu", version: match[1] };
|
||||
} else if (stdout.includes("bsdtar")) {
|
||||
const match = stdout.match(/bsdtar ([0-9.]+)/);
|
||||
if (!match || !match[1]) {
|
||||
throw new Error("Failed to parse output of tar --version.");
|
||||
}
|
||||
|
||||
return { type: "bsd", version: match[1] };
|
||||
} else {
|
||||
throw new Error("Unknown tar version");
|
||||
}
|
||||
}
|
||||
|
||||
export async function isZstdAvailable(logger: Logger): Promise<boolean> {
|
||||
try {
|
||||
const { type, version } = await getTarVersion();
|
||||
logger.info(`Found ${type} tar version ${version}.`);
|
||||
switch (type) {
|
||||
case "gnu":
|
||||
return version >= MIN_REQUIRED_GNU_TAR_VERSION;
|
||||
case "bsd":
|
||||
return version >= MIN_REQUIRED_BSD_TAR_VERSION;
|
||||
default:
|
||||
assertNever(type);
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
"Failed to determine tar version, therefore will assume zstd may not be available. " +
|
||||
`The underlying error was: ${e}`,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export type CompressionMethod = "gzip" | "zstd";
|
||||
|
||||
export async function extract(path: string): Promise<{
|
||||
compressionMethod: CompressionMethod;
|
||||
outputPath: string;
|
||||
}> {
|
||||
if (path.endsWith(".tar.gz")) {
|
||||
return {
|
||||
compressionMethod: "gzip",
|
||||
// While we could also ask tar to autodetect the compression method,
|
||||
// we defensively keep the gzip call identical as requesting a gzipped
|
||||
// bundle will soon be a fallback option.
|
||||
outputPath: await toolcache.extractTar(path),
|
||||
};
|
||||
}
|
||||
return {
|
||||
compressionMethod: "zstd",
|
||||
// By specifying only the "x" flag, we ask tar to autodetect the compression
|
||||
// method.
|
||||
outputPath: await toolcache.extractTar(path, undefined, "x"),
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue