Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UseDotNetV2] Allow to use installed dotnet version #20715

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
"loc.input.help.version": "Specify version of .NET Core SDK or runtime to install.<br/>Versions can be given in the following formats<li>2.x => Install latest in major version.</li><li>2.2.x => Install latest in major and minor version</li><li>2.2.104 => Install exact version</li><br/>Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json). Like link to releases.json for 2.2 version is https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/2.2/releases.json",
"loc.input.label.vsVersion": "Compatible Visual Studio version",
"loc.input.help.vsVersion": "Specify version of compatible visual studio for which .NET core sdk to install. Specifiy complete vs-version like 16.6.4 containing major version, minor version and patch number.Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json)",
"loc.input.label.checkDotnetCLI": "Check is version installed via dotnet",
"loc.input.help.checkDotnetCLI": "Select if you want to check is version already installed via dotnet CLI",
"loc.input.label.includePreviewVersions": "Include Preview Versions",
"loc.input.help.includePreviewVersions": "Select if you want preview versions to be included while searching for latest versions, such as while searching 2.2.x. This setting is ignored if you specify an exact version, such as: 3.0.100-preview3-010431",
"loc.input.label.installationPath": "Path To Install .Net Core",
"loc.input.help.installationPath": "Specify where .Net Core SDK/Runtime should be installed. Different paths can have the following impact on .Net's behavior.<li>$(Agent.ToolsDirectory): This makes the version to be cached on the agent since this directory is not cleanup up across pipelines. All pipelines running on the agent, would have access to the versions installed previously using the agent.</li><li>$(Agent.TempDirectory): This can ensure that a pipeline doesn't use any cached version of .Net core since this folder is cleaned up after each pipeline.</li><li>Any other path: You can configure any other path given the agent process has access to the path. This will change the state of the machine and impact all processes running on it.<br/>Note that you can also configure Multi-Level Lookup setting which can configure .Net host's probing for a suitable version.",
"loc.input.label.performMultiLevelLookup": "Perform Multi Level Lookup",
"loc.input.help.performMultiLevelLookup": "This input is only applicable to Windows based agents. This configures the behavior of .Net host process for looking up a suitable shared framework.<li>unchecked: Only versions present in the folder specified in this task would be looked by the host process.</li><li>checked: The host will attempt to look in pre-defined global locations using multi-level lookup.<br/>The default global locations are: <br/><b>For Windows:</b><br/>C:\\Program Files\\dotnet (64-bit processes)<br/>C:\\Program Files (x86)\\dotnet (32-bit process)</li> You can read more about it [**HERE**](https://github.com/dotnet/core-setup/blob/master/Documentation/design-docs/multilevel-sharedfx-lookup.md).<br/>",
"loc.input.label.requestTimeout": "Set timeout for package download request",
"loc.input.help.requestTimeout": "Provide a timeout value for HTTP requests that the task makes to obtain the .NET package. The value is in milliseconds. Default is 300000 milliseconds (5 minutes). Cannot be more than 600000 milliseconds (10 minutes).",
"loc.messages.ToolFailed": "Tool install failed: %s",
"loc.messages.ImplicitVersionNotSupported": "Version should be a valid and explicit version: %s",
"loc.messages.getMachinePlatformFailed": "Failed to get machine platform details. Error: %s.",
Expand Down
11 changes: 10 additions & 1 deletion Tasks/UseDotNetV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 2,
"Minor": 248,
"Minor": 250,
"Patch": 0
},
"satisfies": [
Expand Down Expand Up @@ -79,6 +79,15 @@
"groupName": "advanced",
"helpMarkDown": "Specify version of compatible visual studio for which .NET core sdk to install. Specifiy complete vs-version like 16.6.4 containing major version, minor version and patch number.Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json)"
},
{
"name": "checkDotnetCLI",
"type": "boolean",
"label": "Check is version installed via dotnet",
"defaultValue": "false",
"required": false,
"helpMarkDown": "Select if you want to check is version already installed via dotnet CLI",
"groupName": "advanced"
},
{
"name": "includePreviewVersions",
"type": "boolean",
Expand Down
11 changes: 10 additions & 1 deletion Tasks/UseDotNetV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 2,
"Minor": 248,
"Minor": 250,
"Patch": 0
},
"satisfies": [
Expand Down Expand Up @@ -79,6 +79,15 @@
"groupName": "advanced",
"helpMarkDown": "ms-resource:loc.input.help.vsVersion"
},
{
"name": "checkDotnetCLI",
"type": "boolean",
"label": "ms-resource:loc.input.label.checkDotnetCLI",
"defaultValue": "false",
"required": false,
"helpMarkDown": "ms-resource:loc.input.help.checkDotnetCLI",
"groupName": "advanced"
},
{
"name": "includePreviewVersions",
"type": "boolean",
Expand Down
67 changes: 63 additions & 4 deletions Tasks/UseDotNetV2/usedotnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function checkVersionForDeprecationAndNotify(versionSpec: string | null): void {

async function run() {
let useGlobalJson: boolean = tl.getBoolInput('useGlobalJson');
let checkDotnetCLI: boolean = tl.getBoolInput('checkDotnetCLI');
let packageType = (tl.getInput('packageType') || "sdk").toLowerCase();;
let versionSpec = tl.getInput('version');
let vsVersionSpec = tl.getInput('vsVersion');
Expand All @@ -31,12 +32,21 @@ async function run() {
let performMultiLevelLookup = tl.getBoolInput("performMultiLevelLookup", false);
// Check if we want install dotnet
if (versionSpec || (useGlobalJson && packageType == "sdk")) {
let isDotnetInstalled = false;

let includePreviewVersions: boolean = tl.getBoolInput('includePreviewVersions');
let workingDirectory: string | null = tl.getPathInput("workingDirectory", false) || null;
await installDotNet(installationPath, packageType, versionSpec, vsVersionSpec, useGlobalJson, workingDirectory, includePreviewVersions);
tl.prependPath(installationPath);
// Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
tl.setVariable('DOTNET_ROOT', installationPath);

// check is dotnet installed via dotnet cli
if (checkDotnetCLI) isDotnetInstalled = await isCompatibleDotnetVersionInstalled(versionSpec, vsVersionSpec, useGlobalJson, packageType, workingDirectory, includePreviewVersions);

if (!isDotnetInstalled) {
await installDotNet(installationPath, packageType, versionSpec, vsVersionSpec, useGlobalJson, workingDirectory, includePreviewVersions);
tl.prependPath(installationPath);
// Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
tl.setVariable('DOTNET_ROOT', installationPath);
}

// By default disable Multi Level Lookup unless user wants it enabled.
tl.setVariable("DOTNET_MULTILEVEL_LOOKUP", !performMultiLevelLookup ? "0" : "1");
}
Expand All @@ -48,6 +58,55 @@ async function run() {
await NuGetInstaller.installNuGet(nugetVersion);
}

/**
*
* @param versionSpec The version the user want to install.
* @param vsVersionSpec Compatible Visual Studio version.
* @param useGlobalJson A switch so we know if the user have `global.json` files and want use that. If this is true only SDK is possible!
* @param packageType The installation type for the installation. Only `sdk` and `runtime` are valid options
* @param workingDirectory This is only relevant if the `useGlobalJson` switch is `true`. It will set the root directory for the search of `global.json`
* @param includePreviewVersions Define if the installer also search for preview version
* @returns { Promise<boolean> } - true if dotnet installed, otherwise - false
*/
async function isCompatibleDotnetVersionInstalled(versionSpec: string, vsVersionSpec: string, useGlobalJson: boolean, packageType: string, workingDirectory: string, includePreviewVersions: boolean): Promise<boolean> {
let versionFetcher = new DotNetCoreVersionFetcher();

if (useGlobalJson && packageType == "sdk") {
let globalJsonFetcherInstance = new globalJsonFetcher(workingDirectory);
let versionsToInstall: VersionInfo[] = await globalJsonFetcherInstance.GetVersions();
return checkVersionInDotnetCLI(versionsToInstall, packageType);
} else if (versionSpec) {
let versionSpecParts = new VersionParts(versionSpec);
let versionInfo: VersionInfo = await versionFetcher.getVersionInfo(versionSpecParts.versionSpec, vsVersionSpec, packageType, includePreviewVersions);
return checkVersionInDotnetCLI(versionInfo, packageType);
}

return false;
}

function checkVersionInDotnetCLI(versionInfo: VersionInfo | VersionInfo[], packageType: string): boolean {
let versions: VersionInfo[];
if (!Array.isArray(versionInfo)) versions = [ versionInfo ];
else versions = versionInfo;
const dotnetPath = tl.which('dotnet', false);
if (!dotnetPath) return false;
const dotnet = tl.tool(dotnetPath);

if (packageType === "sdk") {
dotnet.arg('--list-sdks');
} else {
dotnet.arg('--list-runtimes');
}

const result = dotnet.execSync();
if (result.code !== 0) return false;
const stdout = result.stdout;

const notFoundedversions = versions.filter(version => !stdout.includes(version.getVersion()));

return notFoundedversions.length === 0;
}

/**
* install dotnet to the installation path.
* @param installationPath The installation path. If this is empty it would use {Agent.ToolsDirectory}/dotnet/
Expand Down
4 changes: 2 additions & 2 deletions _generated/UseDotNetV2.versionmap.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Default|2.248.0
Node20_229_3|2.248.1
Default|2.250.0
Node20_229_3|2.250.1
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"loc.input.help.version": "Specify version of .NET Core SDK or runtime to install.<br/>Versions can be given in the following formats<li>2.x => Install latest in major version.</li><li>2.2.x => Install latest in major and minor version</li><li>2.2.104 => Install exact version</li><br/>Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json). Like link to releases.json for 2.2 version is https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/2.2/releases.json",
"loc.input.label.vsVersion": "Compatible Visual Studio version",
"loc.input.help.vsVersion": "Specify version of compatible visual studio for which .NET core sdk to install. Specifiy complete vs-version like 16.6.4 containing major version, minor version and patch number.Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json)",
"loc.input.label.checkDotnetCLI": "Check is version installed via dotnet",
"loc.input.help.checkDotnetCLI": "Select if you want to check is version already installed via dotnet CLI",
"loc.input.label.includePreviewVersions": "Include Preview Versions",
"loc.input.help.includePreviewVersions": "Select if you want preview versions to be included while searching for latest versions, such as while searching 2.2.x. This setting is ignored if you specify an exact version, such as: 3.0.100-preview3-010431",
"loc.input.label.installationPath": "Path To Install .Net Core",
Expand Down
16 changes: 13 additions & 3 deletions _generated/UseDotNetV2/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 2,
"Minor": 248,
"Minor": 250,
"Patch": 0
},
"satisfies": [
Expand Down Expand Up @@ -79,6 +79,15 @@
"groupName": "advanced",
"helpMarkDown": "Specify version of compatible visual studio for which .NET core sdk to install. Specifiy complete vs-version like 16.6.4 containing major version, minor version and patch number.Find the value of `version` for installing SDK/Runtime, from the releases.json. The link to releases.json of that major.minor version can be found in [**releases-index file.**](https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json)"
},
{
"name": "checkDotnetCLI",
"type": "boolean",
"label": "Check is version installed via dotnet",
"defaultValue": "false",
"required": false,
"helpMarkDown": "Select if you want to check is version already installed via dotnet CLI",
"groupName": "advanced"
},
{
"name": "includePreviewVersions",
"type": "boolean",
Expand Down Expand Up @@ -203,7 +212,8 @@
"DepricatedVersionNetCore": "NET Core version you specfied %s is out of support and will be removed from hosted agents soon. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy."
},
"_buildConfigMapping": {
"Default": "2.248.0",
"Node20_229_3": "2.248.1"
"Default": "2.250.0",
"LocalPackages": "2.249.4",
"Node20_229_3": "2.250.1"
}
}
16 changes: 13 additions & 3 deletions _generated/UseDotNetV2/task.loc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"author": "Microsoft Corporation",
"version": {
"Major": 2,
"Minor": 248,
"Minor": 250,
"Patch": 0
},
"satisfies": [
Expand Down Expand Up @@ -79,6 +79,15 @@
"groupName": "advanced",
"helpMarkDown": "ms-resource:loc.input.help.vsVersion"
},
{
"name": "checkDotnetCLI",
"type": "boolean",
"label": "ms-resource:loc.input.label.checkDotnetCLI",
"defaultValue": "false",
"required": false,
"helpMarkDown": "ms-resource:loc.input.help.checkDotnetCLI",
"groupName": "advanced"
},
{
"name": "includePreviewVersions",
"type": "boolean",
Expand Down Expand Up @@ -203,7 +212,8 @@
"DepricatedVersionNetCore": "ms-resource:loc.messages.DepricatedVersionNetCore"
},
"_buildConfigMapping": {
"Default": "2.248.0",
"Node20_229_3": "2.248.1"
"Default": "2.250.0",
"LocalPackages": "2.249.4",
"Node20_229_3": "2.250.1"
}
}
67 changes: 63 additions & 4 deletions _generated/UseDotNetV2/usedotnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function checkVersionForDeprecationAndNotify(versionSpec: string | null): void {

async function run() {
let useGlobalJson: boolean = tl.getBoolInput('useGlobalJson');
let checkDotnetCLI: boolean = tl.getBoolInput('checkDotnetCLI');
let packageType = (tl.getInput('packageType') || "sdk").toLowerCase();;
let versionSpec = tl.getInput('version');
let vsVersionSpec = tl.getInput('vsVersion');
Expand All @@ -31,12 +32,21 @@ async function run() {
let performMultiLevelLookup = tl.getBoolInput("performMultiLevelLookup", false);
// Check if we want install dotnet
if (versionSpec || (useGlobalJson && packageType == "sdk")) {
let isDotnetInstalled = false;

let includePreviewVersions: boolean = tl.getBoolInput('includePreviewVersions');
let workingDirectory: string | null = tl.getPathInput("workingDirectory", false) || null;
await installDotNet(installationPath, packageType, versionSpec, vsVersionSpec, useGlobalJson, workingDirectory, includePreviewVersions);
tl.prependPath(installationPath);
// Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
tl.setVariable('DOTNET_ROOT', installationPath);

// check is dotnet installed via dotnet cli
if (checkDotnetCLI) isDotnetInstalled = await isCompatibleDotnetVersionInstalled(versionSpec, vsVersionSpec, useGlobalJson, packageType, workingDirectory, includePreviewVersions);

if (!isDotnetInstalled) {
await installDotNet(installationPath, packageType, versionSpec, vsVersionSpec, useGlobalJson, workingDirectory, includePreviewVersions);
tl.prependPath(installationPath);
// Set DOTNET_ROOT for dotnet core Apphost to find runtime since it is installed to a non well-known location.
tl.setVariable('DOTNET_ROOT', installationPath);
}

// By default disable Multi Level Lookup unless user wants it enabled.
tl.setVariable("DOTNET_MULTILEVEL_LOOKUP", !performMultiLevelLookup ? "0" : "1");
}
Expand All @@ -48,6 +58,55 @@ async function run() {
await NuGetInstaller.installNuGet(nugetVersion);
}

/**
*
* @param versionSpec The version the user want to install.
* @param vsVersionSpec Compatible Visual Studio version.
* @param useGlobalJson A switch so we know if the user have `global.json` files and want use that. If this is true only SDK is possible!
* @param packageType The installation type for the installation. Only `sdk` and `runtime` are valid options
* @param workingDirectory This is only relevant if the `useGlobalJson` switch is `true`. It will set the root directory for the search of `global.json`
* @param includePreviewVersions Define if the installer also search for preview version
* @returns { Promise<boolean> } - true if dotnet installed, otherwise - false
*/
async function isCompatibleDotnetVersionInstalled(versionSpec: string, vsVersionSpec: string, useGlobalJson: boolean, packageType: string, workingDirectory: string, includePreviewVersions: boolean): Promise<boolean> {
let versionFetcher = new DotNetCoreVersionFetcher();

if (useGlobalJson && packageType == "sdk") {
let globalJsonFetcherInstance = new globalJsonFetcher(workingDirectory);
let versionsToInstall: VersionInfo[] = await globalJsonFetcherInstance.GetVersions();
return checkVersionInDotnetCLI(versionsToInstall, packageType);
} else if (versionSpec) {
let versionSpecParts = new VersionParts(versionSpec);
let versionInfo: VersionInfo = await versionFetcher.getVersionInfo(versionSpecParts.versionSpec, vsVersionSpec, packageType, includePreviewVersions);
return checkVersionInDotnetCLI(versionInfo, packageType);
}

return false;
}

function checkVersionInDotnetCLI(versionInfo: VersionInfo | VersionInfo[], packageType: string): boolean {
let versions: VersionInfo[];
if (!Array.isArray(versionInfo)) versions = [ versionInfo ];
else versions = versionInfo;
const dotnetPath = tl.which('dotnet', false);
if (!dotnetPath) return false;
const dotnet = tl.tool(dotnetPath);

if (packageType === "sdk") {
dotnet.arg('--list-sdks');
} else {
dotnet.arg('--list-runtimes');
}

const result = dotnet.execSync();
if (result.code !== 0) return false;
const stdout = result.stdout;

const notFoundedversions = versions.filter(version => !stdout.includes(version.getVersion()));

return notFoundedversions.length === 0;
}

/**
* install dotnet to the installation path.
* @param installationPath The installation path. If this is empty it would use {Agent.ToolsDirectory}/dotnet/
Expand Down
4 changes: 4 additions & 0 deletions _generated/UseDotNetV2_Node20/.npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
scripts-prepend-node-path=true

registry=https://pkgs.dev.azure.com/mseng/PipelineTools/_packaging/PipelineTools_PublicPackages/npm/registry/

always-auth=true
Loading