1
0
Fork 0
mirror of https://code.forgejo.org/actions/setup-node synced 2025-06-23 11:48:02 +02:00

Update tool-cache we consume

This commit is contained in:
Danny McCormick 2019-06-05 11:22:12 -04:00
parent d83862c273
commit d7b6952411
18 changed files with 230 additions and 163 deletions

View file

@ -17,8 +17,44 @@ const httpm = require("typed-rest-client/HttpClient");
const semver = require("semver");
const uuidV4 = require("uuid/v4");
const exec_1 = require("@actions/exec/lib/exec");
const assert_1 = require("assert");
class HTTPError extends Error {
constructor(httpStatusCode) {
super(`Unexpected HTTP response: ${httpStatusCode}`);
this.httpStatusCode = httpStatusCode;
Object.setPrototypeOf(this, new.target.prototype);
}
}
exports.HTTPError = HTTPError;
const IS_WINDOWS = process.platform === 'win32';
const userAgent = 'actions/tool-cache';
// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this)
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
let cacheRoot = process.env['RUNNER_TOOLSDIRECTORY'] || '';
process.env['RUNNER_TEMPDIRECTORY'] = '';
process.env['RUNNER_TOOLSDIRECTORY'] = '';
// If directories not found, place them in common temp locations
if (!tempDirectory || !cacheRoot) {
let baseLocation;
if (IS_WINDOWS) {
// On windows use the USERPROFILE env variable
baseLocation = process.env['USERPROFILE'] || 'C:\\';
}
else {
if (process.platform === 'darwin') {
baseLocation = '/Users';
}
else {
baseLocation = '/home';
}
}
if (!tempDirectory) {
tempDirectory = path.join(baseLocation, 'actions', 'temp');
}
if (!cacheRoot) {
cacheRoot = path.join(baseLocation, 'actions', 'cache');
}
}
/**
* Download a tool from an url and stream it into a file
*
@ -27,14 +63,15 @@ const userAgent = 'actions/tool-cache';
*/
function downloadTool(url) {
return __awaiter(this, void 0, void 0, function* () {
// Wrap in a promise so that we can resolve from within stream callbacks
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
try {
const http = new httpm.HttpClient(userAgent, [], {
allowRetries: true,
maxRetries: 3
});
const destPath = path.join(_getAgentTemp(), uuidV4());
yield io.mkdirP(_getAgentTemp());
const destPath = path.join(tempDirectory, uuidV4());
yield io.mkdirP(tempDirectory);
core.debug(`Downloading ${url}`);
core.debug(`Downloading ${destPath}`);
if (fs.existsSync(destPath)) {
@ -42,7 +79,7 @@ function downloadTool(url) {
}
const response = yield http.get(url);
if (response.message.statusCode !== 200) {
const err = new Error(`Unexpected HTTP response: ${response.message.statusCode}`);
const err = new HTTPError(response.message.statusCode);
core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`);
throw err;
}
@ -81,45 +118,33 @@ exports.downloadTool = downloadTool;
*/
function extract7z(file, dest) {
return __awaiter(this, void 0, void 0, function* () {
if (!IS_WINDOWS) {
throw new Error('extract7z() not supported on current OS');
}
if (!file) {
throw new Error("parameter 'file' is required");
}
assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS');
assert_1.ok(file, 'parameter "file" is required');
dest = dest || (yield _createExtractFolder(dest));
const originalCwd = process.cwd();
process.chdir(dest);
const escapedScript = path
.join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1')
.replace(/'/g, "''")
.replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
];
const options = {
silent: true
};
try {
process.chdir(dest);
const escapedScript = path
.join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1')
.replace(/'/g, "''")
.replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`;
const powershellPath = yield io.which('powershell', true);
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
];
const options = {
silent: true,
listeners: {
stdout: (data) => {
process.stdout.write(data);
},
stderr: (data) => {
process.stderr.write(data);
}
}
};
yield exec_1.exec(`"${powershellPath}"`, args, options);
}
finally {
@ -162,32 +187,42 @@ function extractZip(file, dest) {
}
dest = dest || (yield _createExtractFolder(dest));
if (IS_WINDOWS) {
// build the powershell command
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
// run powershell
const powershellPath = yield io.which('powershell');
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
];
yield exec_1.exec(`"${powershellPath}"`, args);
yield extractZipWin(file, dest);
}
else {
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip');
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
yield extractZipNix(file, dest);
}
return dest;
});
}
exports.extractZip = extractZip;
function extractZipWin(file, dest) {
return __awaiter(this, void 0, void 0, function* () {
// build the powershell command
const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines
const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, '');
const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`;
// run powershell
const powershellPath = yield io.which('powershell');
const args = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
];
yield exec_1.exec(`"${powershellPath}"`, args);
});
}
function extractZipNix(file, dest) {
return __awaiter(this, void 0, void 0, function* () {
const unzipPath = path.join(__dirname, '..', 'scripts', 'externals', 'unzip');
yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest });
});
}
/**
* Caches a directory and installs it into the tool cacheDir
*
@ -276,7 +311,6 @@ function find(toolName, versionSpec, arch) {
let toolPath = '';
if (versionSpec) {
versionSpec = semver.clean(versionSpec) || '';
const cacheRoot = _getCacheRoot();
const cachePath = path.join(cacheRoot, toolName, versionSpec, arch);
core.debug(`checking cache: ${cachePath}`);
if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) {
@ -294,31 +328,15 @@ function _createExtractFolder(dest) {
return __awaiter(this, void 0, void 0, function* () {
if (!dest) {
// create a temp dir
dest = path.join(_getAgentTemp(), uuidV4());
dest = path.join(tempDirectory, uuidV4());
}
yield io.mkdirP(dest);
return dest;
});
}
function _getAgentTemp() {
// TODO - we need an actual protocol for this (this is just a placeholder)
const tempDirectory = process.env['Runner.TempDirectory'];
if (!tempDirectory) {
throw new Error('Runner.TempDirectory is not set');
}
return tempDirectory;
}
function _getCacheRoot() {
// TODO - we need an actual protocol for this (this is just a placeholder)
const cacheRoot = process.env['Runner.ToolsDirectory'];
if (!cacheRoot) {
throw new Error('Runner.ToolsDirectory is not set');
}
return cacheRoot;
}
function _createToolPath(tool, version, arch) {
return __awaiter(this, void 0, void 0, function* () {
const folderPath = path.join(_getCacheRoot(), tool, semver.clean(version) || version, arch || '');
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
core.debug(`destination ${folderPath}`);
const markerPath = `${folderPath}.complete`;
yield io.rmRF(folderPath);
@ -328,7 +346,7 @@ function _createToolPath(tool, version, arch) {
});
}
function _completeToolPath(tool, version, arch) {
const folderPath = path.join(_getCacheRoot(), tool, semver.clean(version) || version, arch || '');
const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || '');
const markerPath = `${folderPath}.complete`;
fs.writeFileSync(markerPath, '');
core.debug('finished caching tool');
@ -368,7 +386,7 @@ function _evaluateVersions(versions, versionSpec) {
function _findLocalToolVersions(toolName, arch) {
const versions = [];
arch = arch || os.arch();
const toolPath = path.join(_getCacheRoot(), toolName);
const toolPath = path.join(cacheRoot, toolName);
if (fs.existsSync(toolPath)) {
const children = fs.readdirSync(toolPath);
for (const child of children) {