mirror of
https://github.com/actions/setup-dotnet.git
synced 2026-03-23 07:02:19 +08:00
Compare commits
1 Commits
v3.4.0
...
e-korolevs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7caa606d47 |
@@ -1,6 +0,0 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!src/
|
||||
51
.eslintrc.js
51
.eslintrc.js
@@ -1,51 +0,0 @@
|
||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:eslint-plugin-jest/recommended',
|
||||
'eslint-config-prettier'
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-require-imports': 'error',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/ban-ts-comment': [
|
||||
'error',
|
||||
{
|
||||
'ts-ignore': 'allow-with-description'
|
||||
}
|
||||
],
|
||||
'no-console': 'error',
|
||||
'yoda': 'error',
|
||||
'prefer-const': [
|
||||
'error',
|
||||
{
|
||||
destructuring: 'all'
|
||||
}
|
||||
],
|
||||
'no-control-regex': 'off',
|
||||
'no-constant-condition': ['error', {checkLoops: false}],
|
||||
'node/no-extraneous-import': 'error'
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/*{test,spec}.ts'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'jest/no-standalone-expect': 'off',
|
||||
'jest/no-conditional-expect': 'off',
|
||||
'no-console': 'off',
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
env: {
|
||||
node: true,
|
||||
es6: true,
|
||||
'jest/globals': true
|
||||
}
|
||||
};
|
||||
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -1,2 +1 @@
|
||||
* text=auto eol=lf
|
||||
.licenses/** -diff linguist-generated=true
|
||||
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -1 +1,2 @@
|
||||
* @actions/runner-images-team
|
||||
* @actions/setup-actions-team
|
||||
|
||||
2
.github/workflows/basic-validation.yml
vendored
2
.github/workflows/basic-validation.yml
vendored
@@ -14,4 +14,4 @@ on:
|
||||
jobs:
|
||||
call-basic-validation:
|
||||
name: Basic validation
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
||||
2
.github/workflows/check-dist.yml
vendored
2
.github/workflows/check-dist.yml
vendored
@@ -14,4 +14,4 @@ on:
|
||||
jobs:
|
||||
call-check-dist:
|
||||
name: Check dist/
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
||||
8
.github/workflows/codeql-analysis.yml
vendored
8
.github/workflows/codeql-analysis.yml
vendored
@@ -2,13 +2,13 @@ name: CodeQL analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '0 3 * * 0'
|
||||
|
||||
jobs:
|
||||
call-codeQL-analysis:
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||
name: CodeQL analysis
|
||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
||||
355
.github/workflows/e2e-tests.yml
vendored
355
.github/workflows/e2e-tests.yml
vendored
@@ -17,14 +17,14 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet 2.2.402, 3.1.404 and 3.0.x
|
||||
- name: Setup dotnet 2.2.402 and 3.1.404
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: |
|
||||
@@ -33,14 +33,14 @@ jobs:
|
||||
3.0.x
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2.402$", "^3.1.404$", "^3.0"
|
||||
run: __tests__/verify-dotnet.ps1 2.2.402 3.1.404 '3.0'
|
||||
|
||||
test-setup-full-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-13]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -60,16 +60,20 @@ jobs:
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify nuget config file
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-Not (Test-Path "../nuget.config")) { throw "nuget file not generated correctly" }
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$", "^2.2.402$" -CheckNugetConfig
|
||||
run: __tests__/verify-dotnet.ps1 3.1.201 2.2.402
|
||||
|
||||
test-setup-without-patch-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -87,34 +91,38 @@ jobs:
|
||||
dotnet-version: '2.2'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1", "^2.2"
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
test-setup-prerelease-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-13]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet '2.2'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '2.2'
|
||||
- name: Setup dotnet '3.1.100-preview1-014459'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '3.1.100-preview1-014459'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "3.1.100-preview1-014459"
|
||||
run: __tests__/verify-dotnet.ps1 3.1.100-preview1-014459
|
||||
|
||||
test-setup-latest-patch-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -131,35 +139,14 @@ jobs:
|
||||
dotnet-version: 2.2.X
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"
|
||||
|
||||
test-ABCxx-syntax:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.4xx
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '6.0.4xx'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^6\.0\.4\d{2}"
|
||||
run: __tests__/verify-dotnet.ps1 '2.2' '3.1'
|
||||
|
||||
test-setup-with-wildcard:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -176,14 +163,14 @@ jobs:
|
||||
dotnet-version: 2.2.*
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1", "^2.2"
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
test-setup-global-json-specified-and-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -194,7 +181,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir subdirectory
|
||||
echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||
echo '{"sdk":{"version": "2.2","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||
- name: Setup dotnet
|
||||
uses: ./
|
||||
with:
|
||||
@@ -202,173 +189,91 @@ jobs:
|
||||
global-json-file: ./subdirectory/global.json
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"
|
||||
|
||||
test-setup-global-json-only:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Write global.json
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir subdirectory
|
||||
echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||
- name: Setup dotnet
|
||||
uses: ./
|
||||
with:
|
||||
global-json-file: ./subdirectory/global.json
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2"
|
||||
run: __tests__/verify-dotnet.ps1 2.2 3.1
|
||||
|
||||
test-setup-with-dotnet-quality:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 7.0 with preview quality
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '7.0'
|
||||
dotnet-quality: 'preview'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-"
|
||||
|
||||
test-setup-with-cache:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-latest]
|
||||
env:
|
||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Copy NuGet lock file to root
|
||||
shell: bash
|
||||
run: cp ./__tests__/e2e-test-csproj/packages.lock.json ./packages.lock.json
|
||||
- name: Setup .NET Core 3.1
|
||||
id: setup-dotnet
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1
|
||||
cache: true
|
||||
- name: Verify Cache
|
||||
if: steps.setup-dotnet.outputs.cache-hit == 'true'
|
||||
shell: bash
|
||||
run: if [[ -e ${NUGET_PACKAGES} ]]; then exit 0; else exit 1; fi
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1"
|
||||
|
||||
test-setup-with-cache-dependency-path:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-latest]
|
||||
env:
|
||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup .NET Core 3.1
|
||||
id: setup-dotnet
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1
|
||||
cache: true
|
||||
cache-dependency-path: './__tests__/e2e-test-csproj/packages.lock.json'
|
||||
- name: Verify Cache
|
||||
if: steps.setup-dotnet.outputs.cache-hit == 'true'
|
||||
shell: bash
|
||||
run: if [[ -e ${NUGET_PACKAGES} ]]; then exit 0; else exit 1; fi
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1"
|
||||
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 7.0 with preview quality
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: "7.0"
|
||||
dotnet-quality: "preview"
|
||||
- name: Verify preview version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" }
|
||||
|
||||
test-dotnet-version-output-during-single-version-installation:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.401
|
||||
uses: ./
|
||||
id: step1
|
||||
with:
|
||||
dotnet-version: '6.0.401'
|
||||
|
||||
- name: Verify value of the dotnet-version output
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.401
|
||||
uses: ./
|
||||
id: step1
|
||||
with:
|
||||
dotnet-version: "6.0.401"
|
||||
|
||||
- name: Verify value of the dotnet-version output
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
|
||||
|
||||
test-dotnet-version-output-during-multiple-version-installation:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.401, 5.0.408, 7.0.100-rc.1.22431.12
|
||||
uses: ./
|
||||
id: step2
|
||||
with:
|
||||
dotnet-version: |
|
||||
7.0.100-rc.1.22431.12
|
||||
6.0.401
|
||||
5.0.408
|
||||
|
||||
- name: Setup dotnet 6.0.401, 5.0.408, 7.0.100-rc.1.22431.12
|
||||
uses: ./
|
||||
id: step2
|
||||
with:
|
||||
dotnet-version: |
|
||||
7.0.100-rc.1.22431.12
|
||||
6.0.401
|
||||
5.0.408
|
||||
|
||||
- name: Verify value of the dotnet-version output
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = "7.0.100-rc.1.22431.12"
|
||||
if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
|
||||
- name: Verify value of the dotnet-version output
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = "7.0.100-rc.1.22431.12"
|
||||
if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
|
||||
|
||||
test-proxy:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:latest
|
||||
image: mcr.microsoft.com/dotnet/core/runtime-deps:3.0-bionic
|
||||
options: --dns 127.0.0.1
|
||||
services:
|
||||
squid-proxy:
|
||||
@@ -381,41 +286,12 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Powershell
|
||||
- name: Clear tool cache
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Install curl
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y wget apt-transport-https software-properties-common
|
||||
wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
|
||||
dpkg -i packages-microsoft-prod.deb
|
||||
rm packages-microsoft-prod.deb
|
||||
apt-get update
|
||||
apt-get install -y powershell
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet 6.0
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 6.0
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: |
|
||||
__tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-22.04
|
||||
env:
|
||||
https_proxy: http://no-such-proxy:3128
|
||||
no_proxy: github.com,download.visualstudio.microsoft.com,api.nuget.org,builds.dotnet.microsoft.com,ci.dot.net
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
apt update
|
||||
apt -y install curl
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
@@ -424,5 +300,24 @@ jobs:
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$" -CheckNugetConfig
|
||||
run: __tests__/verify-dotnet.sh 3.1.201
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
https_proxy: http://no-such-proxy:3128
|
||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear tool cache
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.201
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify dotnet
|
||||
run: __tests__/verify-dotnet.sh 3.1.201
|
||||
2
.github/workflows/licensed.yml
vendored
2
.github/workflows/licensed.yml
vendored
@@ -12,4 +12,4 @@ on:
|
||||
jobs:
|
||||
call-licensed:
|
||||
name: Licensed
|
||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||
12
.github/workflows/release-new-action-version.yml
vendored
12
.github/workflows/release-new-action-version.yml
vendored
@@ -21,9 +21,9 @@ jobs:
|
||||
name: releaseNewActionVersion
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
id: update-major-tag
|
||||
uses: actions/publish-action@v0.2.2
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
id: update-major-tag
|
||||
uses: actions/publish-action@v0.2.1
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
10
.github/workflows/test-dotnet.yml
vendored
10
.github/workflows/test-dotnet.yml
vendored
@@ -17,8 +17,8 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0']
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -29,7 +29,9 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet-version }}
|
||||
- name: Verify installed version
|
||||
- name: Check installed version
|
||||
shell: pwsh
|
||||
run: |
|
||||
__tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.dotnet-version }}"
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not $version.StartsWith("${{ matrix.dotnet-version }}")) { throw "Unexpected version" }
|
||||
11
.github/workflows/update-config-files.yml
vendored
11
.github/workflows/update-config-files.yml
vendored
@@ -1,11 +0,0 @@
|
||||
name: Update configuration files
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * 0'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
call-update-configuration-files:
|
||||
name: Update configuration files
|
||||
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,8 +3,8 @@ global.json
|
||||
lib/
|
||||
node_modules/
|
||||
__tests__/runner/*
|
||||
__tests__/e2e-test-csproj/bin/
|
||||
__tests__/e2e-test-csproj/obj/
|
||||
__tests__/sample-csproj/bin/
|
||||
__tests__/sample-csproj/obj/
|
||||
|
||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||
# Logs
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run format
|
||||
npm run lint:fix
|
||||
|
||||
@@ -3,4 +3,3 @@
|
||||
|
||||
# Tests are not run at push time since they can take 2-4 minutes to complete
|
||||
npm run format-check
|
||||
npm run lint
|
||||
|
||||
@@ -3,7 +3,6 @@ sources:
|
||||
|
||||
allowed:
|
||||
- apache-2.0
|
||||
- 0bsd
|
||||
- bsd-2-clause
|
||||
- bsd-3-clause
|
||||
- isc
|
||||
@@ -12,5 +11,4 @@ allowed:
|
||||
- unlicense
|
||||
|
||||
reviewed:
|
||||
npm:
|
||||
- sax # ISC + MIT
|
||||
npm:
|
||||
BIN
.licenses/npm/@actions/cache.dep.yml
generated
BIN
.licenses/npm/@actions/cache.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/core.dep.yml
generated
BIN
.licenses/npm/@actions/core.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/glob-0.1.2.dep.yml
generated
BIN
.licenses/npm/@actions/glob-0.1.2.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/glob-0.3.0.dep.yml
generated
BIN
.licenses/npm/@actions/glob-0.3.0.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/abort-controller.dep.yml
generated
BIN
.licenses/npm/@azure/abort-controller.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-auth.dep.yml
generated
BIN
.licenses/npm/@azure/core-auth.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-http.dep.yml
generated
BIN
.licenses/npm/@azure/core-http.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-lro.dep.yml
generated
BIN
.licenses/npm/@azure/core-lro.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-paging.dep.yml
generated
BIN
.licenses/npm/@azure/core-paging.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-tracing.dep.yml
generated
BIN
.licenses/npm/@azure/core-tracing.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-util.dep.yml
generated
BIN
.licenses/npm/@azure/core-util.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/logger.dep.yml
generated
BIN
.licenses/npm/@azure/logger.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/ms-rest-js.dep.yml
generated
BIN
.licenses/npm/@azure/ms-rest-js.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/storage-blob.dep.yml
generated
BIN
.licenses/npm/@azure/storage-blob.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@fastify/busboy.dep.yml
generated
BIN
.licenses/npm/@fastify/busboy.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@opentelemetry/api.dep.yml
generated
BIN
.licenses/npm/@opentelemetry/api.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/plugin-framework.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/plugin-framework.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/plugin.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/plugin.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/protoc.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/protoc.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/runtime-rpc.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/runtime-rpc.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@protobuf-ts/runtime.dep.yml
generated
BIN
.licenses/npm/@protobuf-ts/runtime.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@types/node-fetch.dep.yml
generated
BIN
.licenses/npm/@types/node-fetch.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@types/node.dep.yml
generated
BIN
.licenses/npm/@types/node.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@types/tunnel.dep.yml
generated
BIN
.licenses/npm/@types/tunnel.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/abort-controller.dep.yml
generated
BIN
.licenses/npm/abort-controller.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/asynckit.dep.yml
generated
BIN
.licenses/npm/asynckit.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/balanced-match.dep.yml
generated
BIN
.licenses/npm/balanced-match.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/brace-expansion.dep.yml
generated
BIN
.licenses/npm/brace-expansion.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/combined-stream.dep.yml
generated
BIN
.licenses/npm/combined-stream.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/concat-map.dep.yml
generated
BIN
.licenses/npm/concat-map.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/delayed-stream.dep.yml
generated
BIN
.licenses/npm/delayed-stream.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/event-target-shim.dep.yml
generated
BIN
.licenses/npm/event-target-shim.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/events.dep.yml
generated
BIN
.licenses/npm/events.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/form-data-2.5.1.dep.yml
generated
BIN
.licenses/npm/form-data-2.5.1.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/form-data-3.0.1.dep.yml
generated
BIN
.licenses/npm/form-data-3.0.1.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/form-data-4.0.0.dep.yml
generated
BIN
.licenses/npm/form-data-4.0.0.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/ip-regex.dep.yml
generated
BIN
.licenses/npm/ip-regex.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/mime-db.dep.yml
generated
BIN
.licenses/npm/mime-db.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/mime-types.dep.yml
generated
BIN
.licenses/npm/mime-types.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/minimatch.dep.yml
generated
BIN
.licenses/npm/minimatch.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/process.dep.yml
generated
BIN
.licenses/npm/process.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/psl.dep.yml
generated
BIN
.licenses/npm/psl.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/punycode.dep.yml
generated
BIN
.licenses/npm/punycode.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/sax.dep.yml
generated
BIN
.licenses/npm/sax.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/signal-exit.dep.yml
generated
BIN
.licenses/npm/signal-exit.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/tough-cookie.dep.yml
generated
BIN
.licenses/npm/tough-cookie.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/tslib-1.14.1.dep.yml
generated
BIN
.licenses/npm/tslib-1.14.1.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/tslib-2.5.0.dep.yml
generated
BIN
.licenses/npm/tslib-2.5.0.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/typescript.dep.yml
generated
BIN
.licenses/npm/typescript.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/undici.dep.yml
generated
BIN
.licenses/npm/undici.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/uuid.dep.yml
generated
BIN
.licenses/npm/uuid.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/xml2js.dep.yml
generated
BIN
.licenses/npm/xml2js.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
Binary file not shown.
@@ -1,7 +0,0 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!.github/
|
||||
!src/
|
||||
@@ -1,11 +0,0 @@
|
||||
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||
module.exports = {
|
||||
printWidth: 80,
|
||||
tabWidth: 2,
|
||||
useTabs: false,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'none',
|
||||
bracketSpacing: false,
|
||||
arrowParens: 'avoid'
|
||||
};
|
||||
12
.prettierrc.json
Normal file
12
.prettierrc.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid",
|
||||
"parser": "typescript",
|
||||
"endOfLine": "auto"
|
||||
}
|
||||
83
README.md
83
README.md
@@ -1,7 +1,6 @@
|
||||
# setup-dotnet
|
||||
|
||||
[](https://github.com/actions/setup-dotnet/actions/workflows/basic-validation.yml)
|
||||
[](https://github.com/actions/setup-dotnet/actions/workflows/e2e-tests.yml)
|
||||
[](https://github.com/actions/setup-dotnet)
|
||||
|
||||
This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for use in actions by:
|
||||
|
||||
@@ -49,13 +48,12 @@ The `dotnet-version` input supports following syntax:
|
||||
- **A.B.C** (e.g 6.0.400, 7.0.100-preview.7.22377.5) - installs exact version of .NET SDK
|
||||
- **A.B** or **A.B.x** (e.g. 3.1, 3.1.x) - installs the latest patch version of .NET SDK on the channel `3.1`, including prerelease versions (preview, rc)
|
||||
- **A** or **A.x** (e.g. 3, 3.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
|
||||
- **A.B.Cxx** (e.g. 6.0.4xx) - available since `.NET 5.0` release. Installs the latest version of the specific SDK release, including prerelease versions (preview, rc).
|
||||
|
||||
|
||||
## Using the `dotnet-quality` input
|
||||
This input sets up the action to install the latest build of the specified quality in the channel. The possible values of `dotnet-quality` are: **daily**, **signed**, **validated**, **preview**, **ga**.
|
||||
|
||||
> **Note**: `dotnet-quality` input can be used only with .NET SDK version in 'A.B', 'A.B.x', 'A', 'A.x' and 'A.B.Cxx' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
|
||||
> **Note**: `dotnet-quality` input can be used only with .NET SDK version in 'A.B', 'A.B.x', 'A' and 'A.x' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
|
||||
|
||||
```yml
|
||||
steps:
|
||||
@@ -82,63 +80,6 @@ steps:
|
||||
working-directory: csharp
|
||||
```
|
||||
|
||||
## Caching NuGet Packages
|
||||
The action has a built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching global packages data but requires less configuration settings. The `cache` input is optional, and caching is turned off by default.
|
||||
|
||||
The action searches for [NuGet Lock files](https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies) (`packages.lock.json`) in the repository root, calculates their hash and uses it as a part of the cache key. If lock file does not exist, this action throws error. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
|
||||
|
||||
> **Warning**: Caching NuGet packages is available since .NET SDK 2.1.500 and 2.2.100 as the NuGet lock file [is available](https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies) only for NuGet 4.9 and above.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 6.x
|
||||
cache: true
|
||||
- run: dotnet restore --locked-mode
|
||||
```
|
||||
|
||||
> **Note**: This action will only restore `global-packages` folder, so you will probably get the [NU1403](https://learn.microsoft.com/nuget/reference/errors-and-warnings/nu1403) error when running `dotnet restore`.
|
||||
> To avoid this, you can use [`DisableImplicitNuGetFallbackFolder`](https://github.com/dotnet/reproducible-builds/blob/abfe986832aa28597d3340b92469d1a702013d23/Documentation/Reproducible-MSBuild/Techniques/DisableImplicitNuGetFallbackFolder.md) option.
|
||||
|
||||
```xml
|
||||
<PropertyGroup>
|
||||
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
|
||||
</PropertyGroup>
|
||||
```
|
||||
|
||||
### Reduce caching size
|
||||
|
||||
> **Note**: Use [`NUGET_PACKAGES`](https://learn.microsoft.com/nuget/reference/cli-reference/cli-ref-environment-variables) environment variable if available. Some action runners already has huge libraries. (ex. Xamarin)
|
||||
|
||||
```yaml
|
||||
env:
|
||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 6.x
|
||||
cache: true
|
||||
- run: dotnet restore --locked-mode
|
||||
```
|
||||
|
||||
### Caching NuGet packages in monorepos
|
||||
|
||||
```yaml
|
||||
env:
|
||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 6.x
|
||||
cache: true
|
||||
cache-dependency-path: subdir/packages.lock.json
|
||||
- run: dotnet restore --locked-mode
|
||||
```
|
||||
|
||||
## Matrix Testing
|
||||
Using `setup-dotnet` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of .NET SDK:
|
||||
```yml
|
||||
@@ -271,9 +212,6 @@ When the `dotnet-version` input is used along with the `global-json-file` input,
|
||||
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 2.2.207
|
||||
```
|
||||
|
||||
### `cache-hit`
|
||||
A boolean value to indicate an exact match was found for the cache key (follows [actions/cache](https://github.com/actions/cache#outputs))
|
||||
|
||||
## Environment variables
|
||||
|
||||
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
|
||||
@@ -284,28 +222,25 @@ Some environment variables may be necessary for your particular case or to impro
|
||||
| DOTNET_NOLOGO |Removes logo and telemetry message from first run of dotnet cli|*false*|
|
||||
| DOTNET_CLI_TELEMETRY_OPTOUT |Opt-out of telemetry being sent to Microsoft|*false*|
|
||||
| DOTNET_MULTILEVEL_LOOKUP |Configures whether the global install location is used as a fall-back|*true*|
|
||||
| NUGET_PACKAGES |Configures a path to the [NuGet `global-packages` folder](https://learn.microsoft.com/nuget/consume-packages/managing-the-global-packages-and-cache-folders)|*default value for each OS* |
|
||||
|
||||
The default values of the `DOTNET_INSTALL_DIR` and `NUGET_PACKAGES` environment variables depend on the operation system which is used on a runner:
|
||||
| **Operation system** | `DOTNET_INSTALL_DIR` | `NUGET_PACKAGES` |
|
||||
| ----------- | ----------- | ----------- |
|
||||
| **Windows** | `C:\Program Files\dotnet` | `%userprofile%\.nuget\packages` |
|
||||
| **Ubuntu** | `/usr/share/dotnet` | `~/.nuget/packages` |
|
||||
| **macOS** | `/Users/runner/.dotnet` | `~/.nuget/packages` |
|
||||
The default value of the `DOTNET_INSTALL_DIR` environment variable depends on the operation system which is used on a runner:
|
||||
| **Operation system** | **Default value** |
|
||||
| ----------- | ----------- |
|
||||
| **Windows** | `C:\Program Files\dotnet` |
|
||||
| **Ubuntu** | `/usr/share/dotnet` |
|
||||
| **macOS** | `/Users/runner/.dotnet` |
|
||||
|
||||
**Example usage of environment variable**:
|
||||
**Example usage**:
|
||||
```yml
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOTNET_INSTALL_DIR: "path/to/directory"
|
||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '3.1.x'
|
||||
cache: true
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`authutil tests existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -15,7 +15,7 @@ exports[`authutil tests existing config not in repo root, sets up a partial NuGe
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -30,7 +30,7 @@ exports[`authutil tests existing config w/ Azure Artifacts source and NuGet.org,
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -45,7 +45,7 @@ exports[`authutil tests existing config w/ GPR source and NuGet.org, sets up a p
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -63,7 +63,7 @@ exports[`authutil tests existing config w/ no GPR sources, sets up a full NuGet.
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -81,7 +81,7 @@ exports[`authutil tests existing config w/ no sources, sets up a full NuGet.conf
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -96,7 +96,7 @@ exports[`authutil tests existing config w/ only Azure Artifacts source, sets up
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -111,7 +111,7 @@ exports[`authutil tests existing config w/ only GPR source, sets up a partial Nu
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests Existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -130,7 +130,7 @@ exports[`authutil tests existing config w/ two GPR sources, sets up a partial Nu
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR 1`] = `
|
||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -148,7 +148,7 @@ exports[`authutil tests no existing config, sets up a full NuGet.config with URL
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and token for other source 1`] = `
|
||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and token for other source 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
@@ -166,7 +166,7 @@ exports[`authutil tests no existing config, sets up a full NuGet.config with URL
|
||||
</configuration>"
|
||||
`;
|
||||
|
||||
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||
"<?xml version=\\"1.0\\"?>
|
||||
<configuration>
|
||||
<config>
|
||||
|
||||
@@ -1,336 +1,336 @@
|
||||
import * as io from '@actions/io';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const fakeSourcesDirForTesting = path.join(
|
||||
__dirname,
|
||||
'runner',
|
||||
path.join(Math.random().toString(36).substring(7)),
|
||||
's'
|
||||
);
|
||||
|
||||
const invalidNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>`;
|
||||
|
||||
const emptyNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
</configuration>`;
|
||||
|
||||
const nugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const gprnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const gprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const twogprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR-GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
<add key="GPR-Actions" value="https://nuget.pkg.github.com/actions/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const spaceNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const azureartifactsNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const azureartifactsnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
// We want a NuGet.config one level above the sources directory, so it doesn't trample a user's NuGet.config but is still picked up by NuGet/dotnet.
|
||||
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
||||
|
||||
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
||||
import * as auth from '../src/authutil';
|
||||
|
||||
describe('authutil tests', () => {
|
||||
beforeEach(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
await io.mkdirP(fakeSourcesDirForTesting);
|
||||
}, 30000);
|
||||
|
||||
afterAll(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
}, 30000);
|
||||
|
||||
beforeEach(() => {
|
||||
if (fs.existsSync(nugetConfigFile)) {
|
||||
fs.unlinkSync(nugetConfigFile);
|
||||
}
|
||||
process.env['INPUT_OWNER'] = '';
|
||||
process.env['NUGET_AUTH_TOKEN'] = '';
|
||||
});
|
||||
|
||||
it('no existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('no existing config, auth token environment variable not provided, throws', async () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('no existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
process.env['INPUT_OWNER'] = 'otherorg';
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
||||
let thrown = false;
|
||||
try {
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ spaces in key, throws for now', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
||||
let thrown = false;
|
||||
try {
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigDirectory: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'subfolder'
|
||||
);
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
inputNuGetConfigDirectory,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'subfolder/nuget.config',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||
auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('no existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
import * as io from '@actions/io';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const fakeSourcesDirForTesting = path.join(
|
||||
__dirname,
|
||||
'runner',
|
||||
path.join(Math.random().toString(36).substring(7)),
|
||||
's'
|
||||
);
|
||||
|
||||
const invalidNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>`;
|
||||
|
||||
const emptyNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
</configuration>`;
|
||||
|
||||
const nugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const gprnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const gprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const twogprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR-GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
<add key="GPR-Actions" value="https://nuget.pkg.github.com/actions/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const spaceNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const azureartifactsNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
const azureartifactsnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>`;
|
||||
|
||||
// We want a NuGet.config one level above the sources directory, so it doesn't trample a user's NuGet.config but is still picked up by NuGet/dotnet.
|
||||
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
||||
|
||||
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
||||
import * as auth from '../src/authutil';
|
||||
|
||||
describe('authutil tests', () => {
|
||||
beforeEach(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
await io.mkdirP(fakeSourcesDirForTesting);
|
||||
}, 30000);
|
||||
|
||||
afterAll(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
}, 30000);
|
||||
|
||||
beforeEach(() => {
|
||||
if (fs.existsSync(nugetConfigFile)) {
|
||||
fs.unlinkSync(nugetConfigFile);
|
||||
}
|
||||
process.env['INPUT_OWNER'] = '';
|
||||
process.env['NUGET_AUTH_TOKEN'] = '';
|
||||
});
|
||||
|
||||
it('No existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('No existing config, auth token environment variable not provided, throws', async () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('No existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
process.env['INPUT_OWNER'] = 'otherorg';
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('Existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ spaces in key, throws for now', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
});
|
||||
|
||||
it('Existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigDirectory: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'subfolder'
|
||||
);
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
inputNuGetConfigDirectory,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'subfolder/nuget.config',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('Existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
const inputNuGetConfigPath: string = path.join(
|
||||
fakeSourcesDirForTesting,
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('No existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
import {readdir} from 'node:fs/promises';
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import * as glob from '@actions/glob';
|
||||
import {restoreCache} from '../src/cache-restore';
|
||||
import {getNuGetFolderPath} from '../src/cache-utils';
|
||||
import {lockFilePatterns} from '../src/constants';
|
||||
|
||||
jest.mock('node:fs/promises');
|
||||
jest.mock('@actions/cache');
|
||||
jest.mock('@actions/core');
|
||||
jest.mock('@actions/glob');
|
||||
jest.mock('../src/cache-utils');
|
||||
|
||||
describe('cache-restore tests', () => {
|
||||
describe.each(lockFilePatterns)('restoreCache("%s")', lockFilePattern => {
|
||||
/** Store original process.env.GITHUB_WORKSPACE */
|
||||
let githubWorkspace: string | undefined;
|
||||
beforeAll(() => {
|
||||
githubWorkspace = process.env.GITHUB_WORKSPACE;
|
||||
jest.mocked(getNuGetFolderPath).mockResolvedValue({
|
||||
'global-packages': 'global-packages',
|
||||
'http-cache': 'http-cache',
|
||||
temp: 'temp',
|
||||
'plugins-cache': 'plugins-cache'
|
||||
});
|
||||
});
|
||||
beforeEach(() => {
|
||||
process.env.GITHUB_WORKSPACE = './';
|
||||
jest.mocked(glob.hashFiles).mockClear();
|
||||
jest.mocked(core.saveState).mockClear();
|
||||
jest.mocked(core.setOutput).mockClear();
|
||||
jest.mocked(cache.restoreCache).mockClear();
|
||||
});
|
||||
afterEach(() => (process.env.GITHUB_WORKSPACE = githubWorkspace));
|
||||
|
||||
it('throws error when lock file is not found', async () => {
|
||||
jest.mocked(glob.hashFiles).mockResolvedValue('');
|
||||
|
||||
await expect(restoreCache(lockFilePattern)).rejects.toThrow();
|
||||
|
||||
expect(jest.mocked(core.saveState)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(core.setOutput)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(cache.restoreCache)).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call core.saveState("CACHE_RESULT") when cache.restoreCache() returns falsy', async () => {
|
||||
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
|
||||
jest.mocked(cache.restoreCache).mockResolvedValue(undefined);
|
||||
|
||||
await restoreCache(lockFilePattern);
|
||||
|
||||
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
|
||||
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
|
||||
'CACHE_KEY',
|
||||
expectedKey
|
||||
);
|
||||
expect(jest.mocked(core.saveState)).not.toHaveBeenCalledWith(
|
||||
'CACHE_RESULT',
|
||||
expectedKey
|
||||
);
|
||||
expect(jest.mocked(core.setOutput)).toHaveBeenCalledWith(
|
||||
'cache-hit',
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('calls core.saveState("CACHE_RESULT") when cache.restoreCache() returns key', async () => {
|
||||
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
|
||||
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
|
||||
jest.mocked(cache.restoreCache).mockResolvedValue(expectedKey);
|
||||
|
||||
await restoreCache(lockFilePattern);
|
||||
|
||||
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
|
||||
'CACHE_KEY',
|
||||
expectedKey
|
||||
);
|
||||
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
|
||||
'CACHE_RESULT',
|
||||
expectedKey
|
||||
);
|
||||
expect(jest.mocked(core.setOutput)).toHaveBeenCalledWith(
|
||||
'cache-hit',
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('calls glob.hashFiles("/packages.lock.json") if cacheDependencyPath is falsy', async () => {
|
||||
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
|
||||
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
|
||||
jest.mocked(cache.restoreCache).mockResolvedValue(expectedKey);
|
||||
jest.mocked(readdir).mockResolvedValue([lockFilePattern] as any);
|
||||
|
||||
await restoreCache('');
|
||||
|
||||
expect(jest.mocked(glob.hashFiles)).not.toHaveBeenCalledWith('');
|
||||
expect(jest.mocked(glob.hashFiles)).toHaveBeenCalledWith(lockFilePattern);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,87 +0,0 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'node:fs';
|
||||
import {run} from '../src/cache-save';
|
||||
import {getNuGetFolderPath} from '../src/cache-utils';
|
||||
|
||||
jest.mock('@actions/cache');
|
||||
jest.mock('@actions/core');
|
||||
jest.mock('node:fs');
|
||||
jest.mock('../src/cache-utils');
|
||||
|
||||
describe('cache-save tests', () => {
|
||||
beforeAll(() => {
|
||||
jest.mocked(getNuGetFolderPath).mockResolvedValue({
|
||||
'global-packages': 'global-packages',
|
||||
'http-cache': 'http-cache',
|
||||
temp: 'temp',
|
||||
'plugins-cache': 'plugins-cache'
|
||||
});
|
||||
});
|
||||
beforeEach(() => {
|
||||
jest.mocked(core.setFailed).mockClear();
|
||||
jest.mocked(core.getState).mockClear();
|
||||
jest.mocked(core.setOutput).mockClear();
|
||||
jest.mocked(cache.saveCache).mockClear();
|
||||
jest.mocked(fs.existsSync).mockClear();
|
||||
});
|
||||
|
||||
it('does not save cache when inputs:cache === false', async () => {
|
||||
jest.mocked(core.getBooleanInput).mockReturnValue(false);
|
||||
|
||||
await run();
|
||||
|
||||
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(core.getState)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(fs.existsSync)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not save cache when core.getState("CACHE_KEY") returns ""', async () => {
|
||||
jest.mocked(core.getBooleanInput).mockReturnValue(true);
|
||||
jest.mocked(core.getState).mockReturnValue('');
|
||||
|
||||
await run();
|
||||
|
||||
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
|
||||
expect(jest.mocked(fs.existsSync)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('throws Error when cachePath not exists', async () => {
|
||||
jest.mocked(core.getBooleanInput).mockReturnValue(true);
|
||||
jest.mocked(core.getState).mockReturnValue('cache-key');
|
||||
jest.mocked(fs.existsSync).mockReturnValue(false);
|
||||
|
||||
await run();
|
||||
|
||||
expect(jest.mocked(core.setFailed)).toHaveBeenCalled();
|
||||
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
|
||||
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not save cache when state.CACHE_KEY === state.CACHE_RESULT', async () => {
|
||||
jest.mocked(core.getBooleanInput).mockReturnValue(true);
|
||||
jest.mocked(core.getState).mockReturnValue('cache-key');
|
||||
jest.mocked(fs.existsSync).mockReturnValue(true);
|
||||
|
||||
await run();
|
||||
|
||||
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
|
||||
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('saves cache when state.CACHE_KEY !== state.CACHE_RESULT', async () => {
|
||||
jest.mocked(core.getBooleanInput).mockReturnValue(true);
|
||||
jest.mocked(core.getState).mockImplementation(s => s);
|
||||
jest.mocked(fs.existsSync).mockReturnValue(true);
|
||||
|
||||
await run();
|
||||
|
||||
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
|
||||
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
|
||||
expect(jest.mocked(cache.saveCache)).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -1,122 +0,0 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as exec from '@actions/exec';
|
||||
|
||||
import {getNuGetFolderPath, isCacheFeatureAvailable} from '../src/cache-utils';
|
||||
|
||||
jest.mock('@actions/cache');
|
||||
jest.mock('@actions/core');
|
||||
jest.mock('@actions/exec');
|
||||
|
||||
describe('cache-utils tests', () => {
|
||||
describe('getNuGetFolderPath()', () => {
|
||||
it.each([
|
||||
[
|
||||
`
|
||||
http-cache: /home/codespace/.local/share/NuGet/v3-cache
|
||||
global-packages: /var/nuget
|
||||
temp: /tmp/NuGetScratch
|
||||
plugins-cache: /home/codespace/.local/share/NuGet/plugins-cache
|
||||
`,
|
||||
{
|
||||
'http-cache': '/home/codespace/.local/share/NuGet/v3-cache',
|
||||
'global-packages': '/var/nuget',
|
||||
temp: '/tmp/NuGetScratch',
|
||||
'plugins-cache': '/home/codespace/.local/share/NuGet/plugins-cache'
|
||||
}
|
||||
],
|
||||
[
|
||||
`
|
||||
http-cache: /home/codespace/.local/share/NuGet/v3-cache
|
||||
global-packages: /var/nuget
|
||||
temp: /tmp/NuGetScratch
|
||||
plugins-cache: /home/codespace/.local/share/NuGet/plugins-cache
|
||||
`,
|
||||
{
|
||||
'http-cache': '/home/codespace/.local/share/NuGet/v3-cache',
|
||||
'global-packages': '/var/nuget',
|
||||
temp: '/tmp/NuGetScratch',
|
||||
'plugins-cache': '/home/codespace/.local/share/NuGet/plugins-cache'
|
||||
}
|
||||
],
|
||||
[
|
||||
`
|
||||
http-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache
|
||||
global-packages: C:\\Users\\user\\.nuget\\packages\\
|
||||
temp: C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch
|
||||
plugins-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache
|
||||
`,
|
||||
{
|
||||
'http-cache': 'C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache',
|
||||
'global-packages': 'C:\\Users\\user\\.nuget\\packages\\',
|
||||
temp: 'C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch',
|
||||
'plugins-cache':
|
||||
'C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache'
|
||||
}
|
||||
],
|
||||
[
|
||||
`
|
||||
http-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache
|
||||
global-packages: C:\\Users\\user\\.nuget\\packages\\
|
||||
temp: C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch
|
||||
plugins-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache
|
||||
`,
|
||||
{
|
||||
'http-cache': 'C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache',
|
||||
'global-packages': 'C:\\Users\\user\\.nuget\\packages\\',
|
||||
temp: 'C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch',
|
||||
'plugins-cache':
|
||||
'C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache'
|
||||
}
|
||||
]
|
||||
])('(stdout: "%s") returns %p', async (stdout, expected) => {
|
||||
jest
|
||||
.mocked(exec.getExecOutput)
|
||||
.mockResolvedValue({stdout, stderr: '', exitCode: 0});
|
||||
const pathes = await getNuGetFolderPath();
|
||||
expect(pathes).toStrictEqual(expected);
|
||||
});
|
||||
|
||||
it.each([
|
||||
`
|
||||
error: An invalid local resource name was provided. Provide one of the following values: http-cache, temp, global-packages, all.
|
||||
Usage: dotnet nuget locals [arguments] [options]
|
||||
Arguments:
|
||||
Cache Location(s) Specifies the cache location(s) to list or clear.
|
||||
<all | http-cache | global-packages | temp>
|
||||
Options:
|
||||
-h|--help Show help information
|
||||
--force-english-output Forces the application to run using an invariant, English-based culture.
|
||||
-c|--clear Clear the selected local resources or cache location(s).
|
||||
-l|--list List the selected local resources or cache location(s).
|
||||
`,
|
||||
'bash: dotnet: command not found',
|
||||
''
|
||||
])('(stderr: "%s", exitCode: 1) throws Error', async stderr => {
|
||||
jest
|
||||
.mocked(exec.getExecOutput)
|
||||
.mockResolvedValue({stdout: '', stderr, exitCode: 1});
|
||||
await expect(getNuGetFolderPath()).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe.each(['', 'https://github.com/', 'https://example.com/'])(
|
||||
'isCacheFeatureAvailable()',
|
||||
url => {
|
||||
// Save & Restore env
|
||||
let serverUrlEnv: string | undefined;
|
||||
beforeAll(() => (serverUrlEnv = process.env['GITHUB_SERVER_URL']));
|
||||
beforeEach(() => (process.env['GITHUB_SERVER_URL'] = url));
|
||||
afterEach(() => (process.env['GITHUB_SERVER_URL'] = serverUrlEnv));
|
||||
|
||||
it('returns true when cache.isFeatureAvailable() === true', () => {
|
||||
jest.mocked(cache.isFeatureAvailable).mockReturnValue(true);
|
||||
expect(isCacheFeatureAvailable()).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when cache.isFeatureAvailable() === false', () => {
|
||||
jest.mocked(cache.isFeatureAvailable).mockReturnValue(false);
|
||||
expect(isCacheFeatureAvailable()).toBe(false);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -1,45 +1,21 @@
|
||||
import cscFile from '../.github/csc.json';
|
||||
describe('csc tests', () => {
|
||||
test('regular expression in csc.json is valid', async () => {
|
||||
const regexPattern = cscFile['problemMatcher'][0]['pattern'][0]['regexp'];
|
||||
const regexResultsMap = cscFile['problemMatcher'][0]['pattern'][0];
|
||||
it('Valid regular expression', async () => {
|
||||
var cscFile = require('../.github/csc.json');
|
||||
var regex = cscFile['problemMatcher'][0]['pattern'][0]['regexp'];
|
||||
|
||||
const regex = new RegExp(regexPattern);
|
||||
console.log(regex);
|
||||
var re = new RegExp(regex);
|
||||
|
||||
const stringsToMatch = [
|
||||
// Ideally we would verify that this
|
||||
var stringsToMatch = [
|
||||
'Program.cs(10,79): error CS1002: ; expected [/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj]',
|
||||
"S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs(33,7): error CS1003: Syntax error, ',' expected [S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop]"
|
||||
];
|
||||
// Expected results are calculated according to the csc matcher located in csc.json file
|
||||
const expectedResults = [
|
||||
{
|
||||
file: 'Program.cs',
|
||||
line: '10',
|
||||
severity: 'error',
|
||||
code: 'CS1002',
|
||||
message: '; expected',
|
||||
fromPath:
|
||||
'/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj'
|
||||
},
|
||||
{
|
||||
file: 'S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs',
|
||||
line: '33',
|
||||
severity: 'error',
|
||||
code: 'CS1003',
|
||||
message: "Syntax error, ',' expected",
|
||||
fromPath:
|
||||
'S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop'
|
||||
}
|
||||
];
|
||||
|
||||
stringsToMatch.map((string, index) => {
|
||||
const matchedResultsArray = string.match(regex);
|
||||
for (const propName in expectedResults[index]) {
|
||||
const propertyIndex = regexResultsMap[propName];
|
||||
const expectedPropValue = expectedResults[index][propName];
|
||||
const matchedPropValue = matchedResultsArray![propertyIndex];
|
||||
expect(matchedPropValue).toEqual(expectedPropValue);
|
||||
}
|
||||
stringsToMatch.forEach(string => {
|
||||
var matchStr = string.match(re);
|
||||
console.log(matchStr);
|
||||
expect(matchStr).toEqual(expect.anything());
|
||||
});
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
namespace test_csproj
|
||||
{
|
||||
[TestClass]
|
||||
public class Test
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethod()
|
||||
{
|
||||
Console.WriteLine("TestMethod");
|
||||
int calculatedResult = 1000 / 25;
|
||||
int expectedResult = 40;
|
||||
Assert.AreEqual(calculatedResult, expectedResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>$(TEST_TARGET_FRAMEWORK)</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- These packages will be downloaded over the network for testing proxy settings -->
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20170810-02" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,65 +0,0 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import * as hc from '@actions/http-client';
|
||||
|
||||
const HTTP_CLIENT_OPTIONS = {allowRetries: true, maxRetries: 10} as const;
|
||||
const TEST_TIMEOUT = 30000;
|
||||
|
||||
describe('Dotnet installation scripts tests', () => {
|
||||
it(
|
||||
'Uses an up to date bash download script',
|
||||
async () => {
|
||||
const httpCallbackClient = new hc.HttpClient(
|
||||
'setup-dotnet-test',
|
||||
[],
|
||||
HTTP_CLIENT_OPTIONS
|
||||
);
|
||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||
'https://dot.net/v1/dotnet-install.sh'
|
||||
);
|
||||
expect(response.message.statusCode).toBe(200);
|
||||
const upToDateContents: string = await response.readBody();
|
||||
const currentContents: string = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||
)
|
||||
.toString();
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
},
|
||||
TEST_TIMEOUT
|
||||
);
|
||||
|
||||
it(
|
||||
'Uses an up to date powershell download script',
|
||||
async () => {
|
||||
const httpCallbackClient = new hc.HttpClient(
|
||||
'setup-dotnet-test',
|
||||
[],
|
||||
HTTP_CLIENT_OPTIONS
|
||||
);
|
||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||
'https://dot.net/v1/dotnet-install.ps1'
|
||||
);
|
||||
expect(response.message.statusCode).toBe(200);
|
||||
const upToDateContents: string = await response.readBody();
|
||||
const currentContents: string = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||
)
|
||||
.toString();
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
},
|
||||
TEST_TIMEOUT
|
||||
);
|
||||
});
|
||||
|
||||
function normalizeFileContents(contents: string): string {
|
||||
return contents
|
||||
.trim()
|
||||
.replace(new RegExp('\r\n', 'g'), '\n')
|
||||
.replace(new RegExp('\r', 'g'), '\n');
|
||||
}
|
||||
@@ -1,457 +1,290 @@
|
||||
import each from 'jest-each';
|
||||
import semver from 'semver';
|
||||
import fs from 'fs';
|
||||
import fspromises from 'fs/promises';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
import * as os from 'os';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import each from 'jest-each';
|
||||
import * as hc from '@actions/http-client';
|
||||
import * as installer from '../src/installer';
|
||||
|
||||
import {IS_WINDOWS} from '../src/utils';
|
||||
import {QualityOptions} from '../src/setup-dotnet';
|
||||
|
||||
describe('installer tests', () => {
|
||||
const env = process.env;
|
||||
import {IS_WINDOWS} from '../src/utils';
|
||||
import {IS_LINUX} from '../src/utils';
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
process.env = {...env};
|
||||
});
|
||||
let toolDir: string;
|
||||
|
||||
describe('DotnetCoreInstaller tests', () => {
|
||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||
const warningSpy = jest.spyOn(core, 'warning');
|
||||
const whichSpy = jest.spyOn(io, 'which');
|
||||
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
||||
const chmodSyncSpy = jest.spyOn(fs, 'chmodSync');
|
||||
const readdirSpy = jest.spyOn(fspromises, 'readdir');
|
||||
if (IS_WINDOWS) {
|
||||
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
|
||||
} else if (IS_LINUX) {
|
||||
toolDir = '/usr/share/dotnet';
|
||||
} else {
|
||||
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
|
||||
}
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||
|
||||
describe('installDotnet() tests', () => {
|
||||
beforeAll(() => {
|
||||
whichSpy.mockImplementation(() => Promise.resolve('PathToShell'));
|
||||
chmodSyncSpy.mockImplementation(() => {});
|
||||
readdirSpy.mockImplementation(() => Promise.resolve([]));
|
||||
});
|
||||
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||
process.env['RUNNER_TEMP'] = tempDir;
|
||||
|
||||
afterAll(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
describe('DotnetCoreInstaller tests', () => {
|
||||
beforeAll(async () => {
|
||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||
process.env.RUNNER_TEMP = tempDir;
|
||||
process.env.DOTNET_ROOT = '';
|
||||
try {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Failed to remove test directories, check the error message:${os.EOL}`,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
it('should throw the error in case of non-zero exit code of the installation script. The error message should contain logs.', async () => {
|
||||
const inputVersion = '3.1.100';
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const errorMessage = 'fictitious error message!';
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Failed to remove test directories, check the error message:${os.EOL}`,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 1,
|
||||
stdout: '',
|
||||
stderr: errorMessage
|
||||
});
|
||||
});
|
||||
it('Aquires multiple versions of dotnet', async () => {
|
||||
const versions = ['2.2.207', '3.1.120'];
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
await expect(dotnetInstaller.installDotnet()).rejects.toThrow(
|
||||
`Failed to install dotnet, exit code: 1. ${errorMessage}`
|
||||
);
|
||||
});
|
||||
for (const version of versions) {
|
||||
await getDotnet(version);
|
||||
}
|
||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true);
|
||||
|
||||
it('should return version of .NET SDK after installation complete', async () => {
|
||||
const inputVersion = '3.1.100';
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
if (IS_WINDOWS) {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
const installedVersion = await dotnetInstaller.installDotnet();
|
||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||
expect(process.env.PATH).toBeDefined;
|
||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000);
|
||||
|
||||
expect(installedVersion).toBe(inputVersion);
|
||||
});
|
||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
||||
await getDotnet('3.1.201');
|
||||
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);
|
||||
}
|
||||
|
||||
it(`should supply 'version' argument to the installation script if supplied version is in A.B.C syntax`, async () => {
|
||||
const inputVersion = '6.0.300';
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||
expect(process.env.PATH).toBeDefined;
|
||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
it('Acquires generic version of dotnet if no matching version is installed', async () => {
|
||||
await getDotnet('3.1');
|
||||
var directory = fs
|
||||
.readdirSync(path.join(toolDir, 'sdk'))
|
||||
.filter(fn => fn.startsWith('3.1.'));
|
||||
expect(directory.length > 0).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);
|
||||
}
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||
expect(process.env.PATH).toBeDefined;
|
||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
it('Returns string with installed SDK version', async () => {
|
||||
const version = '3.1.120';
|
||||
let installedVersion: string;
|
||||
|
||||
const scriptArguments = (
|
||||
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||
).join(' ');
|
||||
const expectedArgument = IS_WINDOWS
|
||||
? `-Version ${inputVersion}`
|
||||
: `--version ${inputVersion}`;
|
||||
installedVersion = await getDotnet(version);
|
||||
|
||||
expect(scriptArguments).toContain(expectedArgument);
|
||||
});
|
||||
expect(installedVersion).toBe('3.1.120');
|
||||
}, 600000);
|
||||
|
||||
it(`should warn if the 'quality' input is set and the supplied version is in A.B.C syntax`, async () => {
|
||||
const inputVersion = '6.0.300';
|
||||
const inputQuality = 'ga' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
it('Throws if no location contains correct dotnet version', async () => {
|
||||
await expect(async () => {
|
||||
await getDotnet('1000.0.0');
|
||||
}).rejects.toThrow();
|
||||
}, 30000);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
it('Uses an up to date bash download script', async () => {
|
||||
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||
'https://dot.net/v1/dotnet-install.sh'
|
||||
);
|
||||
expect(response.message.statusCode).toBe(200);
|
||||
const upToDateContents: string = await response.readBody();
|
||||
const currentContents: string = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||
)
|
||||
.toString();
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
}, 30000);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
it('Uses an up to date powershell download script', async () => {
|
||||
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||
'https://dot.net/v1/dotnet-install.ps1'
|
||||
);
|
||||
expect(response.message.statusCode).toBe(200);
|
||||
const upToDateContents: string = await response.readBody();
|
||||
const currentContents: string = fs
|
||||
.readFileSync(
|
||||
path.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||
)
|
||||
.toString();
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
expect(warningSpy).toHaveBeenCalledWith(
|
||||
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
|
||||
);
|
||||
});
|
||||
describe('DotnetVersionResolver tests', () => {
|
||||
each([
|
||||
'3.1',
|
||||
'3.x',
|
||||
'3.1.x',
|
||||
'3.1.*',
|
||||
'3.1.X',
|
||||
'3.1.2',
|
||||
'3.1.0-preview1'
|
||||
]).test(
|
||||
"if valid version: '%s' is supplied, it should return version object with some value",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
it(`should warn if the 'quality' input is set and version isn't in A.B.C syntax but major tag is lower then 6`, async () => {
|
||||
const inputVersion = '3.1';
|
||||
const inputQuality = 'ga' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version 3.1.100 is installed`;
|
||||
expect(!!versionObject.value).toBeTruthy;
|
||||
}
|
||||
);
|
||||
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
|
||||
expect(warningSpy).toHaveBeenCalledWith(
|
||||
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
|
||||
);
|
||||
});
|
||||
|
||||
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
|
||||
`should supply 'quality' argument to the installation script if quality input is set and version (%s) is not in A.B.C syntax`,
|
||||
async inputVersion => {
|
||||
const inputQuality = 'ga' as QualityOptions;
|
||||
const exitCode = 0;
|
||||
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: exitCode,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
|
||||
const scriptArguments = (
|
||||
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||
).join(' ');
|
||||
const expectedArgument = IS_WINDOWS
|
||||
? `-Quality ${inputQuality}`
|
||||
: `--quality ${inputQuality}`;
|
||||
|
||||
expect(scriptArguments).toContain(expectedArgument);
|
||||
}
|
||||
each([
|
||||
'.',
|
||||
'..',
|
||||
' . ',
|
||||
'. ',
|
||||
' .',
|
||||
' . . ',
|
||||
' .. ',
|
||||
' . ',
|
||||
'-1.-1',
|
||||
'-1',
|
||||
'-1.-1.-1',
|
||||
'..3',
|
||||
'1..3',
|
||||
'1..',
|
||||
'.2.3',
|
||||
'.2.x',
|
||||
'*.',
|
||||
'1.2.',
|
||||
'1.2.-abc',
|
||||
'a.b',
|
||||
'a.b.c',
|
||||
'a.b.c-preview',
|
||||
' 0 . 1 . 2 ',
|
||||
'invalid'
|
||||
]).test(
|
||||
"if invalid version: '%s' is supplied, it should throw",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
|
||||
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
|
||||
`should supply 'channel' argument to the installation script if version (%s) isn't in A.B.C syntax`,
|
||||
async inputVersion => {
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const exitCode = 0;
|
||||
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: exitCode,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
await expect(
|
||||
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||
).rejects.toThrow();
|
||||
}
|
||||
);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
|
||||
const scriptArguments = (
|
||||
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||
).join(' ');
|
||||
const expectedArgument = IS_WINDOWS
|
||||
? `-Channel 6.0`
|
||||
: `--channel 6.0`;
|
||||
|
||||
expect(scriptArguments).toContain(expectedArgument);
|
||||
}
|
||||
each(['3.1', '3.1.x', '3.1.*', '3.1.X']).test(
|
||||
"if version: '%s' that can be resolved to 'channel' option is supplied, it should set quality flag to 'true' and type to 'channel' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('channel')).toBeTruthy;
|
||||
expect(versionObject.qualityFlag).toBeTruthy;
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1.0-preview1']).test(
|
||||
"if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('version')).toBeTruthy;
|
||||
expect(versionObject.qualityFlag).toBeFalsy;
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1']).test(
|
||||
'it should create proper line arguments for powershell/bash installation scripts',
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
const windowsRegEx = new RegExp(/^-[VC]/);
|
||||
const nonWindowsRegEx = new RegExp(/^--[vc]/);
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
it(`should supply '-ProxyAddress' argument to the installation script if env.variable 'https_proxy' is set`, async () => {
|
||||
process.env['https_proxy'] = 'https://proxy.com';
|
||||
const inputVersion = '6.0.100';
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
|
||||
const scriptArguments = (
|
||||
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||
).join(' ');
|
||||
|
||||
expect(scriptArguments).toContain(
|
||||
`-ProxyAddress ${process.env['https_proxy']}`
|
||||
);
|
||||
});
|
||||
|
||||
it(`should supply '-ProxyBypassList' argument to the installation script if env.variable 'no_proxy' is set`, async () => {
|
||||
process.env['no_proxy'] = 'first.url,second.url';
|
||||
const inputVersion = '6.0.100';
|
||||
const inputQuality = '' as QualityOptions;
|
||||
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||
|
||||
getExecOutputSpy.mockImplementation(() => {
|
||||
return Promise.resolve({
|
||||
exitCode: 0,
|
||||
stdout: `${stdout}`,
|
||||
stderr: ''
|
||||
});
|
||||
});
|
||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
inputVersion,
|
||||
inputQuality
|
||||
);
|
||||
|
||||
await dotnetInstaller.installDotnet();
|
||||
|
||||
const scriptArguments = (
|
||||
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||
).join(' ');
|
||||
|
||||
expect(scriptArguments).toContain(
|
||||
`-ProxyBypassList ${process.env['no_proxy']}`
|
||||
);
|
||||
});
|
||||
expect(windowsRegEx.test(versionObject.type)).toBeTruthy;
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBeFalsy;
|
||||
} else {
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBeTruthy;
|
||||
expect(windowsRegEx.test(versionObject.type)).toBeFalsy;
|
||||
}
|
||||
});
|
||||
|
||||
describe('addToPath() tests', () => {
|
||||
it(`should export DOTNET_ROOT env.var with value from DOTNET_INSTALL_DIR env.var`, async () => {
|
||||
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
|
||||
installer.DotnetCoreInstaller.addToPath();
|
||||
const dotnet_root = process.env['DOTNET_ROOT'];
|
||||
expect(dotnet_root).toBe(process.env['DOTNET_INSTALL_DIR']);
|
||||
});
|
||||
|
||||
it(`should export value from DOTNET_INSTALL_DIR env.var to the PATH`, async () => {
|
||||
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
|
||||
installer.DotnetCoreInstaller.addToPath();
|
||||
const path = process.env['PATH'];
|
||||
expect(path).toContain(process.env['DOTNET_INSTALL_DIR']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('DotnetVersionResolver tests', () => {
|
||||
describe('createDotNetVersion() tests', () => {
|
||||
each([
|
||||
'3.1',
|
||||
'3.x',
|
||||
'3.1.x',
|
||||
'3.1.*',
|
||||
'3.1.X',
|
||||
'3.1.2',
|
||||
'3.1.0-preview1',
|
||||
'6.0.2xx'
|
||||
]).test(
|
||||
'if valid version is supplied (%s), it should return version object with some value',
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject =
|
||||
await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(!!versionObject.value).toBe(true);
|
||||
}
|
||||
);
|
||||
|
||||
each([
|
||||
'.',
|
||||
'..',
|
||||
' . ',
|
||||
'. ',
|
||||
' .',
|
||||
' . . ',
|
||||
' .. ',
|
||||
' . ',
|
||||
'-1.-1',
|
||||
'-1',
|
||||
'-1.-1.-1',
|
||||
'..3',
|
||||
'1..3',
|
||||
'1..',
|
||||
'.2.3',
|
||||
'.2.x',
|
||||
'*.',
|
||||
'1.2.',
|
||||
'1.2.-abc',
|
||||
'a.b',
|
||||
'a.b.c',
|
||||
'a.b.c-preview',
|
||||
' 0 . 1 . 2 ',
|
||||
'invalid'
|
||||
]).test(
|
||||
'if invalid version is supplied (%s), it should throw',
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
|
||||
await expect(
|
||||
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||
).rejects.toThrow();
|
||||
}
|
||||
);
|
||||
|
||||
each(['3', '3.1', '3.1.x', '3.1.*', '3.1.X', '6.0.2xx']).test(
|
||||
"if version that can be resolved to 'channel' option is supplied (%s), it should set type to 'channel' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject =
|
||||
await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
|
||||
true
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.2xx']).test(
|
||||
"if version that can be resolved to 'channel' option is supplied and its major tag is >= 6 (%s), it should set type to 'channel' and qualityFlag to 'true' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject =
|
||||
await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
|
||||
true
|
||||
);
|
||||
expect(versionObject.qualityFlag).toBe(true);
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1.0-preview1']).test(
|
||||
"if version that can be resolved to 'version' option is supplied (%s), it should set quality flag to 'false' and type to 'version' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject =
|
||||
await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('version')).toBe(
|
||||
true
|
||||
);
|
||||
expect(versionObject.qualityFlag).toBe(false);
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1']).test(
|
||||
'it should create proper line arguments for powershell/bash installation scripts',
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject =
|
||||
await dotnetVersionResolver.createDotNetVersion();
|
||||
const windowsRegEx = new RegExp(/^-(Version|Channel)/);
|
||||
const nonWindowsRegEx = new RegExp(/^--(version|channel)/);
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
expect(windowsRegEx.test(versionObject.type)).toBe(true);
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBe(false);
|
||||
} else {
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBe(true);
|
||||
expect(windowsRegEx.test(versionObject.type)).toBe(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
it(`should throw if dotnet-version is supplied in A.B.Cxx syntax with major tag lower that 5`, async () => {
|
||||
const version = '3.0.1xx';
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
await expect(
|
||||
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||
).rejects.toThrow(
|
||||
`'dotnet-version' was supplied in invalid format: ${version}! The A.B.Cxx syntax is available since the .NET 5.0 release.`
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function normalizeFileContents(contents: string): string {
|
||||
return contents
|
||||
.trim()
|
||||
.replace(new RegExp('\r\n', 'g'), '\n')
|
||||
.replace(new RegExp('\r', 'g'), '\n');
|
||||
}
|
||||
|
||||
async function getDotnet(
|
||||
version: string,
|
||||
quality: string = ''
|
||||
): Promise<string> {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
version,
|
||||
quality as QualityOptions
|
||||
);
|
||||
const installedVersion = await dotnetInstaller.installDotnet();
|
||||
installer.DotnetCoreInstaller.addToPath();
|
||||
return installedVersion;
|
||||
}
|
||||
|
||||
15
__tests__/sample-csproj/Program.cs
Normal file
15
__tests__/sample-csproj/Program.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
namespace sample_csproj
|
||||
{
|
||||
[TestClass]
|
||||
public class Program
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMethod1()
|
||||
{
|
||||
Console.WriteLine("Hello, World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
18
__tests__/sample-csproj/sample.csproj
Normal file
18
__tests__/sample-csproj/sample.csproj
Normal file
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp3.1;netcoreapp3.0;netcoreapp2.2</TargetFrameworks>
|
||||
<RootNamespace>sample_csproj</RootNamespace>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- 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>
|
||||
|
||||
</Project>
|
||||
@@ -1,230 +1,98 @@
|
||||
import * as io from '@actions/io';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'fs';
|
||||
import semver from 'semver';
|
||||
import * as auth from '../src/authutil';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import * as setup from '../src/setup-dotnet';
|
||||
import {DotnetCoreInstaller} from '../src/installer';
|
||||
import * as cacheUtils from '../src/cache-utils';
|
||||
import * as cacheRestore from '../src/cache-restore';
|
||||
import {IS_WINDOWS} from '../src/utils';
|
||||
import {IS_LINUX} from '../src/utils';
|
||||
|
||||
let toolDir: string;
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
|
||||
} else if (IS_LINUX) {
|
||||
toolDir = '/usr/share/dotnet';
|
||||
} else {
|
||||
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
|
||||
}
|
||||
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||
|
||||
describe('setup-dotnet tests', () => {
|
||||
const inputs = {} as any;
|
||||
let getInputSpy = jest.spyOn(core, 'getInput');
|
||||
let getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
|
||||
let setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||
|
||||
const getInputSpy = jest.spyOn(core, 'getInput');
|
||||
const getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
|
||||
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||
const setFailedSpy = jest.spyOn(core, 'setFailed');
|
||||
const warningSpy = jest.spyOn(core, 'warning');
|
||||
const debugSpy = jest.spyOn(core, 'debug');
|
||||
const infoSpy = jest.spyOn(core, 'info');
|
||||
const setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||
let inputs = {} as any;
|
||||
|
||||
const existsSyncSpy = jest.spyOn(fs, 'existsSync');
|
||||
beforeAll(async () => {
|
||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||
process.env.RUNNER_TEMP = tempDir;
|
||||
try {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
const installDotnetSpy = jest.spyOn(
|
||||
DotnetCoreInstaller.prototype,
|
||||
'installDotnet'
|
||||
);
|
||||
const addToPathSpy = jest.spyOn(DotnetCoreInstaller, 'addToPath');
|
||||
const isCacheFeatureAvailableSpy = jest.spyOn(
|
||||
cacheUtils,
|
||||
'isCacheFeatureAvailable'
|
||||
);
|
||||
const restoreCacheSpy = jest.spyOn(cacheRestore, 'restoreCache');
|
||||
const configAuthenticationSpy = jest.spyOn(auth, 'configAuthentication');
|
||||
it('Acquires version of dotnet from global.json 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();
|
||||
|
||||
describe('run() tests', () => {
|
||||
beforeEach(() => {
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
getInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
getBooleanInputSpy.mockImplementation(input => inputs[input as string]);
|
||||
});
|
||||
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);
|
||||
}
|
||||
}, 400000);
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
it("Sets output with the latest installed by action version if global.json file isn't specified", async () => {
|
||||
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
|
||||
|
||||
it('should fail the action if global-json-file input is present, but the file does not exist in the file system', async () => {
|
||||
inputs['global-json-file'] = 'fictitious.json';
|
||||
inputs['dotnet-version'] = [];
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
const expectedErrorMessage = `The specified global.json file '${inputs['global-json-file']}' does not exist`;
|
||||
await setup.run();
|
||||
|
||||
await setup.run();
|
||||
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
|
||||
});
|
||||
expect(setOutputSpy).toBeCalledWith('dotnet-version', '6.0.401');
|
||||
}, 400000);
|
||||
|
||||
test(`if 'dotnet-version' and 'global-json-file' inputs aren't present, should log into debug output, try to find global.json in the repo root, fail and log message into info output`, async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = [];
|
||||
it("Sets output with the version specified in global.json, if it's present", async () => {
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.0.103"${os.EOL}}${os.EOL}}`;
|
||||
if (!fs.existsSync(globalJsonPath)) {
|
||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||
}
|
||||
|
||||
maxSatisfyingSpy.mockImplementation(() => null);
|
||||
setOutputSpy.mockImplementation(() => {});
|
||||
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
|
||||
inputs['global-json-file'] = './global.json';
|
||||
|
||||
const expectedDebugMessage =
|
||||
'No version found, trying to find version from global.json';
|
||||
const expectedInfoMessage = `The global.json wasn't found in the root directory. No .NET version will be installed.`;
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
await setup.run();
|
||||
getInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
expect(debugSpy).toHaveBeenCalledWith(expectedDebugMessage);
|
||||
expect(existsSyncSpy).toHaveBeenCalled();
|
||||
expect(infoSpy).toHaveBeenCalledWith(expectedInfoMessage);
|
||||
});
|
||||
await setup.run();
|
||||
|
||||
it('should fail the action if quality is supplied but its value is not supported', async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = ['6.0'];
|
||||
inputs['dotnet-quality'] = 'fictitiousQuality';
|
||||
|
||||
const expectedErrorMessage = `Value '${inputs['dotnet-quality']}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`;
|
||||
|
||||
await setup.run();
|
||||
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
|
||||
});
|
||||
|
||||
it('should call installDotnet() multiple times if dotnet-version multiline input is provided', async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = ['6.0', '7.0'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||
|
||||
await setup.run();
|
||||
expect(installDotnetSpy).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should call addToPath() after installation complete', async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = ['6.0', '7.0'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
expect(addToPathSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should call auth.configAuthentication() if source-url input is provided', async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['source-url'] = 'fictitious.source.url';
|
||||
|
||||
configAuthenticationSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
expect(configAuthenticationSpy).toHaveBeenCalledWith(
|
||||
inputs['source-url'],
|
||||
undefined
|
||||
);
|
||||
});
|
||||
|
||||
it('should call auth.configAuthentication() with proper parameters if source-url and config-file inputs are provided', async () => {
|
||||
inputs['global-json-file'] = '';
|
||||
inputs['dotnet-version'] = [];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['source-url'] = 'fictitious.source.url';
|
||||
inputs['config-file'] = 'fictitious.path';
|
||||
|
||||
configAuthenticationSpy.mockImplementation(() => {});
|
||||
setOutputSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
expect(configAuthenticationSpy).toHaveBeenCalledWith(
|
||||
inputs['source-url'],
|
||||
inputs['config-file']
|
||||
);
|
||||
});
|
||||
|
||||
it('should call setOutput() after installation complete successfully', async () => {
|
||||
inputs['dotnet-version'] = ['6.0.300'];
|
||||
|
||||
installDotnetSpy.mockImplementation(() =>
|
||||
Promise.resolve(`${inputs['dotnet-version']}`)
|
||||
);
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
expect(setOutputSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it(`shouldn't call setOutput() if parsing dotnet-installer logs failed`, async () => {
|
||||
inputs['dotnet-version'] = ['6.0.300'];
|
||||
const warningMessage = `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`;
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(null));
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
|
||||
expect(setOutputSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it(`shouldn't call setOutput() if actions didn't install .NET`, async () => {
|
||||
inputs['dotnet-version'] = [];
|
||||
const warningMessage = `The 'dotnet-version' output will not be set.`;
|
||||
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
await setup.run();
|
||||
|
||||
expect(infoSpy).toHaveBeenCalledWith(warningMessage);
|
||||
expect(setOutputSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it(`should get 'cache-dependency-path' and call restoreCache() if input cache is set to true and cache feature is available`, async () => {
|
||||
inputs['dotnet-version'] = ['6.0.300'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['cache'] = true;
|
||||
inputs['cache-dependency-path'] = 'fictitious.package.lock.json';
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
isCacheFeatureAvailableSpy.mockImplementation(() => true);
|
||||
restoreCacheSpy.mockImplementation(() => Promise.resolve());
|
||||
|
||||
await setup.run();
|
||||
expect(isCacheFeatureAvailableSpy).toHaveBeenCalledTimes(1);
|
||||
expect(restoreCacheSpy).toHaveBeenCalledWith(
|
||||
inputs['cache-dependency-path']
|
||||
);
|
||||
});
|
||||
|
||||
it(`shouldn't call restoreCache() if input cache isn't set to true`, async () => {
|
||||
inputs['dotnet-version'] = ['6.0.300'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['cache'] = false;
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
isCacheFeatureAvailableSpy.mockImplementation(() => true);
|
||||
restoreCacheSpy.mockImplementation(() => Promise.resolve());
|
||||
|
||||
await setup.run();
|
||||
expect(restoreCacheSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it(`shouldn't call restoreCache() if cache feature isn't available`, async () => {
|
||||
inputs['dotnet-version'] = ['6.0.300'];
|
||||
inputs['dotnet-quality'] = '';
|
||||
inputs['cache'] = true;
|
||||
|
||||
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||
addToPathSpy.mockImplementation(() => {});
|
||||
|
||||
isCacheFeatureAvailableSpy.mockImplementation(() => false);
|
||||
restoreCacheSpy.mockImplementation(() => Promise.resolve());
|
||||
|
||||
await setup.run();
|
||||
expect(restoreCacheSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
expect(setOutputSpy).toBeCalledWith('dotnet-version', '3.0.103');
|
||||
}, 400000);
|
||||
});
|
||||
|
||||
@@ -1,117 +1,73 @@
|
||||
<#
|
||||
.DESCRIPTION
|
||||
Verifies that installed on the machine .NET SDK versions match the input patterns.
|
||||
Optionally checks that the nuget.config file is generated correctly.
|
||||
|
||||
.PARAMETER Patterns
|
||||
Specifies the regular expression patterns that should be matched with the installed
|
||||
on the machine .NET SDK versions. The number of patterns should be equal to the number
|
||||
of installed .NET versions.
|
||||
|
||||
.PARAMETER CheckNugetConfig
|
||||
Switches the check for the existence of the nuget.config file.
|
||||
|
||||
.EXAMPLE
|
||||
PS> .\verify-dotnet.ps1 -Paterns "^3.1.200$", "^6.0" -CheckNugetConfig
|
||||
#>
|
||||
|
||||
param(
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string[]]$Patterns,
|
||||
[switch]$CheckNugetConfig
|
||||
)
|
||||
|
||||
$PatternsList = [System.Collections.ArrayList]($Patterns)
|
||||
|
||||
if ($CheckNugetConfig.IsPresent -and !(Test-Path "../nuget.config")) {
|
||||
throw "The nuget.config file is not generated correctly."
|
||||
if (!$args[0])
|
||||
{
|
||||
throw "Must supply dotnet version argument"
|
||||
}
|
||||
|
||||
Write-Host "These patterns were supplied to the script: $($PatternsList -join ', ')."
|
||||
$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path }
|
||||
Write-Host "Found: '$dotnet'"
|
||||
Write-Host "Found '$dotnet'"
|
||||
|
||||
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
||||
$Versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
||||
Write-Host "Found installed versions: $($Versions -join ', ')."
|
||||
$InstalledVersionCount = $Versions.Count
|
||||
|
||||
foreach($version in $Versions)
|
||||
if($args.count -eq 1)
|
||||
{
|
||||
foreach($pattern in $PatternsList)
|
||||
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
|
||||
Write-Host "Version $version"
|
||||
if (-not ($version.StartsWith($args[0].ToString())))
|
||||
{
|
||||
if ($version -match $pattern)
|
||||
{
|
||||
$PatternsList.Remove($pattern)
|
||||
$InstalledVersionCount--
|
||||
break
|
||||
Write-Host "PATH='$env:PATH'"
|
||||
throw "Unexpected version"
|
||||
}
|
||||
}
|
||||
|
||||
if ($args[1])
|
||||
{
|
||||
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
||||
$versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
||||
Write-Host "Installed versions: $versions"
|
||||
$InstalledVersionCount = 0
|
||||
foreach($arg in $args){
|
||||
foreach ($version in $versions)
|
||||
{
|
||||
if ($version.StartsWith($arg.ToString()))
|
||||
{
|
||||
$InstalledVersionCount++
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $InstalledVersionCount -ne $args.Count)
|
||||
{
|
||||
Write-Host "PATH='$env:PATH'"
|
||||
throw "Unexpected version"
|
||||
}
|
||||
}
|
||||
|
||||
if ( $InstalledVersionCount -ne 0)
|
||||
Write-Host "Building sample csproj"
|
||||
& $dotnet build __tests__/sample-csproj/ --no-cache
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
throw "An unexpected version of Dotnet is found on the machine, please check the correctness of the -Patterns input."
|
||||
throw "Unexpected exit code $LASTEXITCODE"
|
||||
}
|
||||
|
||||
$workingDir = Get-Location
|
||||
$testProjectDir = "./__tests__/e2e-test-csproj"
|
||||
Write-Host "Changing directory to the $testProjectDir"
|
||||
Set-Location $testProjectDir
|
||||
|
||||
$targetFrameworkVersionMap = @{
|
||||
"1.0" = "netcoreapp1.0";
|
||||
"1.1" = "netcoreapp1.1";
|
||||
"2.0" = "netcoreapp2.0";
|
||||
"2.1" = "netcoreapp2.1";
|
||||
"2.2" = "netcoreapp2.2";
|
||||
"3.0" = "netcoreapp3.0";
|
||||
"3.1" = "netcoreapp3.1";
|
||||
"5.0" = "net5.0";
|
||||
"6.0" = "net6.0";
|
||||
"7.0" = "net7.0";
|
||||
"8.0" = "net8.0";
|
||||
}
|
||||
|
||||
foreach ($version in $Versions)
|
||||
Write-Host "Testing compiled app"
|
||||
$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
|
||||
Write-Host "Sample output: $sample_output"
|
||||
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
||||
if ($args[1])
|
||||
{
|
||||
# Creating temporary global.json file inside e2e-test-csproj dir and setting exact version of .NET inside allows to override default behavior of .NET and run build and tests on that exact version.
|
||||
Write-Host "Creating temporary global.json file for $version .NET version."
|
||||
& $dotnet new globaljson --sdk-version $version --force | Out-Null
|
||||
if (!(Test-Path "./global.json"))
|
||||
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
|
||||
{
|
||||
throw "An error occured while creating the global.json file. Exit code: $LASTEXITCODE"
|
||||
throw "Unexpected output"
|
||||
}
|
||||
}
|
||||
if ($args[2])
|
||||
{
|
||||
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*Test Run Successful.*")
|
||||
{
|
||||
throw "Unexpected output"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($sample_output -notlike "*Test Run Successful.*")
|
||||
{
|
||||
throw "Unexpected output"
|
||||
}
|
||||
Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)."
|
||||
|
||||
# Environment variable TEST_TARGET_FRAMEWORK is used inside the test.csproj file to target required framework version
|
||||
$version -match "^(?<key>\d+\.\d+)" | Out-Null
|
||||
if (!($targetFrameworkVersionMap.ContainsKey($Matches.key)))
|
||||
{
|
||||
throw "The map with the framework targets doesn't contain a target name for the version $version."
|
||||
}
|
||||
Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMap[$Matches.key])"
|
||||
[Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMap[$Matches.key]))
|
||||
|
||||
Write-Host "Building test C# project with $version .NET version."
|
||||
& $dotnet build --no-cache
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
throw "Building process is not successful, exit code: $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host "Testing compiled C# project with $version .NET version."
|
||||
& $dotnet test --no-build
|
||||
if ($LASTEXITCODE -ne 0)
|
||||
{
|
||||
throw "Testing process is not successful, exit code: $LASTEXITCODE"
|
||||
}
|
||||
|
||||
Write-Host "Tests are completed successfully!"
|
||||
|
||||
Write-Host "Removing temporary global.json file."
|
||||
Remove-Item ./global.json
|
||||
}
|
||||
|
||||
Set-Location $workingDir
|
||||
|
||||
44
__tests__/verify-dotnet.sh
Executable file
44
__tests__/verify-dotnet.sh
Executable file
@@ -0,0 +1,44 @@
|
||||
if [ -z "$1" ]; then
|
||||
echo "Must supply dotnet version argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "../nuget.config" ]; then
|
||||
echo "nuget file not generated correctly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dotnet_version="$(dotnet --version)"
|
||||
echo "Found dotnet version '$dotnet_version'"
|
||||
if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
||||
echo "Unexpected version"
|
||||
exit 1
|
||||
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"
|
||||
dotnet build __tests__/sample-csproj/ --no-cache || exit 1
|
||||
|
||||
echo "Testing compiled app"
|
||||
sample_output=$(dotnet test __tests__/sample-csproj/ --no-build)
|
||||
echo "Sample output: $sample_output"
|
||||
# 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"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then
|
||||
echo "Unexpected output"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
15
action.yml
15
action.yml
@@ -6,7 +6,7 @@ branding:
|
||||
color: green
|
||||
inputs:
|
||||
dotnet-version:
|
||||
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x, 3.x, 6.0.2xx'
|
||||
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x, 3.x'
|
||||
dotnet-quality:
|
||||
description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.'
|
||||
global-json-file:
|
||||
@@ -17,20 +17,9 @@ inputs:
|
||||
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
|
||||
config-file:
|
||||
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
|
||||
cache:
|
||||
description: 'Optional input to enable caching of the NuGet global-packages folder'
|
||||
required: false
|
||||
default: false
|
||||
cache-dependency-path:
|
||||
description: 'Used to specify the path to a dependency file: packages.lock.json. Supports wildcards or a list of file names for caching multiple dependencies.'
|
||||
required: false
|
||||
outputs:
|
||||
cache-hit:
|
||||
description: 'A boolean value to indicate if a cache was hit.'
|
||||
dotnet-version:
|
||||
description: 'Contains the installed by action .NET SDK version for reuse.'
|
||||
runs:
|
||||
using: 'node16'
|
||||
main: 'dist/setup/index.js'
|
||||
post: 'dist/cache-save/index.js'
|
||||
post-if: success()
|
||||
main: 'dist/index.js'
|
||||
|
||||
89370
dist/cache-save/index.js
vendored
89370
dist/cache-save/index.js
vendored
File diff suppressed because one or more lines are too long
21277
dist/index.js
vendored
Normal file
21277
dist/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
102276
dist/setup/index.js
vendored
102276
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -61,13 +61,12 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
|
||||
|
||||
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
|
||||
- To comply with the code style, **you need to run the `format` script**
|
||||
- To lint the code, **you need to run the `lint:fix` script**
|
||||
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
|
||||
|
||||
**Learn more about how to implement tests:**
|
||||
|
||||
Adding or changing tests is an integral part of making a change to the code.
|
||||
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [e2e-tests.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/e2e-tests.yml).
|
||||
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [workflow.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/workflow.yml).
|
||||
|
||||
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality
|
||||
- Tests should cover a successful execution, as well as some edge cases and possible errors
|
||||
|
||||
3106
externals/install-dotnet.ps1
vendored
3106
externals/install-dotnet.ps1
vendored
File diff suppressed because it is too large
Load Diff
312
externals/install-dotnet.sh
vendored
312
externals/install-dotnet.sh
vendored
@@ -298,20 +298,11 @@ get_machine_architecture() {
|
||||
if command -v uname > /dev/null; then
|
||||
CPUName=$(uname -m)
|
||||
case $CPUName in
|
||||
armv1*|armv2*|armv3*|armv4*|armv5*|armv6*)
|
||||
echo "armv6-or-below"
|
||||
return 0
|
||||
;;
|
||||
armv*l)
|
||||
echo "arm"
|
||||
return 0
|
||||
;;
|
||||
aarch64|arm64)
|
||||
if [ "$(getconf LONG_BIT)" -lt 64 ]; then
|
||||
# This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
|
||||
echo "arm"
|
||||
return 0
|
||||
fi
|
||||
echo "arm64"
|
||||
return 0
|
||||
;;
|
||||
@@ -319,22 +310,6 @@ get_machine_architecture() {
|
||||
echo "s390x"
|
||||
return 0
|
||||
;;
|
||||
ppc64le)
|
||||
echo "ppc64le"
|
||||
return 0
|
||||
;;
|
||||
loongarch64)
|
||||
echo "loongarch64"
|
||||
return 0
|
||||
;;
|
||||
riscv64)
|
||||
echo "riscv64"
|
||||
return 0
|
||||
;;
|
||||
powerpc|ppc)
|
||||
echo "ppc"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -351,13 +326,7 @@ get_normalized_architecture_from_architecture() {
|
||||
local architecture="$(to_lowercase "$1")"
|
||||
|
||||
if [[ $architecture == \<auto\> ]]; then
|
||||
machine_architecture="$(get_machine_architecture)"
|
||||
if [[ "$machine_architecture" == "armv6-or-below" ]]; then
|
||||
say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo $machine_architecture
|
||||
echo "$(get_machine_architecture)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -378,14 +347,6 @@ get_normalized_architecture_from_architecture() {
|
||||
echo "s390x"
|
||||
return 0
|
||||
;;
|
||||
ppc64le)
|
||||
echo "ppc64le"
|
||||
return 0
|
||||
;;
|
||||
loongarch64)
|
||||
echo "loongarch64"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||
@@ -423,17 +384,11 @@ get_normalized_architecture_for_specific_sdk_version() {
|
||||
# args:
|
||||
# version or channel - $1
|
||||
is_arm64_supported() {
|
||||
# Extract the major version by splitting on the dot
|
||||
major_version="${1%%.*}"
|
||||
|
||||
# Check if the major version is a valid number and less than 6
|
||||
case "$major_version" in
|
||||
[0-9]*)
|
||||
if [ "$major_version" -lt 6 ]; then
|
||||
echo false
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
#any channel or version that starts with the specified versions
|
||||
case "$1" in
|
||||
( "1"* | "2"* | "3"* | "4"* | "5"*)
|
||||
echo false
|
||||
return 0
|
||||
esac
|
||||
|
||||
echo true
|
||||
@@ -452,13 +407,8 @@ get_normalized_os() {
|
||||
echo "$osname"
|
||||
return 0
|
||||
;;
|
||||
macos)
|
||||
osname='osx'
|
||||
echo "$osname"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
@@ -588,40 +538,6 @@ is_dotnet_package_installed() {
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# downloaded file - $1
|
||||
# remote_file_size - $2
|
||||
validate_remote_local_file_sizes()
|
||||
{
|
||||
eval $invocation
|
||||
|
||||
local downloaded_file="$1"
|
||||
local remote_file_size="$2"
|
||||
local file_size=''
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
file_size="$(stat -c '%s' "$downloaded_file")"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# hardcode in order to avoid conflicts with GNU stat
|
||||
file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
|
||||
fi
|
||||
|
||||
if [ -n "$file_size" ]; then
|
||||
say "Downloaded file size is $file_size bytes."
|
||||
|
||||
if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
|
||||
if [ "$remote_file_size" -ne "$file_size" ]; then
|
||||
say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
|
||||
else
|
||||
say "The remote and local file sizes are equal."
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
say "Either downloaded or local package size can not be measured. One of them may be corrupted."
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# channel - $2
|
||||
@@ -956,37 +872,6 @@ get_absolute_path() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# override - $1 (boolean, true or false)
|
||||
get_cp_options() {
|
||||
eval $invocation
|
||||
|
||||
local override="$1"
|
||||
local override_switch=""
|
||||
|
||||
if [ "$override" = false ]; then
|
||||
override_switch="-n"
|
||||
|
||||
# create temporary files to check if 'cp -u' is supported
|
||||
tmp_dir="$(mktemp -d)"
|
||||
tmp_file="$tmp_dir/testfile"
|
||||
tmp_file2="$tmp_dir/testfile2"
|
||||
|
||||
touch "$tmp_file"
|
||||
|
||||
# use -u instead of -n if it's available
|
||||
if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
|
||||
override_switch="-u"
|
||||
fi
|
||||
|
||||
# clean up
|
||||
rm -f "$tmp_file" "$tmp_file2"
|
||||
rm -rf "$tmp_dir"
|
||||
fi
|
||||
|
||||
echo "$override_switch"
|
||||
}
|
||||
|
||||
# args:
|
||||
# input_files - stdin
|
||||
# root_path - $1
|
||||
@@ -998,7 +883,15 @@ copy_files_or_dirs_from_list() {
|
||||
local root_path="$(remove_trailing_slash "$1")"
|
||||
local out_path="$(remove_trailing_slash "$2")"
|
||||
local override="$3"
|
||||
local override_switch="$(get_cp_options "$override")"
|
||||
local osname="$(get_current_os_name)"
|
||||
local override_switch=$(
|
||||
if [ "$override" = false ]; then
|
||||
if [ "$osname" = "linux-musl" ]; then
|
||||
printf -- "-u";
|
||||
else
|
||||
printf -- "-n";
|
||||
fi
|
||||
fi)
|
||||
|
||||
cat | uniq | while read -r file_path; do
|
||||
local path="$(remove_beginning_slash "${file_path#$root_path}")"
|
||||
@@ -1013,39 +906,14 @@ copy_files_or_dirs_from_list() {
|
||||
done
|
||||
}
|
||||
|
||||
# args:
|
||||
# zip_uri - $1
|
||||
get_remote_file_size() {
|
||||
local zip_uri="$1"
|
||||
|
||||
if machine_has "curl"; then
|
||||
file_size=$(curl -sI "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
|
||||
elif machine_has "wget"; then
|
||||
file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
|
||||
else
|
||||
say "Neither curl nor wget is available on this system."
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$file_size" ]; then
|
||||
say "Remote file $zip_uri size is $file_size bytes."
|
||||
echo "$file_size"
|
||||
else
|
||||
say_verbose "Content-Length header was not extracted for $zip_uri."
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# zip_path - $1
|
||||
# out_path - $2
|
||||
# remote_file_size - $3
|
||||
extract_dotnet_package() {
|
||||
eval $invocation
|
||||
|
||||
local zip_path="$1"
|
||||
local out_path="$2"
|
||||
local remote_file_size="$3"
|
||||
|
||||
local temp_out_path="$(mktemp -d "$temporary_file_template")"
|
||||
|
||||
@@ -1055,13 +923,9 @@ extract_dotnet_package() {
|
||||
local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/'
|
||||
find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
|
||||
find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
|
||||
|
||||
validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
|
||||
|
||||
|
||||
rm -rf "$temp_out_path"
|
||||
if [ -z ${keep_zip+x} ]; then
|
||||
rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed"
|
||||
fi
|
||||
rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
say_err "Extraction failed"
|
||||
@@ -1272,61 +1136,6 @@ downloadwget() {
|
||||
return 0
|
||||
}
|
||||
|
||||
extract_stem() {
|
||||
local url="$1"
|
||||
# extract the protocol
|
||||
proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
|
||||
# remove the protocol
|
||||
url="${1/$proto/}"
|
||||
# extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
|
||||
full_path="$(echo $url | grep / | cut -d/ -f2-)"
|
||||
path="$(echo $full_path | cut -d/ -f2-)"
|
||||
echo $path
|
||||
}
|
||||
|
||||
check_url_exists() {
|
||||
eval $invocation
|
||||
local url="$1"
|
||||
|
||||
local code=""
|
||||
if machine_has "curl"
|
||||
then
|
||||
code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
|
||||
elif machine_has "wget"
|
||||
then
|
||||
# get the http response, grab the status code
|
||||
server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
|
||||
code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
|
||||
fi
|
||||
if [ $code = "200" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
sanitize_redirect_url() {
|
||||
eval $invocation
|
||||
|
||||
local url_stem
|
||||
url_stem=$(extract_stem "$1")
|
||||
say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
|
||||
|
||||
for feed in "${feeds[@]}"
|
||||
do
|
||||
local trial_url="$feed/$url_stem"
|
||||
say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
|
||||
if check_url_exists "$trial_url"; then
|
||||
say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
|
||||
echo "$trial_url"
|
||||
return 0
|
||||
else
|
||||
say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
get_download_link_from_aka_ms() {
|
||||
eval $invocation
|
||||
|
||||
@@ -1363,12 +1172,6 @@ get_download_link_from_aka_ms() {
|
||||
http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
|
||||
# They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
|
||||
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
|
||||
# The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
|
||||
# In this case it should not exclude the last.
|
||||
last_http_code=$( echo "$http_codes" | tail -n 1 )
|
||||
if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
|
||||
broken_redirects=$( echo "$http_codes" | grep -v '301' )
|
||||
fi
|
||||
|
||||
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
|
||||
if [[ -z "$broken_redirects" ]]; then
|
||||
@@ -1379,11 +1182,6 @@ get_download_link_from_aka_ms() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
|
||||
if [[ -n "$sanitized_redirect_url" ]]; then
|
||||
aka_ms_download_link="$sanitized_redirect_url"
|
||||
fi
|
||||
|
||||
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
|
||||
return 0
|
||||
else
|
||||
@@ -1395,16 +1193,23 @@ get_download_link_from_aka_ms() {
|
||||
get_feeds_to_use()
|
||||
{
|
||||
feeds=(
|
||||
"https://builds.dotnet.microsoft.com/dotnet"
|
||||
"https://ci.dot.net/public"
|
||||
"https://dotnetcli.azureedge.net/dotnet"
|
||||
"https://dotnetbuilds.azureedge.net/public"
|
||||
)
|
||||
|
||||
if [[ -n "$azure_feed" ]]; then
|
||||
feeds=("$azure_feed")
|
||||
fi
|
||||
|
||||
if [[ -n "$uncached_feed" ]]; then
|
||||
feeds=("$uncached_feed")
|
||||
if [[ "$no_cdn" == "true" ]]; then
|
||||
feeds=(
|
||||
"https://dotnetcli.blob.core.windows.net/dotnet"
|
||||
"https://dotnetbuilds.blob.core.windows.net/public"
|
||||
)
|
||||
|
||||
if [[ -n "$uncached_feed" ]]; then
|
||||
feeds=("$uncached_feed")
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1536,7 +1341,7 @@ generate_regular_links() {
|
||||
link_types+=("legacy")
|
||||
else
|
||||
legacy_download_link=""
|
||||
say_verbose "Could not construct a legacy_download_link; omitting..."
|
||||
say_verbose "Cound not construct a legacy_download_link; omitting..."
|
||||
fi
|
||||
|
||||
# Check if the SDK version is already installed.
|
||||
@@ -1614,11 +1419,10 @@ install_dotnet() {
|
||||
eval $invocation
|
||||
local download_failed=false
|
||||
local download_completed=false
|
||||
local remote_file_size=0
|
||||
|
||||
mkdir -p "$install_root"
|
||||
zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
|
||||
say_verbose "Archive path: $zip_path"
|
||||
zip_path="$(mktemp "$temporary_file_template")"
|
||||
say_verbose "Zip path: $zip_path"
|
||||
|
||||
for link_index in "${!download_links[@]}"
|
||||
do
|
||||
@@ -1639,10 +1443,10 @@ install_dotnet() {
|
||||
say "The resource at $link_type link '$download_link' is not available."
|
||||
;;
|
||||
*)
|
||||
say "Failed to download $link_type link '$download_link': $http_code $download_error_msg"
|
||||
say "Failed to download $link_type link '$download_link': $download_error_msg"
|
||||
;;
|
||||
esac
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
|
||||
else
|
||||
download_completed=true
|
||||
break
|
||||
@@ -1655,10 +1459,8 @@ install_dotnet() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
remote_file_size="$(get_remote_file_size "$download_link")"
|
||||
|
||||
say "Extracting archive from $download_link"
|
||||
extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
|
||||
say "Extracting zip from $download_link"
|
||||
extract_dotnet_package "$zip_path" "$install_root" || return 1
|
||||
|
||||
# Check if the SDK version is installed; if not, fail the installation.
|
||||
# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
|
||||
@@ -1700,6 +1502,7 @@ install_dir="<auto>"
|
||||
architecture="<auto>"
|
||||
dry_run=false
|
||||
no_path=false
|
||||
no_cdn=false
|
||||
azure_feed=""
|
||||
uncached_feed=""
|
||||
feed_credential=""
|
||||
@@ -1772,6 +1575,10 @@ do
|
||||
verbose=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--no-cdn|-[Nn]o[Cc]dn)
|
||||
no_cdn=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--azure-feed|-[Aa]zure[Ff]eed)
|
||||
shift
|
||||
azure_feed="$1"
|
||||
@@ -1803,29 +1610,13 @@ do
|
||||
override_non_versioned_files=false
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--keep-zip|-[Kk]eep[Zz]ip)
|
||||
keep_zip=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--zip-path|-[Zz]ip[Pp]ath)
|
||||
shift
|
||||
zip_path="$1"
|
||||
;;
|
||||
-?|--?|-h|--help|-[Hh]elp)
|
||||
script_name="dotnet-install.sh"
|
||||
script_name="$(basename "$0")"
|
||||
echo ".NET Tools Installer"
|
||||
echo "Usage:"
|
||||
echo " # Install a .NET SDK of a given Quality from a given Channel"
|
||||
echo " $script_name [-c|--channel <CHANNEL>] [-q|--quality <QUALITY>]"
|
||||
echo " # Install a .NET SDK of a specific public version"
|
||||
echo " $script_name [-v|--version <VERSION>]"
|
||||
echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]"
|
||||
echo " $script_name -h|-?|--help"
|
||||
echo ""
|
||||
echo "$script_name is a simple command line interface for obtaining dotnet cli."
|
||||
echo " Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
echo " - The SDK needs to be installed without user interaction and without admin rights."
|
||||
echo " - The SDK installation doesn't need to persist across multiple CI runs."
|
||||
echo " To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -c,--channel <CHANNEL> Download from the channel specified, Defaults to \`$channel\`."
|
||||
@@ -1860,7 +1651,7 @@ do
|
||||
echo " -InstallDir"
|
||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||
echo " --arch,-Architecture,-Arch"
|
||||
echo " Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
|
||||
echo " Possible values: x64, arm, arm64 and s390x"
|
||||
echo " --os <system> Specifies operating system to be used when selecting the installer."
|
||||
echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
|
||||
echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
|
||||
@@ -1876,14 +1667,15 @@ do
|
||||
echo " --verbose,-Verbose Display diagnostics information."
|
||||
echo " --azure-feed,-AzureFeed For internal use only."
|
||||
echo " Allows using a different storage to download SDK archives from."
|
||||
echo " This parameter is only used if --no-cdn is false."
|
||||
echo " --uncached-feed,-UncachedFeed For internal use only."
|
||||
echo " Allows using a different storage to download SDK archives from."
|
||||
echo " This parameter is only used if --no-cdn is true."
|
||||
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||
echo " -SkipNonVersionedFiles"
|
||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
|
||||
echo " Note: global.json must have a value for 'SDK:Version'"
|
||||
echo " --keep-zip,-KeepZip If set, downloaded file is kept."
|
||||
echo " --zip-path, -ZipPath If set, downloaded file is stored at the specified path."
|
||||
echo " -?,--?,-h,--help,-Help Shows this help message"
|
||||
echo ""
|
||||
echo "Install Location:"
|
||||
@@ -1902,10 +1694,10 @@ do
|
||||
shift
|
||||
done
|
||||
|
||||
say_verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
say_verbose "- The SDK needs to be installed without user interaction and without admin rights."
|
||||
say_verbose "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||
say_verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||
say "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
say "- The SDK needs to be installed without user interaction and without admin rights."
|
||||
say "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||
say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||
|
||||
if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
|
||||
message="Provide credentials via --feed-credential parameter."
|
||||
@@ -1939,4 +1731,4 @@ fi
|
||||
|
||||
say "Note that the script does not resolve dependencies during installation."
|
||||
say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
||||
say "Installation finished successfully."
|
||||
say "Installation finished successfully."
|
||||
|
||||
5677
package-lock.json
generated
5677
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user