Install sxs with the install-dotnet scripts (#124)

* Use dotnet-install scripts for proper sxs

* Update dotnet version in testing

* Error message cleanup

* SxS testing in the dotnet project

* Update package lock

* Test fixes

* Use proper environment variable

* Set dotnet root for windows
This commit is contained in:
Zachary Eisinger 2020-09-15 09:36:09 -07:00 committed by GitHub
parent 3569a93d9f
commit 352338157c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 775 additions and 1816 deletions

View File

@ -11,6 +11,7 @@ jobs:
build: build:
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
strategy: strategy:
fail-fast: false
matrix: matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest] operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
@ -19,7 +20,7 @@ jobs:
- name: Set Node.js 12 - name: Set Node.js 12
uses: actions/setup-node@v1 uses: actions/setup-node@v1
with: with:
version: 12.x node-version: 12.x
- run: npm ci - run: npm ci
- run: npm run build - run: npm run build
- run: npm run format-check - run: npm run format-check
@ -31,27 +32,50 @@ jobs:
test: test:
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
strategy: strategy:
fail-fast: false
matrix: matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest] operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Clear tool cache - name: Clear tool cache (macOS)
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" if: runner.os == 'macos'
- name: Setup dotnet 3.0.100 run: |
echo $PATH
dotnet --info
rm -rf "/Users/runner/.dotnet"
- name: Clear tool cache (Ubuntu)
if: runner.os == 'linux'
run: |
echo $PATH
dotnet --info
rm -rf "/usr/share/dotnet"
- name: Clear tool cache (Windows)
if: runner.os == 'windows'
run: |
echo $env:PATH
dotnet --info
Remove-Item $env:LocalAppData\Microsoft\dotnet/* -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item "$env:ProgramFiles\dotnet/*" -Recurse -Force -ErrorAction SilentlyContinue
# Side-by-side install of 2.2 and 3.1 used for the test project
- name: Setup dotnet 2.2.402
uses: ./ uses: ./
with: with:
dotnet-version: 3.0.100 dotnet-version: 2.2.402
- name: Setup dotnet 3.1.201
uses: ./
with:
dotnet-version: 3.1.201
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place # We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place
source-url: https://api.nuget.org/v3/index.json source-url: https://api.nuget.org/v3/index.json
env: env:
NUGET_AUTH_TOKEN: NOTATOKEN NUGET_AUTH_TOKEN: NOTATOKEN
- name: Verify dotnet - name: Verify dotnet
if: runner.os != 'windows' if: runner.os != 'windows'
run: __tests__/verify-dotnet.sh 3.0.100 run: __tests__/verify-dotnet.sh 3.1.201 2.2.402
- name: Verify dotnet (Windows) - name: Verify dotnet (Windows)
if: runner.os == 'windows' if: runner.os == 'windows'
run: __tests__/verify-dotnet.ps1 3.0.100 run: __tests__/verify-dotnet.ps1 3.1.201
test-proxy: test-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -65,37 +89,42 @@ jobs:
- 3128:3128 - 3128:3128
env: env:
https_proxy: http://squid-proxy:3128 https_proxy: http://squid-proxy:3128
http_proxy: http://squid-proxy:3128
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Clear tool cache - name: Clear tool cache
run: rm -rf $RUNNER_TOOL_CACHE/* run: rm -rf "/usr/share/dotnet"
- name: Setup dotnet 3.0.100 - name: Install curl
run: |
apt update
apt -y install curl
- name: Setup dotnet 3.1.201
uses: ./ uses: ./
with: with:
dotnet-version: 3.0.100 dotnet-version: 3.1.201
source-url: https://api.nuget.org/v3/index.json source-url: https://api.nuget.org/v3/index.json
env: env:
NUGET_AUTH_TOKEN: NOTATOKEN NUGET_AUTH_TOKEN: NOTATOKEN
- name: Verify dotnet - name: Verify dotnet
run: __tests__/verify-dotnet.sh 3.0.100 run: __tests__/verify-dotnet.sh 3.1.201
test-bypass-proxy: test-bypass-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
https_proxy: http://no-such-proxy:3128 https_proxy: http://no-such-proxy:3128
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Clear tool cache - name: Clear tool cache
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old" run: rm -rf "/usr/share/dotnet"
- name: Setup dotnet 3.0.100 - name: Setup dotnet 3.1.201
uses: ./ uses: ./
with: with:
dotnet-version: 3.0.100 dotnet-version: 3.1.201
source-url: https://api.nuget.org/v3/index.json source-url: https://api.nuget.org/v3/index.json
env: env:
NUGET_AUTH_TOKEN: NOTATOKEN NUGET_AUTH_TOKEN: NOTATOKEN
- name: Verify dotnet - name: Verify dotnet
run: __tests__/verify-dotnet.sh 3.0.100 run: __tests__/verify-dotnet.sh 3.1.201

3
.gitignore vendored
View File

@ -95,4 +95,5 @@ typings/
# DynamoDB Local files # DynamoDB Local files
.dynamodb/ .dynamodb/
.vscode/* # Ignore .vscode files
.vscode/

View File

@ -81,7 +81,11 @@ describe('authutil tests', () => {
beforeEach(async () => { beforeEach(async () => {
await io.rmRF(fakeSourcesDirForTesting); await io.rmRF(fakeSourcesDirForTesting);
await io.mkdirP(fakeSourcesDirForTesting); await io.mkdirP(fakeSourcesDirForTesting);
}, 100000); }, 30000);
afterAll(async () => {
await io.rmRF(fakeSourcesDirForTesting);
}, 30000);
beforeEach(() => { beforeEach(() => {
if (fs.existsSync(nugetConfigFile)) { if (fs.existsSync(nugetConfigFile)) {

View File

@ -73,6 +73,9 @@ describe('version tests', () => {
describe('installer tests', () => { describe('installer tests', () => {
beforeAll(async () => { beforeAll(async () => {
process.env.RUNNER_TOOL_CACHE = toolDir;
process.env.DOTNET_INSTALL_DIR = toolDir;
process.env.RUNNER_TEMP = tempDir;
await io.rmRF(toolDir); await io.rmRF(toolDir);
await io.rmRF(tempDir); await io.rmRF(tempDir);
}); });
@ -84,23 +87,21 @@ describe('installer tests', () => {
} catch { } catch {
console.log('Failed to remove test directories'); console.log('Failed to remove test directories');
} }
}, 100000); }, 30000);
it('Resolving a normal generic version works', async () => { it('Resolving a normal generic version works', async () => {
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.x'); const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.x');
let versInfo = await dotnetInstaller.resolveInfos( let versInfo = await dotnetInstaller.resolveVersion(
['win-x64'],
new installer.DotNetVersionInfo('3.1.x') new installer.DotNetVersionInfo('3.1.x')
); );
expect(versInfo.resolvedVersion.startsWith('3.1.')); expect(versInfo.startsWith('3.1.'));
}, 100000); }, 100000);
it('Resolving a nonexistent generic version fails', async () => { it('Resolving a nonexistent generic version fails', async () => {
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x'); const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
try { try {
await dotnetInstaller.resolveInfos( await dotnetInstaller.resolveVersion(
['win-x64'],
new installer.DotNetVersionInfo('999.1.x') new installer.DotNetVersionInfo('999.1.x')
); );
fail(); fail();
@ -111,53 +112,47 @@ describe('installer tests', () => {
it('Resolving a exact stable version works', async () => { it('Resolving a exact stable version works', async () => {
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.201'); const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.201');
let versInfo = await dotnetInstaller.resolveInfos( let versInfo = await dotnetInstaller.resolveVersion(
['win-x64'],
new installer.DotNetVersionInfo('3.1.201') new installer.DotNetVersionInfo('3.1.201')
); );
expect(versInfo.resolvedVersion).toBe('3.1.201'); expect(versInfo).toBe('3.1.201');
}, 100000); }, 100000);
it('Resolving a exact preview version works', async () => { it('Resolving a exact preview version works', async () => {
const dotnetInstaller = new installer.DotnetCoreInstaller( const dotnetInstaller = new installer.DotnetCoreInstaller(
'5.0.0-preview.4' '5.0.0-preview.6'
); );
let versInfo = await dotnetInstaller.resolveInfos( let versInfo = await dotnetInstaller.resolveVersion(
['win-x64'], new installer.DotNetVersionInfo('5.0.0-preview.6')
new installer.DotNetVersionInfo('5.0.0-preview.4')
); );
expect(versInfo.resolvedVersion).toBe('5.0.0-preview.4'); expect(versInfo).toBe('5.0.0-preview.6');
}, 100000); }, 100000);
it('Acquires version of dotnet if no matching version is installed', async () => { it('Acquires version of dotnet if no matching version is installed', async () => {
await getDotnet('2.2.205'); await getDotnet('3.1.201');
const dotnetDir = path.join(toolDir, 'dncs', '2.2.205', os.arch()); expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true);
if (IS_WINDOWS) { if (IS_WINDOWS) {
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true); expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
} else { } else {
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true); expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
} }
}, 400000); //This needs some time to download on "slower" internet connections }, 400000); //This needs some time to download on "slower" internet connections
it('Acquires version of dotnet if no matching version is installed', async () => { it('Acquires version of dotnet from global.json if no matching version is installed', async () => {
const dotnetDir = path.join(toolDir, 'dncs', '2.2.105', os.arch());
const globalJsonPath = path.join(process.cwd(), 'global.json'); const globalJsonPath = path.join(process.cwd(), 'global.json');
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "2.2.105"${os.EOL}}${os.EOL}}`; const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.1.201"${os.EOL}}${os.EOL}}`;
if (!fs.existsSync(globalJsonPath)) { if (!fs.existsSync(globalJsonPath)) {
fs.writeFileSync(globalJsonPath, jsonContents); fs.writeFileSync(globalJsonPath, jsonContents);
} }
await setup.run(); await setup.run();
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true); expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
if (IS_WINDOWS) { if (IS_WINDOWS) {
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true); expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
} else { } else {
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true); expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
} }
fs.unlinkSync(globalJsonPath); fs.unlinkSync(globalJsonPath);
}, 100000); }, 100000);
@ -170,30 +165,7 @@ describe('installer tests', () => {
thrown = true; thrown = true;
} }
expect(thrown).toBe(true); expect(thrown).toBe(true);
}, 100000); }, 30000);
it('Uses version of dotnet installed in cache', async () => {
const dotnetDir: string = path.join(toolDir, 'dncs', '250.0.0', os.arch());
await io.mkdirP(dotnetDir);
fs.writeFileSync(`${dotnetDir}.complete`, 'hello');
// This will throw if it doesn't find it in the cache (because no such version exists)
await getDotnet('250.0.0');
return;
});
it('Doesnt use version of dotnet that was only partially installed in cache', async () => {
const dotnetDir: string = path.join(toolDir, 'dncs', '251.0.0', os.arch());
await io.mkdirP(dotnetDir);
let thrown = false;
try {
// This will throw if it doesn't find it in the cache (because no such version exists)
await getDotnet('251.0.0');
} catch {
thrown = true;
}
expect(thrown).toBe(true);
return;
});
it('Uses an up to date bash download script', async () => { it('Uses an up to date bash download script', async () => {
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], { const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
@ -213,7 +185,7 @@ describe('installer tests', () => {
expect(normalizeFileContents(currentContents)).toBe( expect(normalizeFileContents(currentContents)).toBe(
normalizeFileContents(upToDateContents) normalizeFileContents(upToDateContents)
); );
}, 100000); }, 30000);
it('Uses an up to date powershell download script', async () => { it('Uses an up to date powershell download script', async () => {
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], { var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
@ -233,7 +205,7 @@ describe('installer tests', () => {
expect(normalizeFileContents(currentContents)).toBe( expect(normalizeFileContents(currentContents)).toBe(
normalizeFileContents(upToDateContents) normalizeFileContents(upToDateContents)
); );
}, 100000); }, 30000);
}); });
function normalizeFileContents(contents: string): string { function normalizeFileContents(contents: string): string {

View File

@ -1,14 +1,15 @@
using System; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json; using System;
namespace sample_csproj namespace sample_csproj
{ {
class Program [TestClass]
public class Program
{ {
static void Main(string[] args) [TestMethod]
public void TestMethod1()
{ {
var json = JsonConvert.SerializeObject(new[] {"Hello", "World!" }); Console.WriteLine("Hello, World!");
Console.WriteLine(json);
} }
} }
} }

View File

@ -1,7 +0,0 @@
{
"runtimeOptions": {
"configProperties": {
"System.Globalization.Invariant": true
}
}
}

View File

@ -1,13 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <TargetFrameworks>netcoreapp3.1;netcoreapp2.2</TargetFrameworks>
<TargetFramework>netcoreapp3.0</TargetFramework>
<RootNamespace>sample_csproj</RootNamespace> <RootNamespace>sample_csproj</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <!-- These packages will be downloaded over the network for testing proxy settings -->
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,48 @@
import io = require('@actions/io');
import fs = require('fs');
import os = require('os');
import path = require('path');
const toolDir = path.join(__dirname, 'runner', 'tools2');
const tempDir = path.join(__dirname, 'runner', 'temp2');
import * as setup from '../src/setup-dotnet';
const IS_WINDOWS = process.platform === 'win32';
describe('setup-dotnet tests', () => {
beforeAll(async () => {
process.env.RUNNER_TOOL_CACHE = toolDir;
process.env.DOTNET_INSTALL_DIR = toolDir;
process.env.RUNNER_TEMP = tempDir;
await io.rmRF(toolDir);
await io.rmRF(tempDir);
});
afterAll(async () => {
try {
await io.rmRF(path.join(process.cwd(), 'global.json'));
await io.rmRF(toolDir);
await io.rmRF(tempDir);
} catch {
console.log('Failed to remove test directories');
}
}, 30000);
it('Acquires version of dotnet if no matching version is installed', async () => {
const globalJsonPath = path.join(process.cwd(), 'global.json');
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.1.201"${os.EOL}}${os.EOL}}`;
if (!fs.existsSync(globalJsonPath)) {
fs.writeFileSync(globalJsonPath, jsonContents);
}
await setup.run();
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
}
fs.unlinkSync(globalJsonPath);
}, 100000);
});

View File

@ -13,13 +13,23 @@ Write-Host "Found '$dotnet'"
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() } $version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
Write-Host "Version $version" Write-Host "Version $version"
# if ($version -ne $args[0]) if ($version -ne $args[0])
# { {
# Write-Host "PATH='$env:path'" Write-Host "PATH='$env:path'"
# Write-Host "gcm dotnet:" throw "Unexpected version"
# gcm dotnet | fl }
# throw "Unexpected version"
# } if ($args[1])
{
# SDKs are listed on multiple lines with the path afterwards in square brackets
$version = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
Write-Host "Version $version"
if (-not ($version -contains $args[1]))
{
Write-Host "PATH='$env:path'"
throw "Unexpected version"
}
}
Write-Host "Building sample csproj" Write-Host "Building sample csproj"
& $dotnet build __tests__/sample-csproj/ --no-cache & $dotnet build __tests__/sample-csproj/ --no-cache
@ -29,9 +39,20 @@ if ($LASTEXITCODE -ne 0)
} }
Write-Host "Testing compiled app" Write-Host "Testing compiled app"
$sample_output = "$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample.exe)".Trim() $sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
Write-Host "Sample output: $sample_output" Write-Host "Sample output: $sample_output"
if ($sample_output -notlike "*Hello*World*") # For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
if ($args[1])
{ {
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
{
throw "Unexpected output" throw "Unexpected output"
}
}
else
{
if ($sample_output -notlike "*Test Run Successful.*")
{
throw "Unexpected output"
}
} }

View File

@ -15,13 +15,30 @@ if [ -z "$(echo $dotnet_version | grep $1)" ]; then
exit 1 exit 1
fi fi
if [ -n "$2" ]; then
dotnet_version="$(dotnet --list-sdks)"
echo "Found dotnet version '$dotnet_version'"
if [ -z "$(echo $dotnet_version | grep $2)" ]; then
echo "Unexpected version"
exit 1
fi
fi
echo "Building sample csproj" echo "Building sample csproj"
dotnet build __tests__/sample-csproj/ --no-cache || exit 1 dotnet build __tests__/sample-csproj/ --no-cache || exit 1
echo "Testing compiled app" echo "Testing compiled app"
sample_output="$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample)" sample_output=$(dotnet test __tests__/sample-csproj/ --no-build)
echo "Sample output: $sample_output" echo "Sample output: $sample_output"
if [ -z "$(echo $sample_output | grep Hello)" ]; then # For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
if [ -n "$2" ]; then
if [ -z "$(echo $sample_output | grep "Test Run Successful.*Test Run Successful.")" ]; then
echo "Unexpected output" echo "Unexpected output"
exit 1 exit 1
fi
else
if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then
echo "Unexpected output"
exit 1
fi
fi fi

1563
dist/index.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,192 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) .NET Foundation and contributors. All rights reserved.
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
#
# Stop script on NZEC
set -e
# Stop script if unbound variable found (use ${var:-} if intentional)
set -u
# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
# This is causing it to fail
set -o pipefail
# Use in the the functions: eval $invocation
invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
# standard output may be used as a return value in the functions
# we need a way to write text on the screen in the functions so that
# it won't interfere with the return value.
# Exposing stream 3 as a pipe to standard output of the script itself
exec 3>&1
say_err() {
printf "%b\n" "get-os-distro: Error: $1" >&2
}
# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
# then and only then should the Linux distribution appear in this list.
# Adding a Linux distribution to this list does not imply distribution-specific support.
get_legacy_os_name_from_platform() {
platform="$1"
case "$platform" in
"centos.7")
echo "centos"
return 0
;;
"debian.8")
echo "debian"
return 0
;;
"fedora.23")
echo "fedora.23"
return 0
;;
"fedora.27")
echo "fedora.27"
return 0
;;
"fedora.24")
echo "fedora.24"
return 0
;;
"opensuse.13.2")
echo "opensuse.13.2"
return 0
;;
"opensuse.42.1")
echo "opensuse.42.1"
return 0
;;
"opensuse.42.3")
echo "opensuse.42.3"
return 0
;;
"rhel.7"*)
echo "rhel"
return 0
;;
"ubuntu.14.04")
echo "ubuntu"
return 0
;;
"ubuntu.16.04")
echo "ubuntu.16.04"
return 0
;;
"ubuntu.16.10")
echo "ubuntu.16.10"
return 0
;;
"ubuntu.18.04")
echo "ubuntu.18.04"
return 0
;;
"alpine.3.4.3")
echo "alpine"
return 0
;;
esac
return 1
}
get_linux_platform_name() {
if [ -e /etc/os-release ]; then
. /etc/os-release
echo "$ID.$VERSION_ID"
return 0
elif [ -e /etc/redhat-release ]; then
local redhatRelease=$(</etc/redhat-release)
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]; then
echo "rhel.6"
return 0
fi
fi
say_err "Linux specific platform name and version could not be detected: UName = $uname"
return 1
}
get_current_os_name() {
local uname=$(uname)
if [ "$uname" = "Darwin" ]; then
echo "osx"
return 0
elif [ "$uname" = "Linux" ]; then
local linux_platform_name
linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; }
if [[ $linux_platform_name == "rhel.6" ]]; then
echo "$linux_platform_name"
return 0
elif [[ $linux_platform_name == alpine* ]]; then
echo "linux-musl"
return 0
else
echo "linux"
return 0
fi
fi
say_err "OS name could not be detected: UName = $uname"
return 1
}
get_legacy_os_name() {
local uname=$(uname)
if [ "$uname" = "Darwin" ]; then
echo "osx"
return 0
else
if [ -e /etc/os-release ]; then
. /etc/os-release
os=$(get_legacy_os_name_from_platform "$ID.$VERSION_ID" || echo "")
if [ -n "$os" ]; then
echo "$os"
return 0
fi
fi
fi
say_err "Distribution specific OS name and version could not be detected: UName = $uname"
return 1
}
get_machine_architecture() {
if command -v uname > /dev/null; then
CPUName=$(uname -m)
case $CPUName in
armv7l)
echo "arm"
return 0
;;
aarch64)
echo "arm64"
return 0
;;
esac
fi
# Always default to 'x64'
echo "x64"
return 0
}
osName=$(get_current_os_name || echo "")
legacyOsName=$(get_legacy_os_name || echo "")
arch=$(get_machine_architecture || echo "")
primaryName="$osName-$arch"
legacyName="$legacyOsName"
echo "Primary:$primaryName"
echo "Legacy:$legacyName"
if [ -z "$osName" ] && [ -z "$legacyOsName" ];then
exit 1
fi

View File

@ -1,18 +0,0 @@
function Get-Machine-Architecture()
{
# possible values: AMD64, IA64, x86
return $ENV:PROCESSOR_ARCHITECTURE
}
function Get-CLIArchitecture-From-Architecture([string]$Architecture)
{
switch ($Architecture.ToLower())
{
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
{ $_ -eq "x86" } { return "x86" }
default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" }
}
}
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture)
Write-Output "Primary:win-$CLIArchitecture"

110
package-lock.json generated
View File

@ -32,6 +32,13 @@
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "0.0.6"
},
"dependencies": {
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
}
} }
}, },
"@actions/io": { "@actions/io": {
@ -39,19 +46,6 @@
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz",
"integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" "integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg=="
}, },
"@actions/tool-cache": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.3.1.tgz",
"integrity": "sha512-sKoEJv0/c7WzjPEq2PO12Sc8QdEp58XIBHMm3c4lUn/iZWgLz9HBeCuFGpLQjDvXJNfLZ4g+WD+rMjgOmpH4Ag==",
"requires": {
"@actions/core": "^1.2.0",
"@actions/exec": "^1.0.0",
"@actions/http-client": "^1.0.3",
"@actions/io": "^1.0.1",
"semver": "^6.1.0",
"uuid": "^3.3.2"
}
},
"@babel/code-frame": { "@babel/code-frame": {
"version": "7.8.3", "version": "7.8.3",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
@ -478,6 +472,14 @@
"jest-message-util": "^26.0.1", "jest-message-util": "^26.0.1",
"jest-util": "^26.0.1", "jest-util": "^26.0.1",
"slash": "^3.0.0" "slash": "^3.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"@jest/core": { "@jest/core": {
@ -513,6 +515,14 @@
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"slash": "^3.0.0", "slash": "^3.0.0",
"strip-ansi": "^6.0.0" "strip-ansi": "^6.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"@jest/environment": { "@jest/environment": {
@ -581,6 +591,14 @@
"string-length": "^4.0.1", "string-length": "^4.0.1",
"terminal-link": "^2.0.0", "terminal-link": "^2.0.0",
"v8-to-istanbul": "^4.1.3" "v8-to-istanbul": "^4.1.3"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"@jest/source-map": { "@jest/source-map": {
@ -640,6 +658,14 @@
"slash": "^3.0.0", "slash": "^3.0.0",
"source-map": "^0.6.1", "source-map": "^0.6.1",
"write-file-atomic": "^3.0.0" "write-file-atomic": "^3.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"@jest/types": { "@jest/types": {
@ -964,9 +990,9 @@
"dev": true "dev": true
}, },
"@types/semver": { "@types/semver": {
"version": "6.0.1", "version": "6.2.1",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-6.2.1.tgz",
"integrity": "sha512-ffCdcrEE5h8DqVxinQjo+2d1q+FV5z7iNtPofw3JsrltSoSVlOGaW0rY8XxtO9XukdTn8TaCGWmk2VFGhI70mg==", "integrity": "sha512-+beqKQOh9PYxuHvijhVl+tIHvT6tuwOrE9m14zd+MT2A38KoKZhh7pYJ0SNleLtwDsiIxHDsIk9bv01oOxvSvA==",
"dev": true "dev": true
}, },
"@types/stack-utils": { "@types/stack-utils": {
@ -1176,6 +1202,14 @@
"chalk": "^4.0.0", "chalk": "^4.0.0",
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"slash": "^3.0.0" "slash": "^3.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"babel-plugin-istanbul": { "babel-plugin-istanbul": {
@ -2304,6 +2338,14 @@
"please-upgrade-node": "^3.2.0", "please-upgrade-node": "^3.2.0",
"slash": "^3.0.0", "slash": "^3.0.0",
"which-pm-runs": "^1.0.0" "which-pm-runs": "^1.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"iconv-lite": { "iconv-lite": {
@ -2938,6 +2980,14 @@
"micromatch": "^4.0.2", "micromatch": "^4.0.2",
"slash": "^3.0.0", "slash": "^3.0.0",
"stack-utils": "^2.0.2" "stack-utils": "^2.0.2"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"jest-mock": { "jest-mock": {
@ -2975,6 +3025,14 @@
"read-pkg-up": "^7.0.1", "read-pkg-up": "^7.0.1",
"resolve": "^1.17.0", "resolve": "^1.17.0",
"slash": "^3.0.0" "slash": "^3.0.0"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"jest-resolve-dependencies": { "jest-resolve-dependencies": {
@ -3047,6 +3105,14 @@
"slash": "^3.0.0", "slash": "^3.0.0",
"strip-bom": "^4.0.0", "strip-bom": "^4.0.0",
"yargs": "^15.3.1" "yargs": "^15.3.1"
},
"dependencies": {
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
}
} }
}, },
"jest-serializer": { "jest-serializer": {
@ -4345,12 +4411,6 @@
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
"dev": true "dev": true
}, },
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
"dev": true
},
"snapdragon": { "snapdragon": {
"version": "0.8.2", "version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@ -4823,7 +4883,8 @@
"tunnel": { "tunnel": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==" "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"dev": true
}, },
"tunnel-agent": { "tunnel-agent": {
"version": "0.6.0", "version": "0.6.0",
@ -4960,7 +5021,8 @@
"uuid": { "uuid": {
"version": "3.3.2", "version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"dev": true
}, },
"v8-to-istanbul": { "v8-to-istanbul": {
"version": "4.1.4", "version": "4.1.4",

View File

@ -35,7 +35,6 @@
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/http-client": "^1.0.8", "@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.3.1",
"fast-xml-parser": "^3.15.1", "fast-xml-parser": "^3.15.1",
"semver": "^6.3.0", "semver": "^6.3.0",
"xmlbuilder": "^13.0.2" "xmlbuilder": "^13.0.2"
@ -52,5 +51,8 @@
"ts-jest": "^26.0.0", "ts-jest": "^26.0.0",
"typescript": "^3.9.3", "typescript": "^3.9.3",
"wget-improved": "^3.2.1" "wget-improved": "^3.2.1"
},
"jest": {
"testEnvironment": "node"
} }
} }

View File

@ -1,40 +1,26 @@
// 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 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 hc = require('@actions/http-client'); import hc = require('@actions/http-client');
import {chmodSync} from 'fs'; import {chmodSync} from 'fs';
import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import {ExecOptions} from '@actions/exec/lib/interfaces';
import * as semver from 'semver'; import * as semver from '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');
}
/** /**
* Represents the inputted version information * Represents the inputted version information
*/ */
export class DotNetVersionInfo { export class DotNetVersionInfo {
public inputVersion: string;
private fullversion: string; private fullversion: string;
private isExactVersionSet: boolean = false; private isExactVersionSet: boolean = false;
constructor(version: string) { constructor(version: string) {
this.inputVersion = version;
// Check for exact match // Check for exact match
if (semver.valid(semver.clean(version) || '') != null) { if (semver.valid(semver.clean(version) || '') != null) {
this.fullversion = semver.clean(version) as string; this.fullversion = semver.clean(version) as string;
@ -89,91 +75,54 @@ export class DotNetVersionInfo {
} }
} }
/**
* Represents a resolved version from the Web-Api
*/
class ResolvedVersionInfo {
downloadUrls: string[];
resolvedVersion: string;
constructor(downloadUrls: string[], resolvedVersion: string) {
if (downloadUrls.length === 0) {
throw 'DownloadUrls can not be empty';
}
if (!resolvedVersion) {
throw 'Resolved version is invalid';
}
this.downloadUrls = downloadUrls;
this.resolvedVersion = resolvedVersion;
}
}
export class DotnetCoreInstaller { export class DotnetCoreInstaller {
constructor(version: string) { constructor(version: string) {
this.versionInfo = new DotNetVersionInfo(version); this.version = version;
this.cachedToolName = 'dncs';
this.arch = 'x64';
} }
public async installDotnet() { public async installDotnet() {
// Check cache let output = '';
let toolPath: string = ''; let resultCode = 0;
let osSuffixes = await this.detectMachineOS();
let parts = osSuffixes[0].split('-');
if (parts.length > 1) {
this.arch = parts[1];
}
// If version is not generic -> look up cache let calculatedVersion = await this.resolveVersion(
if (this.versionInfo.isExactVersion()) new DotNetVersionInfo(this.version)
toolPath = this.getLocalTool(this.versionInfo.version());
if (!toolPath) {
// download, extract, cache
console.log('Getting a download url', this.versionInfo.version());
let resolvedVersionInfo = await this.resolveInfos(
osSuffixes,
this.versionInfo
); );
//Check if cache exists for resolved version var envVariables: {[key: string]: string} = {};
toolPath = this.getLocalTool(resolvedVersionInfo.resolvedVersion); for (let key in process.env) {
if (!toolPath) { if (process.env[key]) {
//If not exists install it let value: any = process.env[key];
toolPath = await this.downloadAndInstall(resolvedVersionInfo); envVariables[key] = value;
} else {
console.log('Using cached tool');
} }
} 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(version: string): string {
console.log('Checking tool cache', version);
return tc.find(this.cachedToolName, version, this.arch);
}
private async detectMachineOS(): Promise<string[]> {
let osSuffix: string[] = [];
let output = '';
let resultCode = 0;
if (IS_WINDOWS) { if (IS_WINDOWS) {
let escapedScript = path let escapedScript = path
.join(__dirname, '..', 'externals', 'get-os-platform.ps1') .join(__dirname, '..', 'externals', 'install-dotnet.ps1')
.replace(/'/g, "''"); .replace(/'/g, "''");
let command = `& '${escapedScript}'`; let command = `& '${escapedScript}'`;
if (calculatedVersion) {
command += ` -Version ${calculatedVersion}`;
}
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']}`;
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
const powershellPath = await io.which('powershell', true); const powershellPath = await io.which('powershell', true);
var options: ExecOptions = {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
},
env: envVariables
};
resultCode = await exec.exec( resultCode = await exec.exec(
`"${powershellPath}"`, `"${powershellPath}"`,
[ [
@ -186,98 +135,63 @@ export class DotnetCoreInstaller {
'-Command', '-Command',
command command
], ],
{ options
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
}
}
); );
} else { } else {
let scriptPath = path.join( let escapedScript = path
__dirname, .join(__dirname, '..', 'externals', 'install-dotnet.sh')
'..', .replace(/'/g, "''");
'externals', chmodSync(escapedScript, '777');
'get-os-distro.sh'
);
chmodSync(scriptPath, '777');
const toolPath = await io.which(scriptPath, true); const scriptPath = await io.which(escapedScript, true);
resultCode = await exec.exec(`"${toolPath}"`, [], {
let scriptArguments: string[] = [];
if (this.version) {
scriptArguments.push('--version', this.version);
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
resultCode = await exec.exec(`"${scriptPath}"`, scriptArguments, {
listeners: { listeners: {
stdout: (data: Buffer) => { stdout: (data: Buffer) => {
output += data.toString(); output += data.toString();
} }
} },
env: envVariables
}); });
} }
if (resultCode != 0) { if (process.env['DOTNET_INSTALL_DIR']) {
throw `Failed to detect os with result code ${resultCode}. Output: ${output}`; core.addPath(process.env['DOTNET_INSTALL_DIR']);
} } else {
if (IS_WINDOWS) {
let index; // This is the default set in install-dotnet.ps1
if ((index = output.indexOf('Primary:')) >= 0) { core.addPath(
let primary = output.substr(index + 'Primary:'.length).split(os.EOL)[0]; path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
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(resolvedVersionInfo: ResolvedVersionInfo) {
let downloaded = false;
let downloadPath = '';
for (const url of resolvedVersionInfo.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,
resolvedVersionInfo.resolvedVersion,
this.arch
); );
core.exportVariable(
console.log('Successfully installed', resolvedVersionInfo.resolvedVersion); 'DOTNET_ROOT',
return cachedDir; path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
);
} else {
// This is the default set in install-dotnet.sh
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
}
}
console.log(process.env['PATH']);
if (resultCode != 0) {
throw `Failed to install dotnet ${resultCode}. ${output}`;
}
} }
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
// Type - SDK / Runtime
// versionInfo - versionInfo of the SDK/Runtime // versionInfo - versionInfo of the SDK/Runtime
async resolveInfos( async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
osSuffixes: string[], if (versionInfo.isExactVersion()) {
versionInfo: DotNetVersionInfo return versionInfo.version();
): Promise<ResolvedVersionInfo> { }
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
allowRetries: true, allowRetries: true,
maxRetries: 3 maxRetries: 3
@ -305,67 +219,23 @@ export class DotnetCoreInstaller {
}); });
// Exclude versions that are newer than the latest if using not exact // Exclude versions that are newer than the latest if using not exact
if (!versionInfo.isExactVersion()) {
let latestSdk: string = releasesResult['latest-sdk']; let latestSdk: string = releasesResult['latest-sdk'];
releasesInfo = releasesInfo.filter((releaseInfo: any) => releasesInfo = releasesInfo.filter((releaseInfo: any) =>
semver.lte(releaseInfo['sdk']['version'], latestSdk) semver.lte(releaseInfo['sdk']['version'], latestSdk)
); );
}
// Sort for latest version // Sort for latest version
releasesInfo = releasesInfo.sort((a, b) => releasesInfo = releasesInfo.sort((a, b) =>
semver.rcompare(a['sdk']['version'], b['sdk']['version']) semver.rcompare(a['sdk']['version'], b['sdk']['version'])
); );
let downloadedVersion: string = ''; if (releasesInfo.length == 0) {
let downloadUrls: string[] = []; throw `Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`;
}
if (releasesInfo.length != 0) {
let release = releasesInfo[0]; let release = releasesInfo[0];
return release['sdk']['version'];
downloadedVersion = release['sdk']['version'];
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 ${versionInfo.version()}`
);
if (versionInfo.isExactVersion()) {
console.log('Using fallback');
downloadUrls = await this.getFallbackDownloadUrls(
versionInfo.version()
);
downloadedVersion = versionInfo.version();
} else {
console.log('Unable to use fallback, version is generic!');
}
}
if (downloadUrls.length == 0) {
throw `Could not construct download URL. Please ensure that specified version ${versionInfo.version()}/${downloadedVersion} is valid.`;
}
core.debug(`Got download urls ${downloadUrls}`);
return new ResolvedVersionInfo(downloadUrls, downloadedVersion);
} }
private async getReleasesJsonUrl( private async getReleasesJsonUrl(
@ -391,108 +261,7 @@ export class DotnetCoreInstaller {
return releasesInfo[0]['releases.json']; return releasesInfo[0]['releases.json'];
} }
private async getFallbackDownloadUrls(version: string): Promise<string[]> { private version: string;
let primaryUrlSearchString: string;
let legacyUrlSearchString: string;
let output = '';
let resultCode = 0;
if (IS_WINDOWS) {
let escapedScript = path
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
.replace(/'/g, "''");
let command = `& '${escapedScript}' -Version ${version} -DryRun`;
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();
}
}
}
);
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
} else {
let escapedScript = path
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
.replace(/'/g, "''");
chmodSync(escapedScript, '777');
const scriptPath = await io.which(escapedScript, true);
resultCode = await exec.exec(
`"${scriptPath}"`,
['--version', version, '--dry-run'],
{
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
}
}
);
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
}
if (resultCode != 0) {
throw `Failed to get download urls with result code ${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 versionInfo: DotNetVersionInfo;
private cachedToolName: string;
private arch: string;
} }
const DotNetCoreIndexUrl: string = const DotNetCoreIndexUrl: string =