mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-08-18 22:55:08 +00:00
Use install-dotnet scripts for install
This commit is contained in:
parent
6647a1deba
commit
21cbb73d4e
239
lib/installer.js
239
lib/installer.js
@ -16,229 +16,28 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|||||||
};
|
};
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
// Load tempDirectory before it gets wiped by tool-cache
|
// Load tempDirectory before it gets wiped by tool-cache
|
||||||
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
|
|
||||||
const core = __importStar(require("@actions/core"));
|
|
||||||
const exec = __importStar(require("@actions/exec"));
|
const exec = __importStar(require("@actions/exec"));
|
||||||
const io = __importStar(require("@actions/io"));
|
const io = __importStar(require("@actions/io"));
|
||||||
const tc = __importStar(require("@actions/tool-cache"));
|
|
||||||
const httpClient = require("typed-rest-client/HttpClient");
|
|
||||||
const fs_1 = require("fs");
|
const fs_1 = require("fs");
|
||||||
const os = __importStar(require("os"));
|
|
||||||
const path = __importStar(require("path"));
|
const path = __importStar(require("path"));
|
||||||
const semver = __importStar(require("semver"));
|
const semver = __importStar(require("semver"));
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
if (!tempDirectory) {
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
|
||||||
}
|
|
||||||
class DotnetCoreInstaller {
|
class DotnetCoreInstaller {
|
||||||
constructor(version) {
|
constructor(version) {
|
||||||
if (semver.valid(semver.clean(version) || '') == null) {
|
if (semver.valid(semver.clean(version) || '') == null) {
|
||||||
throw 'Implicit version not permitted';
|
throw 'Implicit version not permitted';
|
||||||
}
|
}
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.cachedToolName = 'dncs';
|
|
||||||
this.arch = 'x64';
|
|
||||||
}
|
}
|
||||||
installDotnet() {
|
installDotnet() {
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
// Check cache
|
|
||||||
let toolPath;
|
|
||||||
let osSuffixes = yield this.detectMachineOS();
|
|
||||||
let parts = osSuffixes[0].split('-');
|
|
||||||
if (parts.length > 1) {
|
|
||||||
this.arch = parts[1];
|
|
||||||
}
|
|
||||||
toolPath = this.getLocalTool();
|
|
||||||
if (!toolPath) {
|
|
||||||
// download, extract, cache
|
|
||||||
console.log('Getting a download url', this.version);
|
|
||||||
let downloadUrls = yield this.getDownloadUrls(osSuffixes, this.version);
|
|
||||||
toolPath = yield this.downloadAndInstall(downloadUrls);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log('Using cached tool');
|
|
||||||
}
|
|
||||||
// Need to set this so that .NET Core global tools find the right locations.
|
|
||||||
core.exportVariable('DOTNET_ROOT', toolPath);
|
|
||||||
// Prepend the tools path. instructs the agent to prepend for future tasks
|
|
||||||
core.addPath(toolPath);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getLocalTool() {
|
|
||||||
console.log('Checking tool cache');
|
|
||||||
return tc.find(this.cachedToolName, this.version, this.arch);
|
|
||||||
}
|
|
||||||
detectMachineOS() {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let osSuffix = [];
|
|
||||||
let output = '';
|
|
||||||
let resultCode = 0;
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
let escapedScript = path
|
|
||||||
.join(__dirname, '..', 'externals', 'get-os-platform.ps1')
|
|
||||||
.replace(/'/g, "''");
|
|
||||||
let command = `& '${escapedScript}'`;
|
|
||||||
const powershellPath = yield io.which('powershell', true);
|
|
||||||
resultCode = yield exec.exec(`"${powershellPath}"`, [
|
|
||||||
'-NoLogo',
|
|
||||||
'-Sta',
|
|
||||||
'-NoProfile',
|
|
||||||
'-NonInteractive',
|
|
||||||
'-ExecutionPolicy',
|
|
||||||
'Unrestricted',
|
|
||||||
'-Command',
|
|
||||||
command
|
|
||||||
], {
|
|
||||||
listeners: {
|
|
||||||
stdout: (data) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let scriptPath = path.join(__dirname, '..', 'externals', 'get-os-distro.sh');
|
|
||||||
fs_1.chmodSync(scriptPath, '777');
|
|
||||||
const toolPath = yield io.which(scriptPath, true);
|
|
||||||
resultCode = yield exec.exec(`"${toolPath}"`, [], {
|
|
||||||
listeners: {
|
|
||||||
stdout: (data) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (resultCode != 0) {
|
|
||||||
throw `Failed to detect os with result code ${resultCode}. Output: ${output}`;
|
|
||||||
}
|
|
||||||
let index;
|
|
||||||
if ((index = output.indexOf('Primary:')) >= 0) {
|
|
||||||
let primary = output.substr(index + 'Primary:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(primary);
|
|
||||||
}
|
|
||||||
if ((index = output.indexOf('Legacy:')) >= 0) {
|
|
||||||
let legacy = output.substr(index + 'Legacy:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(legacy);
|
|
||||||
}
|
|
||||||
if (osSuffix.length == 0) {
|
|
||||||
throw 'Could not detect platform';
|
|
||||||
}
|
|
||||||
return osSuffix;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
downloadAndInstall(downloadUrls) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let downloaded = false;
|
|
||||||
let downloadPath = '';
|
|
||||||
for (const url of downloadUrls) {
|
|
||||||
try {
|
|
||||||
downloadPath = yield tc.downloadTool(url);
|
|
||||||
downloaded = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
console.log('Could Not Download', url, JSON.stringify(error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!downloaded) {
|
|
||||||
throw 'Failed to download package';
|
|
||||||
}
|
|
||||||
// extract
|
|
||||||
console.log('Extracting Package', downloadPath);
|
|
||||||
let extPath = IS_WINDOWS
|
|
||||||
? yield tc.extractZip(downloadPath)
|
|
||||||
: yield tc.extractTar(downloadPath);
|
|
||||||
// cache tool
|
|
||||||
console.log('Caching tool');
|
|
||||||
let cachedDir = yield tc.cacheDir(extPath, this.cachedToolName, this.version, this.arch);
|
|
||||||
console.log('Successfully installed', this.version);
|
|
||||||
return cachedDir;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
|
|
||||||
// Type - SDK / Runtime
|
|
||||||
// Version - Version of the SDK/Runtime
|
|
||||||
getDownloadUrls(osSuffixes, version) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let downloadUrls = [];
|
|
||||||
const httpCallbackClient = new httpClient.HttpClient('actions/setup-dotnet', [], {});
|
|
||||||
const releasesJsonUrl = yield this.getReleasesJsonUrl(httpCallbackClient, version.split('.'));
|
|
||||||
let releasesJSON = yield httpCallbackClient.get(releasesJsonUrl);
|
|
||||||
let releasesInfo = JSON.parse(yield releasesJSON.readBody())['releases'];
|
|
||||||
releasesInfo = releasesInfo.filter((releaseInfo) => {
|
|
||||||
return (releaseInfo['sdk']['version'] === version ||
|
|
||||||
releaseInfo['sdk']['version-display'] === version);
|
|
||||||
});
|
|
||||||
if (releasesInfo.length != 0) {
|
|
||||||
let release = releasesInfo[0];
|
|
||||||
let files = release['sdk']['files'];
|
|
||||||
files = files.filter((file) => {
|
|
||||||
if (file['rid'] == osSuffixes[0] || file['rid'] == osSuffixes[1]) {
|
|
||||||
return (file['url'].endsWith('.zip') || file['url'].endsWith('.tar.gz'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (files.length > 0) {
|
|
||||||
files.forEach((file) => {
|
|
||||||
downloadUrls.push(file['url']);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw `The specified version's download links are not correctly formed in the supported versions document => ${releasesJsonUrl}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(`Could not fetch download information for version ${version}`);
|
|
||||||
downloadUrls = yield this.getFallbackDownloadUrls(version);
|
|
||||||
}
|
|
||||||
if (downloadUrls.length == 0) {
|
|
||||||
throw `Could not construct download URL. Please ensure that specified version ${version} is valid.`;
|
|
||||||
}
|
|
||||||
core.debug(`Got download urls ${downloadUrls}`);
|
|
||||||
return downloadUrls;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getReleasesJsonUrl(httpCallbackClient, versionParts) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
const releasesIndex = yield httpCallbackClient.get(DotNetCoreIndexUrl);
|
|
||||||
let releasesInfo = JSON.parse(yield releasesIndex.readBody())['releases-index'];
|
|
||||||
releasesInfo = releasesInfo.filter((info) => {
|
|
||||||
// channel-version is the first 2 elements of the version (e.g. 2.1), filter out versions that don't match 2.1.x.
|
|
||||||
const sdkParts = info['channel-version'].split('.');
|
|
||||||
if (versionParts.length >= 2 && versionParts[1] != 'x') {
|
|
||||||
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
|
|
||||||
}
|
|
||||||
return versionParts[0] == sdkParts[0];
|
|
||||||
});
|
|
||||||
if (releasesInfo.length === 0) {
|
|
||||||
throw `Could not find info for version ${versionParts.join('.')} at ${DotNetCoreIndexUrl}`;
|
|
||||||
}
|
|
||||||
return releasesInfo[0]['releases.json'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getFallbackDownloadUrls(version) {
|
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
|
||||||
let primaryUrlSearchString;
|
|
||||||
let legacyUrlSearchString;
|
|
||||||
let output = '';
|
let output = '';
|
||||||
let resultCode = 0;
|
let resultCode = 0;
|
||||||
if (IS_WINDOWS) {
|
if (IS_WINDOWS) {
|
||||||
let escapedScript = path
|
let escapedScript = path
|
||||||
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||||
.replace(/'/g, "''");
|
.replace(/'/g, "''");
|
||||||
let command = `& '${escapedScript}' -Version ${version} -DryRun`;
|
let command = `& '${escapedScript}' -Version ${this.version}`;
|
||||||
const powershellPath = yield io.which('powershell', true);
|
const powershellPath = yield io.which('powershell', true);
|
||||||
resultCode = yield exec.exec(`"${powershellPath}"`, [
|
resultCode = yield exec.exec(`"${powershellPath}"`, [
|
||||||
'-NoLogo',
|
'-NoLogo',
|
||||||
@ -256,8 +55,6 @@ class DotnetCoreInstaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let escapedScript = path
|
let escapedScript = path
|
||||||
@ -265,48 +62,18 @@ class DotnetCoreInstaller {
|
|||||||
.replace(/'/g, "''");
|
.replace(/'/g, "''");
|
||||||
fs_1.chmodSync(escapedScript, '777');
|
fs_1.chmodSync(escapedScript, '777');
|
||||||
const scriptPath = yield io.which(escapedScript, true);
|
const scriptPath = yield io.which(escapedScript, true);
|
||||||
resultCode = yield exec.exec(`"${scriptPath}"`, ['--version', version, '--dry-run'], {
|
resultCode = yield exec.exec(`"${scriptPath}"`, ['--version', this.version], {
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data) => {
|
stdout: (data) => {
|
||||||
output += data.toString();
|
output += data.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
|
||||||
}
|
}
|
||||||
if (resultCode != 0) {
|
if (resultCode != 0) {
|
||||||
throw `Failed to get download urls with result code ${resultCode}. ${output}`;
|
throw `Failed to install dotnet ${resultCode}. ${output}`;
|
||||||
}
|
}
|
||||||
let primaryUrl = '';
|
|
||||||
let legacyUrl = '';
|
|
||||||
if (!!output && output.length > 0) {
|
|
||||||
let lines = output.split(os.EOL);
|
|
||||||
// Fallback to \n if initial split doesn't work (not consistent across versions)
|
|
||||||
if (lines.length === 1) {
|
|
||||||
lines = output.split('\n');
|
|
||||||
}
|
|
||||||
if (!!lines && lines.length > 0) {
|
|
||||||
lines.forEach((line) => {
|
|
||||||
if (!line) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var primarySearchStringIndex = line.indexOf(primaryUrlSearchString);
|
|
||||||
if (primarySearchStringIndex > -1) {
|
|
||||||
primaryUrl = line.substring(primarySearchStringIndex + primaryUrlSearchString.length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var legacySearchStringIndex = line.indexOf(legacyUrlSearchString);
|
|
||||||
if (legacySearchStringIndex > -1) {
|
|
||||||
legacyUrl = line.substring(legacySearchStringIndex + legacyUrlSearchString.length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [primaryUrl, legacyUrl];
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
exports.DotnetCoreInstaller = DotnetCoreInstaller;
|
exports.DotnetCoreInstaller = DotnetCoreInstaller;
|
||||||
const DotNetCoreIndexUrl = 'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json';
|
|
||||||
|
308
src/installer.ts
308
src/installer.ts
@ -1,278 +1,22 @@
|
|||||||
// Load tempDirectory before it gets wiped by tool-cache
|
// Load tempDirectory before it gets wiped by tool-cache
|
||||||
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
|
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as exec from '@actions/exec';
|
import * as exec from '@actions/exec';
|
||||||
import * as io from '@actions/io';
|
import * as io from '@actions/io';
|
||||||
import * as tc from '@actions/tool-cache';
|
|
||||||
import httpClient = require('typed-rest-client/HttpClient');
|
import httpClient = require('typed-rest-client/HttpClient');
|
||||||
import {HttpClientResponse} from 'typed-rest-client/HttpClient';
|
|
||||||
import {chmodSync} from 'fs';
|
import {chmodSync} from 'fs';
|
||||||
import * as os from 'os';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
import * as util from 'util';
|
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
if (!tempDirectory) {
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DotnetCoreInstaller {
|
export class DotnetCoreInstaller {
|
||||||
constructor(version: string) {
|
constructor(version: string) {
|
||||||
if (semver.valid(semver.clean(version) || '') == null) {
|
if (semver.valid(semver.clean(version) || '') == null) {
|
||||||
throw 'Implicit version not permitted';
|
throw 'Implicit version not permitted';
|
||||||
}
|
}
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.cachedToolName = 'dncs';
|
|
||||||
this.arch = 'x64';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async installDotnet() {
|
public async installDotnet() {
|
||||||
// Check cache
|
|
||||||
let toolPath: string;
|
|
||||||
let osSuffixes = await this.detectMachineOS();
|
|
||||||
let parts = osSuffixes[0].split('-');
|
|
||||||
if (parts.length > 1) {
|
|
||||||
this.arch = parts[1];
|
|
||||||
}
|
|
||||||
toolPath = this.getLocalTool();
|
|
||||||
|
|
||||||
if (!toolPath) {
|
|
||||||
// download, extract, cache
|
|
||||||
console.log('Getting a download url', this.version);
|
|
||||||
let downloadUrls = await this.getDownloadUrls(osSuffixes, this.version);
|
|
||||||
toolPath = await this.downloadAndInstall(downloadUrls);
|
|
||||||
} else {
|
|
||||||
console.log('Using cached tool');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Need to set this so that .NET Core global tools find the right locations.
|
|
||||||
core.exportVariable('DOTNET_ROOT', toolPath);
|
|
||||||
|
|
||||||
// Prepend the tools path. instructs the agent to prepend for future tasks
|
|
||||||
core.addPath(toolPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getLocalTool(): string {
|
|
||||||
console.log('Checking tool cache');
|
|
||||||
return tc.find(this.cachedToolName, this.version, this.arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async detectMachineOS(): Promise<string[]> {
|
|
||||||
let osSuffix = [];
|
|
||||||
let output = '';
|
|
||||||
|
|
||||||
let resultCode = 0;
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
let escapedScript = path
|
|
||||||
.join(__dirname, '..', 'externals', 'get-os-platform.ps1')
|
|
||||||
.replace(/'/g, "''");
|
|
||||||
let command = `& '${escapedScript}'`;
|
|
||||||
|
|
||||||
const powershellPath = await io.which('powershell', true);
|
|
||||||
resultCode = await exec.exec(
|
|
||||||
`"${powershellPath}"`,
|
|
||||||
[
|
|
||||||
'-NoLogo',
|
|
||||||
'-Sta',
|
|
||||||
'-NoProfile',
|
|
||||||
'-NonInteractive',
|
|
||||||
'-ExecutionPolicy',
|
|
||||||
'Unrestricted',
|
|
||||||
'-Command',
|
|
||||||
command
|
|
||||||
],
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let scriptPath = path.join(
|
|
||||||
__dirname,
|
|
||||||
'..',
|
|
||||||
'externals',
|
|
||||||
'get-os-distro.sh'
|
|
||||||
);
|
|
||||||
chmodSync(scriptPath, '777');
|
|
||||||
|
|
||||||
const toolPath = await io.which(scriptPath, true);
|
|
||||||
resultCode = await exec.exec(`"${toolPath}"`, [], {
|
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (resultCode != 0) {
|
|
||||||
throw `Failed to detect os with result code ${resultCode}. Output: ${output}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let index;
|
|
||||||
if ((index = output.indexOf('Primary:')) >= 0) {
|
|
||||||
let primary = output.substr(index + 'Primary:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((index = output.indexOf('Legacy:')) >= 0) {
|
|
||||||
let legacy = output.substr(index + 'Legacy:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(legacy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osSuffix.length == 0) {
|
|
||||||
throw 'Could not detect platform';
|
|
||||||
}
|
|
||||||
|
|
||||||
return osSuffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async downloadAndInstall(downloadUrls: string[]) {
|
|
||||||
let downloaded = false;
|
|
||||||
let downloadPath = '';
|
|
||||||
for (const url of downloadUrls) {
|
|
||||||
try {
|
|
||||||
downloadPath = await tc.downloadTool(url);
|
|
||||||
downloaded = true;
|
|
||||||
break;
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Could Not Download', url, JSON.stringify(error));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!downloaded) {
|
|
||||||
throw 'Failed to download package';
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract
|
|
||||||
console.log('Extracting Package', downloadPath);
|
|
||||||
let extPath: string = IS_WINDOWS
|
|
||||||
? await tc.extractZip(downloadPath)
|
|
||||||
: await tc.extractTar(downloadPath);
|
|
||||||
|
|
||||||
// cache tool
|
|
||||||
console.log('Caching tool');
|
|
||||||
let cachedDir = await tc.cacheDir(
|
|
||||||
extPath,
|
|
||||||
this.cachedToolName,
|
|
||||||
this.version,
|
|
||||||
this.arch
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log('Successfully installed', this.version);
|
|
||||||
return cachedDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
|
|
||||||
// Type - SDK / Runtime
|
|
||||||
// Version - Version of the SDK/Runtime
|
|
||||||
private async getDownloadUrls(
|
|
||||||
osSuffixes: string[],
|
|
||||||
version: string
|
|
||||||
): Promise<string[]> {
|
|
||||||
let downloadUrls: string[] = [];
|
|
||||||
|
|
||||||
const httpCallbackClient = new httpClient.HttpClient(
|
|
||||||
'actions/setup-dotnet',
|
|
||||||
[],
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
const releasesJsonUrl: string = await this.getReleasesJsonUrl(
|
|
||||||
httpCallbackClient,
|
|
||||||
version.split('.')
|
|
||||||
);
|
|
||||||
|
|
||||||
let releasesJSON = await httpCallbackClient.get(releasesJsonUrl);
|
|
||||||
|
|
||||||
let releasesInfo: any[] = JSON.parse(await releasesJSON.readBody())[
|
|
||||||
'releases'
|
|
||||||
];
|
|
||||||
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
|
|
||||||
return (
|
|
||||||
releaseInfo['sdk']['version'] === version ||
|
|
||||||
releaseInfo['sdk']['version-display'] === version
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (releasesInfo.length != 0) {
|
|
||||||
let release = releasesInfo[0];
|
|
||||||
let files: any[] = release['sdk']['files'];
|
|
||||||
files = files.filter((file: any) => {
|
|
||||||
if (file['rid'] == osSuffixes[0] || file['rid'] == osSuffixes[1]) {
|
|
||||||
return (
|
|
||||||
file['url'].endsWith('.zip') || file['url'].endsWith('.tar.gz')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (files.length > 0) {
|
|
||||||
files.forEach((file: any) => {
|
|
||||||
downloadUrls.push(file['url']);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw `The specified version's download links are not correctly formed in the supported versions document => ${releasesJsonUrl}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
`Could not fetch download information for version ${version}`
|
|
||||||
);
|
|
||||||
downloadUrls = await this.getFallbackDownloadUrls(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadUrls.length == 0) {
|
|
||||||
throw `Could not construct download URL. Please ensure that specified version ${version} is valid.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
core.debug(`Got download urls ${downloadUrls}`);
|
|
||||||
|
|
||||||
return downloadUrls;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getReleasesJsonUrl(
|
|
||||||
httpCallbackClient: httpClient.HttpClient,
|
|
||||||
versionParts: string[]
|
|
||||||
): Promise<string> {
|
|
||||||
const releasesIndex: HttpClientResponse = await httpCallbackClient.get(
|
|
||||||
DotNetCoreIndexUrl
|
|
||||||
);
|
|
||||||
let releasesInfo: any[] = JSON.parse(await releasesIndex.readBody())[
|
|
||||||
'releases-index'
|
|
||||||
];
|
|
||||||
releasesInfo = releasesInfo.filter((info: any) => {
|
|
||||||
// channel-version is the first 2 elements of the version (e.g. 2.1), filter out versions that don't match 2.1.x.
|
|
||||||
const sdkParts: string[] = info['channel-version'].split('.');
|
|
||||||
if (versionParts.length >= 2 && versionParts[1] != 'x') {
|
|
||||||
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
|
|
||||||
}
|
|
||||||
return versionParts[0] == sdkParts[0];
|
|
||||||
});
|
|
||||||
if (releasesInfo.length === 0) {
|
|
||||||
throw `Could not find info for version ${versionParts.join(
|
|
||||||
'.'
|
|
||||||
)} at ${DotNetCoreIndexUrl}`;
|
|
||||||
}
|
|
||||||
return releasesInfo[0]['releases.json'];
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getFallbackDownloadUrls(version: string): Promise<string[]> {
|
|
||||||
let primaryUrlSearchString: string;
|
|
||||||
let legacyUrlSearchString: string;
|
|
||||||
let output = '';
|
let output = '';
|
||||||
let resultCode = 0;
|
let resultCode = 0;
|
||||||
|
|
||||||
@ -280,7 +24,7 @@ export class DotnetCoreInstaller {
|
|||||||
let escapedScript = path
|
let escapedScript = path
|
||||||
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||||
.replace(/'/g, "''");
|
.replace(/'/g, "''");
|
||||||
let command = `& '${escapedScript}' -Version ${version} -DryRun`;
|
let command = `& '${escapedScript}' -Version ${this.version}`;
|
||||||
|
|
||||||
const powershellPath = await io.which('powershell', true);
|
const powershellPath = await io.which('powershell', true);
|
||||||
resultCode = await exec.exec(
|
resultCode = await exec.exec(
|
||||||
@ -303,9 +47,6 @@ export class DotnetCoreInstaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
|
||||||
} else {
|
} else {
|
||||||
let escapedScript = path
|
let escapedScript = path
|
||||||
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||||
@ -315,7 +56,7 @@ export class DotnetCoreInstaller {
|
|||||||
const scriptPath = await io.which(escapedScript, true);
|
const scriptPath = await io.which(escapedScript, true);
|
||||||
resultCode = await exec.exec(
|
resultCode = await exec.exec(
|
||||||
`"${scriptPath}"`,
|
`"${scriptPath}"`,
|
||||||
['--version', version, '--dry-run'],
|
['--version', this.version],
|
||||||
{
|
{
|
||||||
listeners: {
|
listeners: {
|
||||||
stdout: (data: Buffer) => {
|
stdout: (data: Buffer) => {
|
||||||
@ -324,55 +65,12 @@ export class DotnetCoreInstaller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultCode != 0) {
|
if (resultCode != 0) {
|
||||||
throw `Failed to get download urls with result code ${resultCode}. ${output}`;
|
throw `Failed to install dotnet ${resultCode}. ${output}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let primaryUrl: string = '';
|
|
||||||
let legacyUrl: string = '';
|
|
||||||
if (!!output && output.length > 0) {
|
|
||||||
let lines: string[] = output.split(os.EOL);
|
|
||||||
|
|
||||||
// Fallback to \n if initial split doesn't work (not consistent across versions)
|
|
||||||
if (lines.length === 1) {
|
|
||||||
lines = output.split('\n');
|
|
||||||
}
|
|
||||||
if (!!lines && lines.length > 0) {
|
|
||||||
lines.forEach((line: string) => {
|
|
||||||
if (!line) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var primarySearchStringIndex = line.indexOf(primaryUrlSearchString);
|
|
||||||
if (primarySearchStringIndex > -1) {
|
|
||||||
primaryUrl = line.substring(
|
|
||||||
primarySearchStringIndex + primaryUrlSearchString.length
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var legacySearchStringIndex = line.indexOf(legacyUrlSearchString);
|
|
||||||
if (legacySearchStringIndex > -1) {
|
|
||||||
legacyUrl = line.substring(
|
|
||||||
legacySearchStringIndex + legacyUrlSearchString.length
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [primaryUrl, legacyUrl];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private version: string;
|
private version: string;
|
||||||
private cachedToolName: string;
|
|
||||||
private arch: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DotNetCoreIndexUrl: string =
|
|
||||||
'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json';
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user