mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-08-18 06:35:09 +00:00
236 lines
7.2 KiB
TypeScript
236 lines
7.2 KiB
TypeScript
// Load tempDirectory before it gets wiped by tool-cache
|
|
import * as core from '@actions/core';
|
|
import * as exec from '@actions/exec';
|
|
import * as io from '@actions/io';
|
|
import hc = require('@actions/http-client');
|
|
import {chmodSync} from 'fs';
|
|
import * as path from 'path';
|
|
import semver from 'semver';
|
|
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
|
|
|
const IS_WINDOWS = process.platform === 'win32';
|
|
const IS_LINUX = process.platform === 'linux';
|
|
|
|
export class DotnetQualityValidator {
|
|
private quality: string;
|
|
private qualityOptions: string[];
|
|
|
|
constructor(quality: string) {
|
|
this.quality = quality;
|
|
this.qualityOptions = ['daily', 'signed', 'validated', 'preview', 'ga'];
|
|
}
|
|
|
|
public validateQuality() {
|
|
if (this.quality && !this.qualityOptions.includes(this.quality)) {
|
|
throw new Error(
|
|
`${this.quality} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`
|
|
);
|
|
}
|
|
return this.quality;
|
|
}
|
|
}
|
|
|
|
export class DotnetVersionResolver {
|
|
private inputVersion: string;
|
|
private resolvedArgument: {type: string; value: string; qualityFlag: boolean};
|
|
|
|
constructor(version: string) {
|
|
this.inputVersion = version.trim();
|
|
this.resolvedArgument = {type: '', value: '', qualityFlag: false};
|
|
}
|
|
|
|
private resolveVersionInput(): void {
|
|
if (
|
|
!semver.valid(this.inputVersion) &&
|
|
!semver.validRange(this.inputVersion)
|
|
) {
|
|
throw new Error(
|
|
`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B.C-D, A.B.x, A.B.X, A.B.*`
|
|
);
|
|
}
|
|
if (semver.valid(this.inputVersion)) {
|
|
this.resolvedArgument.type = 'version';
|
|
this.resolvedArgument.value = this.inputVersion;
|
|
} else {
|
|
this.resolvedArgument.type = 'channel';
|
|
this.resolvedArgument.qualityFlag = true;
|
|
this.resolvedArgument.value = semver.validRange(this.inputVersion)
|
|
? this.inputVersion
|
|
.split('.')
|
|
.slice(0, 2)
|
|
.join('.')
|
|
: this.inputVersion;
|
|
}
|
|
}
|
|
|
|
public createVersionObject(): {
|
|
type: string;
|
|
value: string;
|
|
qualityFlag: boolean;
|
|
} {
|
|
this.resolveVersionInput();
|
|
if (IS_WINDOWS) {
|
|
this.resolvedArgument.type =
|
|
this.resolvedArgument.type === 'channel' ? '-Channel' : '-Version';
|
|
} else {
|
|
this.resolvedArgument.type =
|
|
this.resolvedArgument.type === 'channel' ? '--channel' : '--version';
|
|
}
|
|
return this.resolvedArgument;
|
|
}
|
|
}
|
|
|
|
export class DotnetCoreInstaller {
|
|
private version: string;
|
|
private quality: string;
|
|
static installationDirectoryWindows = path.join(process.env['PROGRAMFILES'] + '', "dotnet");
|
|
static installationDirectoryLinux = '/usr/share/dotnet';
|
|
|
|
constructor(version: string, quality: string) {
|
|
this.version = version;
|
|
this.quality = quality;
|
|
}
|
|
|
|
public async installDotnet() {
|
|
let output = '';
|
|
let resultCode = 0;
|
|
|
|
|
|
const versionResolver = new DotnetVersionResolver(this.version);
|
|
const versionObject = versionResolver.createVersionObject();
|
|
|
|
var envVariables: {[key: string]: string} = {};
|
|
for (let key in process.env) {
|
|
if (process.env[key]) {
|
|
let value: any = process.env[key];
|
|
envVariables[key] = value;
|
|
}
|
|
}
|
|
if (IS_WINDOWS) {
|
|
let escapedScript = path
|
|
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
|
.replace(/'/g, "''");
|
|
let command = `& '${escapedScript}' ${versionObject.type} ${versionObject.value}`;
|
|
|
|
if (this.quality) {
|
|
if (versionObject.qualityFlag) {
|
|
command += ` -Quality ${this.quality}`;
|
|
} else {
|
|
logWarning(
|
|
`'dotnet-quality' input can't be used with exact version: ${versionObject.value} of .NET. 'dotnet-quality' input is ignored.`
|
|
);
|
|
}
|
|
}
|
|
|
|
if (process.env['https_proxy'] != null) {
|
|
command += ` -ProxyAddress ${process.env['https_proxy']}`;
|
|
}
|
|
// This is not currently an option
|
|
if (process.env['no_proxy'] != null) {
|
|
command += ` -ProxyBypassList ${process.env['no_proxy']}`;
|
|
}
|
|
|
|
command += ` -InstallDir '${DotnetCoreInstaller.installationDirectoryWindows}'`;
|
|
|
|
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
|
const powershellPath = await io.which('powershell', true);
|
|
|
|
var options: ExecOptions = {
|
|
listeners: {
|
|
stdout: (data: Buffer) => {
|
|
output += data.toString();
|
|
}
|
|
},
|
|
env: envVariables
|
|
};
|
|
|
|
resultCode = await exec.exec(
|
|
`"${powershellPath}"`,
|
|
[
|
|
'-NoLogo',
|
|
'-Sta',
|
|
'-NoProfile',
|
|
'-NonInteractive',
|
|
'-ExecutionPolicy',
|
|
'Unrestricted',
|
|
'-Command',
|
|
command
|
|
],
|
|
options
|
|
);
|
|
} else {
|
|
let escapedScript = path
|
|
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
|
.replace(/'/g, "''");
|
|
chmodSync(escapedScript, '777');
|
|
|
|
const scriptPath = await io.which(escapedScript, true);
|
|
|
|
let scriptArguments: string[] = [versionObject.type, versionObject.value];
|
|
|
|
if (this.quality) {
|
|
if (versionObject.qualityFlag) {
|
|
scriptArguments.push('--quality', this.quality);
|
|
} else {
|
|
logWarning(
|
|
`'dotnet-quality' input can't be used with exact version: ${versionObject.value} of .NET. 'dotnet-quality' input is ignored.`
|
|
);
|
|
}
|
|
}
|
|
|
|
if (IS_LINUX) {
|
|
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryLinux);
|
|
}
|
|
|
|
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
|
resultCode = await exec.exec(`"${scriptPath}"`, scriptArguments, {
|
|
listeners: {
|
|
stdout: (data: Buffer) => {
|
|
output += data.toString();
|
|
}
|
|
},
|
|
env: envVariables
|
|
});
|
|
}
|
|
|
|
if (resultCode != 0) {
|
|
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
|
}
|
|
}
|
|
|
|
static addToPath() {
|
|
if (process.env['DOTNET_INSTALL_DIR']) {
|
|
core.addPath(process.env['DOTNET_INSTALL_DIR']);
|
|
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
|
|
} else {
|
|
if (IS_WINDOWS) {
|
|
core.exportVariable(
|
|
'DOTNET_ROOT',
|
|
DotnetCoreInstaller.installationDirectoryWindows
|
|
);
|
|
}
|
|
else if (IS_LINUX) {
|
|
core.exportVariable(
|
|
'DOTNET_ROOT',
|
|
DotnetCoreInstaller.installationDirectoryLinux
|
|
);
|
|
core.addPath(DotnetCoreInstaller.installationDirectoryLinux);
|
|
} else {
|
|
// This is the default set in install-dotnet.sh
|
|
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
|
|
core.exportVariable(
|
|
'DOTNET_ROOT',
|
|
path.join(process.env['HOME'] + '', '.dotnet')
|
|
);
|
|
}
|
|
}
|
|
|
|
console.log(process.env['PATH']);
|
|
}
|
|
}
|
|
|
|
export function logWarning(message: string): void {
|
|
const warningPrefix = '[warning]';
|
|
core.info(`${warningPrefix}${message}`);
|
|
}
|