Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,4 @@ node_modules/
.idea/

# vscode python env files
.env
.env.nuget/nuget.exe
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Remove this change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Reverted .gitignore to original state in commit 14016c4.

3 changes: 2 additions & 1 deletion eng/common/dotnet-install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Param(
[string] $verbosity = 'minimal',
[string] $architecture = '',
[string] $version = 'Latest',
[string] $channel = '',
[string] $runtime = 'dotnet',
[string] $RuntimeSourceFeed = '',
[string] $RuntimeSourceFeedKey = ''
Expand All @@ -17,7 +18,7 @@ try {
if ($architecture -and $architecture.Trim() -eq 'x86') {
$installdir = Join-Path $installdir 'x86'
}
InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey
InstallDotNet $installdir $version $architecture $runtime $true -RuntimeSourceFeed $RuntimeSourceFeed -RuntimeSourceFeedKey $RuntimeSourceFeedKey -Channel $channel
}
catch {
Write-Host $_.ScriptStackTrace
Expand Down
7 changes: 6 additions & 1 deletion eng/common/dotnet-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ scriptroot="$( cd -P "$( dirname "$source" )" && pwd )"
. "$scriptroot/tools.sh"

version='Latest'
channel=''
architecture=''
runtime='dotnet'
runtimeSourceFeed=''
Expand All @@ -25,6 +26,10 @@ while [[ $# -gt 0 ]]; do
shift
version="$1"
;;
-channel|-c)
shift
channel="$1"
;;
-architecture|-a)
shift
architecture="$1"
Expand Down Expand Up @@ -85,7 +90,7 @@ if [[ $architecture != "" ]] && [[ $architecture != $buildarch ]]; then
dotnetRoot="$dotnetRoot/$architecture"
fi

InstallDotNet "$dotnetRoot" $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey || {
InstallDotNet "$dotnetRoot" $version "$architecture" $runtime true $runtimeSourceFeed $runtimeSourceFeedKey "$channel" || {
local exit_code=$?
Write-PipelineTelemetryError -Category 'InitializeToolset' -Message "dotnet-install.sh failed (exit code '$exit_code')." >&2
ExitWithExitCode $exit_code
Expand Down
38 changes: 27 additions & 11 deletions eng/common/tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ function InstallDotNet([string] $dotnetRoot,
[bool] $skipNonVersionedFiles = $false,
[string] $runtimeSourceFeed = '',
[string] $runtimeSourceFeedKey = '',
[string] $channel = '',
[switch] $noPath) {

$dotnetVersionLabel = "'sdk v$version'"
Expand All @@ -301,21 +302,36 @@ function InstallDotNet([string] $dotnetRoot,
if ($runtime -eq "dotnet") { $runtimePath = $runtimePath + "\Microsoft.NETCore.App" }
if ($runtime -eq "aspnetcore") { $runtimePath = $runtimePath + "\Microsoft.AspNetCore.App" }
if ($runtime -eq "windowsdesktop") { $runtimePath = $runtimePath + "\Microsoft.WindowsDesktop.App" }
$runtimePath = $runtimePath + "\" + $version

$dotnetVersionLabel = "runtime toolset '$runtime/$architecture v$version'"

if (Test-Path $runtimePath) {
Write-Host " Runtime toolset '$runtime/$architecture v$version' already installed."
$installSuccess = $true
Exit

# When using channel, we can't check for an existing installation by version
# since we don't know which version will be installed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mconnew would this be a problem for you? it means we'd run dotnet-install.ps1 everytime

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@akoeplinger, would that only be when running restore? If running build -build doesn't trigger this, that would be fine.

if (-not $channel) {
$runtimePath = $runtimePath + "\" + $version
$dotnetVersionLabel = "runtime toolset '$runtime/$architecture v$version'"

if (Test-Path $runtimePath) {
Write-Host " Runtime toolset '$runtime/$architecture v$version' already installed."
$installSuccess = $true
return
}
} else {
$dotnetVersionLabel = "runtime toolset '$runtime/$architecture channel $channel'"
}
}

$installScript = GetDotNetInstallScript $dotnetRoot
$installParameters = @{
Version = $version
InstallDir = $dotnetRoot

# Use -Channel if specified, otherwise use -Version
if ($channel) {
$installParameters = @{
Channel = $channel
InstallDir = $dotnetRoot
}
} else {
$installParameters = @{
Version = $version
InstallDir = $dotnetRoot
}
}

if ($architecture) { $installParameters.Architecture = $architecture }
Expand Down
30 changes: 21 additions & 9 deletions eng/common/tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ function InstallDotNet {
local root=$1
local version=$2
local runtime=$4
local channel="${8:-}"

local dotnetVersionLabel="'$runtime v$version'"
if [[ -n "${4:-}" ]] && [ "$4" != 'sdk' ]; then
Expand All @@ -201,21 +202,32 @@ function InstallDotNet {
*)
;;
esac
runtimePath="$runtimePath/$version"

dotnetVersionLabel="runtime toolset '$runtime/$architecture v$version'"

if [ -d "$runtimePath" ]; then
echo " Runtime toolset '$runtime/$architecture v$version' already installed."
local installSuccess=1
return

# When using channel, we can't check for an existing installation by version
# since we don't know which version will be installed
if [[ -z "$channel" ]]; then
runtimePath="$runtimePath/$version"
dotnetVersionLabel="runtime toolset '$runtime/$architecture v$version'"

if [ -d "$runtimePath" ]; then
echo " Runtime toolset '$runtime/$architecture v$version' already installed."
local installSuccess=1
return
fi
else
dotnetVersionLabel="runtime toolset '$runtime/$architecture channel $channel'"
fi
fi

GetDotNetInstallScript "$root"
local install_script=$_GetDotNetInstallScript

local installParameters=(--version $version --install-dir "$root")
# Use --channel if specified, otherwise use --version
if [[ -n "$channel" ]]; then
local installParameters=(--channel $channel --install-dir "$root")
else
local installParameters=(--version $version --install-dir "$root")
fi

if [[ -n "${3:-}" ]] && [ "$3" != 'unset' ]; then
installParameters+=(--architecture $3)
Expand Down
37 changes: 37 additions & 0 deletions src/Microsoft.DotNet.Arcade.Sdk.Tests/InstallDotNetCoreTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.IO;
using System.Reflection;
using Xunit;

namespace Microsoft.DotNet.Arcade.Sdk.Tests
{
public class InstallDotNetCoreTests
{
[Theory]
[InlineData("8.0", true)]
[InlineData("10.0", true)]
[InlineData("3.1", true)]
[InlineData("8.0.22", false)]
[InlineData("10.0.1", false)]
[InlineData("8.0.0-preview.1", false)]
[InlineData("", false)]
[InlineData(null, false)]
[InlineData("8", false)]
[InlineData("8.0.1.2", false)]
[InlineData("v8.0", false)]
[InlineData("8.x", false)]
public void IsTwoPartVersion_DetectsCorrectFormat(string versionString, bool expected)
{
// Use reflection to call the private method
var task = new InstallDotNetCore();
var method = typeof(InstallDotNetCore).GetMethod("IsTwoPartVersion", BindingFlags.NonPublic | BindingFlags.Instance);

var result = (bool)method.Invoke(task, new object[] { versionString });

Assert.Equal(expected, result);
}
}
}
38 changes: 35 additions & 3 deletions src/Microsoft.DotNet.Arcade.Sdk/src/InstallDotNetCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ public override bool Execute()
}

SemanticVersion version = null;
string channel = null;

// Check if the version is in major.minor format (e.g., "8.0", "10.0")
// This format should use the -channel parameter instead of -version
if (IsTwoPartVersion(item.Key))
{
channel = item.Key;
}
// Try to parse version
if (!SemanticVersion.TryParse(item.Key, out version))
else if (!SemanticVersion.TryParse(item.Key, out version))
{
var propertyName = item.Key.Trim(s_keyTrimChars);

Expand All @@ -123,9 +131,12 @@ public override bool Execute()
}
}

if (version != null)
if (version != null || channel != null)
{
string arguments = $"-runtime \"{runtimeItem.Key}\" -version \"{version.ToNormalizedString()}\"";
string arguments = channel != null
? $"-runtime \"{runtimeItem.Key}\" -channel \"{channel}\""
: $"-runtime \"{runtimeItem.Key}\" -version \"{version.ToNormalizedString()}\"";

if (!string.IsNullOrEmpty(architecture))
{
arguments += $" -architecture {architecture}";
Expand Down Expand Up @@ -204,6 +215,27 @@ private string GetArchitecture(string architecture)
return null;
}

/*
* Checks if a version string is in major.minor format (e.g., "8.0", "10.0").
* Returns true if the version has exactly two numeric parts separated by a dot.
*/
private bool IsTwoPartVersion(string versionString)
{
if (string.IsNullOrWhiteSpace(versionString))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Please use a regex for this detection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use regex pattern ^\d+\.\d+$ for version detection in commit a9584e4.

{
return false;
}

var parts = versionString.Split('.');
if (parts.Length != 2)
{
return false;
}

// Both parts must be valid integers
return int.TryParse(parts[0], out _) && int.TryParse(parts[1], out _);
}

/*
* Parses a json token of this format
* { (runtime): [(version), ..., (version)] }
Expand Down
Loading