import { exec } from "@actions/exec"; import * as io from "@actions/io"; import { existsSync, writeFileSync } from "fs"; import * as path from "path"; import { CacheFilename, ManifestFilename } from "./constants"; async function getTarPath(): Promise { // Explicitly use BSD Tar on Windows const IS_WINDOWS = process.platform === "win32"; if (IS_WINDOWS) { const systemTar = `${process.env["windir"]}\\System32\\tar.exe`; if (existsSync(systemTar)) { return systemTar; } } return await io.which("tar", true); } async function execTar(args: string[], cwd?: string): Promise { try { await exec(`"${await getTarPath()}"`, args, { cwd: cwd }); } catch (error) { const IS_WINDOWS = process.platform === "win32"; if (IS_WINDOWS) { throw new Error( `Tar failed with error: ${error?.message}. Ensure BSD tar is installed and on the PATH.` ); } throw new Error(`Tar failed with error: ${error?.message}`); } } function getWorkingDirectory(): string { return process.env["GITHUB_WORKSPACE"] ?? process.cwd(); } export async function extractTar(archivePath: string): Promise { // Create directory to extract tar into const workingDirectory = getWorkingDirectory(); await io.mkdirP(workingDirectory); const args = [ "--use-compress-program", "zstd --long=31 -d", "-xf", archivePath, "-P", "-C", workingDirectory ]; await execTar(args); } export async function createTar( archiveFolder: string, sourceDirectories: string[] ): Promise { // Write source directories to manifest.txt to avoid command length limits writeFileSync( path.join(archiveFolder, ManifestFilename), sourceDirectories.join("\n") ); const workingDirectory = getWorkingDirectory(); const args = [ "--use-compress-program", "zstd -T0 --long=31", "-cf", CacheFilename, "-C", workingDirectory, "--files-from", ManifestFilename ]; await execTar(args, archiveFolder); }