Skip to content

Commit

Permalink
Capture stderr from extracting .tar.zst
Browse files Browse the repository at this point in the history
  • Loading branch information
henrymercer committed Oct 2, 2024
1 parent 1aa7f6f commit 3da852e
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 28 deletions.
12 changes: 8 additions & 4 deletions lib/setup-codeql.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/setup-codeql.js.map

Large diffs are not rendered by default.

66 changes: 56 additions & 10 deletions lib/tar.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion lib/tar.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 13 additions & 2 deletions src/setup-codeql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { default as deepEqual } from "fast-deep-equal";
import * as semver from "semver";
import { v4 as uuidV4 } from "uuid";

import { isRunningLocalAction } from "./actions-util";
import { CommandInvocationError, isRunningLocalAction } from "./actions-util";
import * as api from "./api-client";
// Note: defaults.json is referenced from the CodeQL Action sync tool and the Actions runner image
// creation scripts. Ensure that any changes to the format of this file are compatible with both of
Expand Down Expand Up @@ -497,6 +497,7 @@ export const downloadCodeQL = async function (
maybeBundleVersion: string | undefined,
maybeCliVersion: string | undefined,
apiDetails: api.GitHubApiDetails,
tarVersion: tar.TarVersion | undefined,
tempDir: string,
logger: Logger,
): Promise<{
Expand Down Expand Up @@ -554,6 +555,7 @@ export const downloadCodeQL = async function (
const extractedBundlePath = await tar.extract(
archivedBundlePath,
compressionMethod,
tarVersion,
);
const extractionDurationMs = Math.round(performance.now() - extractionStart);
logger.debug(
Expand Down Expand Up @@ -700,6 +702,10 @@ export async function setupCodeQLBundle(
);
} catch (e) {
zstdFailureReason = util.getErrorMessage(e) || "unknown error";
if (e instanceof CommandInvocationError) {
zstdFailureReason += ` Full error: ${e.stderr}`;
logger.debug(`Invocation output the following to stderr: ${e.stderr}`);
}
logger.warning(
`Failed to set up CodeQL tools with zstd. Falling back to gzipped version. Error: ${util.getErrorMessage(
e,
Expand Down Expand Up @@ -755,7 +761,11 @@ async function setupCodeQLBundleWithCompressionMethod(
const compressionMethod = tar.inferCompressionMethod(
source.codeqlTarPath,
);
codeqlFolder = await tar.extract(source.codeqlTarPath, compressionMethod);
codeqlFolder = await tar.extract(
source.codeqlTarPath,
compressionMethod,
zstdAvailability.version,
);
toolsSource = ToolsSource.Local;
break;
}
Expand All @@ -770,6 +780,7 @@ async function setupCodeQLBundleWithCompressionMethod(
source.bundleVersion,
source.cliVersion,
apiDetails,
zstdAvailability.version,
tempDir,
logger,
);
Expand Down
78 changes: 68 additions & 10 deletions src/tar.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import * as fs from "fs";
import path from "path";

import { ToolRunner } from "@actions/exec/lib/toolrunner";
import * as toolcache from "@actions/tool-cache";
import { safeWhich } from "@chrisgavin/safe-which";
import { v4 as uuidV4 } from "uuid";

import { getTemporaryDirectory, runTool } from "./actions-util";
import { Logger } from "./logging";
import { assertNever } from "./util";

Expand Down Expand Up @@ -84,24 +89,77 @@ export async function isZstdAvailable(
export type CompressionMethod = "gzip" | "zstd";

export async function extract(
path: string,
tarPath: string,
compressionMethod: CompressionMethod,
tarVersion: TarVersion | undefined,
): Promise<string> {
switch (compressionMethod) {
case "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.
return await toolcache.extractTar(path);
// Defensively continue to call the toolcache API as requesting a gzipped
// bundle may be a fallback option.
return await toolcache.extractTar(tarPath);
case "zstd":
// By specifying only the "x" flag, we ask tar to autodetect the
// compression method.
return await toolcache.extractTar(path, undefined, "x");
if (!tarVersion) {
throw new Error(
"Could not determine tar version, which is required to extract a Zstandard archive.",
);
}
return await extractTarZst(tarPath, tarVersion);
}
}

/**
* Extract a compressed tar archive
*
* @param file path to the tar
* @param dest destination directory. Optional.
* @returns path to the destination directory
*/
export async function extractTarZst(
file: string,
tarVersion: TarVersion,
): Promise<string> {
if (!file) {
throw new Error("parameter 'file' is required");
}

// Create dest
const dest = await createExtractFolder();

// Initialize args
const args = ["-x", "-v"];

let destArg = dest;
let fileArg = file;
if (process.platform === "win32" && tarVersion.type === "gnu") {
args.push("--force-local");
destArg = dest.replace(/\\/g, "/");

// Technically only the dest needs to have `/` but for aesthetic consistency
// convert slashes in the file arg too.
fileArg = file.replace(/\\/g, "/");
}

if (tarVersion.type === "gnu") {
// Suppress warnings when using GNU tar to extract archives created by BSD tar
args.push("--warning=no-unknown-keyword");
args.push("--overwrite");
}

args.push("-C", destArg, "-f", fileArg);
await runTool(`tar`, args);

return dest;
}

async function createExtractFolder(): Promise<string> {
const dest = path.join(getTemporaryDirectory(), uuidV4());
fs.mkdirSync(dest, { recursive: true });
return dest;
}

export function inferCompressionMethod(path: string): CompressionMethod {
if (path.endsWith(".tar.gz")) {
export function inferCompressionMethod(tarPath: string): CompressionMethod {
if (tarPath.endsWith(".tar.gz")) {
return "gzip";
}
return "zstd";
Expand Down

0 comments on commit 3da852e

Please sign in to comment.