mirror of
https://github.com/actions/setup-dotnet.git
synced 2026-03-22 14:42:20 +08:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e6bd2905e | ||
|
|
603ff3ab1c | ||
|
|
d284574c05 | ||
|
|
bac33b41f7 | ||
|
|
f56a6a6861 | ||
|
|
fb81433816 | ||
|
|
9798ae12d7 | ||
|
|
aab9aab748 |
@@ -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
|
|
||||||
}
|
|
||||||
};
|
|
||||||
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -1,2 +1 @@
|
|||||||
* text=auto eol=lf
|
.licenses/** -diff linguist-generated=true
|
||||||
.licenses/** -diff linguist-generated=true
|
|
||||||
2
.github/CODEOWNERS
vendored
2
.github/CODEOWNERS
vendored
@@ -1 +1 @@
|
|||||||
* @actions/setup-actions-team
|
* @actions/virtual-environments-owners
|
||||||
|
|||||||
17
.github/workflows/basic-validation.yml
vendored
17
.github/workflows/basic-validation.yml
vendored
@@ -1,17 +0,0 @@
|
|||||||
name: Basic validation
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- releases/*
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
call-basic-validation:
|
|
||||||
name: Basic validation
|
|
||||||
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
|
||||||
41
.github/workflows/check-dist.yml
vendored
41
.github/workflows/check-dist.yml
vendored
@@ -1,3 +1,8 @@
|
|||||||
|
# `dist/index.js` is a special file in Actions.
|
||||||
|
# When you reference an action with `uses:` in a workflow,
|
||||||
|
# `index.js` is the code that will run.
|
||||||
|
# For our project, we generate this file through a build process from other source files.
|
||||||
|
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||||
name: Check dist/
|
name: Check dist/
|
||||||
|
|
||||||
on:
|
on:
|
||||||
@@ -12,6 +17,36 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-check-dist:
|
check-dist:
|
||||||
name: Check dist/
|
runs-on: ubuntu-latest
|
||||||
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set Node.js 16
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16.x
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci --ignore-scripts
|
||||||
|
|
||||||
|
- name: Rebuild the dist/ directory
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Compare the expected and actual dist/ directories
|
||||||
|
run: |
|
||||||
|
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||||
|
echo "Detected uncommitted changes after build. See status below:"
|
||||||
|
git diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
id: diff
|
||||||
|
|
||||||
|
# If index.js was different than expected, upload the expected version as an artifact
|
||||||
|
- uses: actions/upload-artifact@v4
|
||||||
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
||||||
|
|||||||
70
.github/workflows/codeql-analysis.yml
vendored
70
.github/workflows/codeql-analysis.yml
vendored
@@ -1,14 +1,70 @@
|
|||||||
name: CodeQL analysis
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [ main ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [main]
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ main ]
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 3 * * 0'
|
- cron: '23 19 * * 0'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-codeQL-analysis:
|
analyze:
|
||||||
name: CodeQL analysis
|
name: Analyze
|
||||||
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'javascript' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|||||||
428
.github/workflows/e2e-tests.yml
vendored
428
.github/workflows/e2e-tests.yml
vendored
@@ -1,428 +0,0 @@
|
|||||||
name: e2e tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- releases/*
|
|
||||||
paths-ignore:
|
|
||||||
- '**.md'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test-setup-multiple-versions:
|
|
||||||
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 2.2.402, 3.1.404 and 3.0.x
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: |
|
|
||||||
2.2.402
|
|
||||||
3.1.404
|
|
||||||
3.0.x
|
|
||||||
- name: Verify dotnet
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/verify-dotnet.ps1 -Patterns "^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]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Clear toolcache
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
|
||||||
# Side-by-side install of 2.2 and 3.1 used for the test project
|
|
||||||
- name: Setup dotnet 2.2.402
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.2.402
|
|
||||||
- name: Setup dotnet 3.1.201
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.201
|
|
||||||
# We are including this variable to force the generation of the nuget config file to verify that it is created in the correct place
|
|
||||||
source-url: https://api.nuget.org/v3/index.json
|
|
||||||
env:
|
|
||||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
|
||||||
- name: Verify dotnet
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$", "^2.2.402$" -CheckNugetConfig
|
|
||||||
|
|
||||||
test-setup-without-patch-version:
|
|
||||||
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 }}
|
|
||||||
# 2.0, 3.0, 5.0 needs to be in single quotes to interpret as a string instead of as an integer
|
|
||||||
- name: Setup dotnet '3.1'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: '3.1'
|
|
||||||
- name: Setup dotnet '2.2'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: '2.2'
|
|
||||||
- name: Verify dotnet
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/verify-dotnet.ps1 -Patterns "^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]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Clear toolcache
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
|
||||||
- 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"
|
|
||||||
|
|
||||||
test-setup-latest-patch-version:
|
|
||||||
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 3.1.x
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.x
|
|
||||||
- name: Setup dotnet 2.2.X
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
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}"
|
|
||||||
|
|
||||||
test-setup-with-wildcard:
|
|
||||||
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 3.1.*
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.*
|
|
||||||
- name: Setup dotnet 2.2.*
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.2.*
|
|
||||||
- name: Verify dotnet
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/verify-dotnet.ps1 -Patterns "^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]
|
|
||||||
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:
|
|
||||||
dotnet-version: 3.1
|
|
||||||
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"
|
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
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" }
|
|
||||||
|
|
||||||
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 }}
|
|
||||||
|
|
||||||
- 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" }
|
|
||||||
|
|
||||||
test-proxy:
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
container:
|
|
||||||
image: ubuntu:latest
|
|
||||||
options: --dns 127.0.0.1
|
|
||||||
services:
|
|
||||||
squid-proxy:
|
|
||||||
image: ubuntu/squid:latest
|
|
||||||
ports:
|
|
||||||
- 3128:3128
|
|
||||||
env:
|
|
||||||
https_proxy: http://squid-proxy:3128
|
|
||||||
http_proxy: http://squid-proxy:3128
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
- name: Install Powershell
|
|
||||||
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 }}
|
|
||||||
- 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
|
|
||||||
shell: pwsh
|
|
||||||
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$" -CheckNugetConfig
|
|
||||||
16
.github/workflows/licensed.yml
vendored
16
.github/workflows/licensed.yml
vendored
@@ -10,6 +10,16 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
call-licensed:
|
test:
|
||||||
name: Licensed
|
runs-on: ubuntu-latest
|
||||||
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
name: Check licenses
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: npm ci --ignore-scripts
|
||||||
|
- name: Install licensed
|
||||||
|
run: |
|
||||||
|
cd $RUNNER_TEMP
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
|
||||||
|
sudo tar -xzf licensed.tar.gz
|
||||||
|
sudo mv licensed /usr/local/bin/licensed
|
||||||
|
- run: licensed status
|
||||||
|
|||||||
13
.github/workflows/release-new-action-version.yml
vendored
13
.github/workflows/release-new-action-version.yml
vendored
@@ -1,5 +1,4 @@
|
|||||||
name: Release new action version
|
name: Release new action version
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [released]
|
types: [released]
|
||||||
@@ -21,9 +20,9 @@ jobs:
|
|||||||
name: releaseNewActionVersion
|
name: releaseNewActionVersion
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
id: update-major-tag
|
id: update-major-tag
|
||||||
uses: actions/publish-action@v0.2.2
|
uses: actions/publish-action@v0.1.0
|
||||||
with:
|
with:
|
||||||
source-tag: ${{ env.TAG_NAME }}
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
8
.github/workflows/test-dotnet.yml
vendored
8
.github/workflows/test-dotnet.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
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']
|
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0']
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@@ -29,7 +29,9 @@ jobs:
|
|||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet-version }}
|
dotnet-version: ${{ matrix.dotnet-version }}
|
||||||
- name: Verify installed version
|
- name: Check installed version
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
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
|
|
||||||
244
.github/workflows/workflow.yml
vendored
Normal file
244
.github/workflows/workflow.yml
vendored
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
name: Main workflow
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/*
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
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: Set Node.js 16
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16.x
|
||||||
|
cache: npm
|
||||||
|
- run: npm ci --ignore-scripts
|
||||||
|
- run: npm run build
|
||||||
|
- run: npm run format-check
|
||||||
|
- run: npm test
|
||||||
|
- name: Verify no unstaged changes
|
||||||
|
if: runner.os != 'windows'
|
||||||
|
run: __tests__/verify-no-unstaged-changes.sh
|
||||||
|
|
||||||
|
test-setup-multiple-versions:
|
||||||
|
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 2.2.402 and 3.1.404
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
2.2.402
|
||||||
|
3.1.404
|
||||||
|
3.0.x
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
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]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
# Side-by-side install of 2.2 and 3.1 used for the test project
|
||||||
|
- name: Setup dotnet 2.2.402
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.402
|
||||||
|
- name: Setup dotnet 3.1.201
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.201
|
||||||
|
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place
|
||||||
|
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 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]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
# 2.0, 3.0, 5.0 needs to be in single quotes to interpret as a string instead of as an integer
|
||||||
|
- name: Setup dotnet '3.1'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '3.1'
|
||||||
|
- name: Setup dotnet '2.2'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '2.2'
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||||
|
|
||||||
|
test-setup-latest-patch-version:
|
||||||
|
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 3.1.x
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.x
|
||||||
|
- name: Setup dotnet 2.2.x
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.x
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||||
|
|
||||||
|
test-setup-with-wildcard:
|
||||||
|
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 3.1.*
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.*
|
||||||
|
- name: Setup dotnet 2.2.*
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.*
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
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]
|
||||||
|
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","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1
|
||||||
|
global-json-file: ./subdirectory/global.json
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 2.2 3.1
|
||||||
|
|
||||||
|
test-proxy:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
container:
|
||||||
|
image: ubuntu:20.04
|
||||||
|
options: --dns 127.0.0.1
|
||||||
|
services:
|
||||||
|
squid-proxy:
|
||||||
|
image: ubuntu/squid:latest
|
||||||
|
ports:
|
||||||
|
- 3128:3128
|
||||||
|
env:
|
||||||
|
https_proxy: http://squid-proxy:3128
|
||||||
|
http_proxy: http://squid-proxy:3128
|
||||||
|
DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear tool cache
|
||||||
|
run: rm -rf "/usr/share/dotnet"
|
||||||
|
- name: Install curl
|
||||||
|
run: |
|
||||||
|
apt update
|
||||||
|
apt -y install curl libssl1.1 libssl-dev
|
||||||
|
- 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
|
||||||
|
|
||||||
|
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 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
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,8 +3,8 @@ global.json
|
|||||||
lib/
|
lib/
|
||||||
node_modules/
|
node_modules/
|
||||||
__tests__/runner/*
|
__tests__/runner/*
|
||||||
__tests__/e2e-test-csproj/bin/
|
__tests__/sample-csproj/bin/
|
||||||
__tests__/e2e-test-csproj/obj/
|
__tests__/sample-csproj/obj/
|
||||||
|
|
||||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||||
# Logs
|
# Logs
|
||||||
|
|||||||
@@ -2,4 +2,3 @@
|
|||||||
. "$(dirname -- "$0")/_/husky.sh"
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm run format
|
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
|
# Tests are not run at push time since they can take 2-4 minutes to complete
|
||||||
npm run format-check
|
npm run format-check
|
||||||
npm run lint
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ sources:
|
|||||||
|
|
||||||
allowed:
|
allowed:
|
||||||
- apache-2.0
|
- apache-2.0
|
||||||
- 0bsd
|
|
||||||
- bsd-2-clause
|
- bsd-2-clause
|
||||||
- bsd-3-clause
|
- bsd-3-clause
|
||||||
- isc
|
- isc
|
||||||
@@ -12,5 +11,4 @@ allowed:
|
|||||||
- unlicense
|
- unlicense
|
||||||
|
|
||||||
reviewed:
|
reviewed:
|
||||||
npm:
|
npm:
|
||||||
- sax # ISC + MIT
|
|
||||||
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/exec.dep.yml
generated
BIN
.licenses/npm/@actions/exec.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.
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
BIN
.licenses/npm/@actions/io.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/fast-xml-parser.dep.yml
generated
BIN
.licenses/npm/fast-xml-parser.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/strnum.dep.yml
generated
BIN
.licenses/npm/strnum.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'
|
|
||||||
};
|
|
||||||
11
.prettierrc.json
Normal file
11
.prettierrc.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 80,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"bracketSpacing": false,
|
||||||
|
"arrowParens": "avoid",
|
||||||
|
"parser": "typescript"
|
||||||
|
}
|
||||||
252
README.md
252
README.md
@@ -1,7 +1,6 @@
|
|||||||
# setup-dotnet
|
# setup-dotnet
|
||||||
|
|
||||||
[](https://github.com/actions/setup-dotnet/actions/workflows/basic-validation.yml)
|
[](https://github.com/actions/setup-dotnet)
|
||||||
[](https://github.com/actions/setup-dotnet/actions/workflows/e2e-tests.yml)
|
|
||||||
|
|
||||||
This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for use in actions by:
|
This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for use in actions by:
|
||||||
|
|
||||||
@@ -9,139 +8,62 @@ This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for
|
|||||||
- registering problem matchers for error output
|
- registering problem matchers for error output
|
||||||
- setting up authentication to private package sources like GitHub Packages
|
- setting up authentication to private package sources like GitHub Packages
|
||||||
|
|
||||||
> **Note**: GitHub hosted runners have some versions of the .NET SDK
|
Please Note: GitHub hosted runners have some versions of the .NET SDK
|
||||||
preinstalled. Installed versions are subject to change. Please refer to the
|
preinstalled. Installed versions are subject to change. Please refer to the
|
||||||
documentation:
|
documentation
|
||||||
[Software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software)
|
[software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software)
|
||||||
for .NET SDK versions that are currently available.
|
for .NET SDK versions that are currently available.
|
||||||
|
|
||||||
## Usage
|
# Usage
|
||||||
|
|
||||||
See [action.yml](action.yml)
|
See [action.yml](action.yml)
|
||||||
|
|
||||||
**Basic**:
|
Basic:
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.x'
|
dotnet-version: '3.1.x' # SDK Version to use; x will use the latest version of the 3.1 channel
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
> **Warning**: Unless a concrete version is specified in the [`global.json`](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) file, **_the latest .NET version installed on the runner (including preinstalled versions) will be used [by default](https://learn.microsoft.com/en-us/dotnet/core/versions/selection#the-sdk-uses-the-latest-installed-version)_**. Please refer to the [documentation](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software) for the currently preinstalled .NET SDK versions.
|
Multiple versions:
|
||||||
|
> Note: In case multiple versions are installed, the latest .NET version will be used by default unless another version is specified in the `global.json` file.
|
||||||
|
|
||||||
**Multiple version installation**:
|
|
||||||
```yml
|
```yml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: |
|
dotnet-version: |
|
||||||
3.1.x
|
3.1.x
|
||||||
5.0.x
|
5.0.x
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
## Supported version syntax
|
Preview version:
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '6.0.x'
|
||||||
dotnet-quality: 'preview'
|
include-prerelease: true
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
|
global.json in a subdirectory:
|
||||||
## Using the `global-json-file` input
|
|
||||||
`setup-dotnet` action can read .NET SDK version from a `global.json` file. Input `global-json-file` is used for specifying the path to the `global.json`. If the file that was supplied to `global-json-file` input doesn't exist, the action will fail with error.
|
|
||||||
|
|
||||||
>**Note**: In case both `dotnet-version` and `global-json-file` inputs are used, versions from both inputs will be installed.
|
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
global-json-file: csharp/global.json
|
global-json-file: csharp/global.json
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
working-directory: csharp
|
working-directory: csharp
|
||||||
```
|
```
|
||||||
|
|
||||||
## Caching NuGet Packages
|
Matrix Testing:
|
||||||
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
|
```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
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -152,44 +74,38 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet }}
|
dotnet-version: ${{ matrix.dotnet }}
|
||||||
- name: Execute dotnet
|
- run: dotnet build <my project>
|
||||||
run: dotnet build <my project>
|
|
||||||
```
|
```
|
||||||
>**Note**: Unless a concrete version is specified in the [`global.json`](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) file, the latest .NET version installed on the runner (including preinstalled versions) will be used [by default](https://learn.microsoft.com/en-us/dotnet/core/versions/selection#the-sdk-uses-the-latest-installed-version). To control this behavior you may want to use temporary `global.json` files:
|
|
||||||
|
|
||||||
**Matrix testing with temporary global.json creation**
|
Side by Side Testing:
|
||||||
```yml
|
```yaml
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
name: Dotnet Side by Side testing sample
|
||||||
matrix:
|
|
||||||
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
|
|
||||||
name: Dotnet ${{ matrix.dotnet }} sample
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v3
|
uses: actions/setup-dotnet@v2
|
||||||
id: stepid
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet }}
|
dotnet-version: |
|
||||||
- name: Create temporary global.json
|
2.1.x
|
||||||
run: echo '{"sdk":{"version": "${{ steps.stepid.outputs.dotnet-version }}"}}' > ./global.json
|
3.1.x
|
||||||
- name: Execute dotnet
|
- run: dotnet build <my project>
|
||||||
run: dotnet build <my project>
|
- run: dotnet test <my project>
|
||||||
```
|
```
|
||||||
## Setting up authentication for nuget feeds
|
|
||||||
|
|
||||||
### Github Package Registry (GPR)
|
Authentication for nuget feeds:
|
||||||
```yml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v3
|
# Authenticates packages to push to GPR
|
||||||
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.x'
|
dotnet-version: '3.1.x' # SDK Version to use.
|
||||||
source-url: https://nuget.pkg.github.com/<owner>/index.json
|
source-url: https://nuget.pkg.github.com/<owner>/index.json
|
||||||
env:
|
env:
|
||||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||||
@@ -198,22 +114,19 @@ steps:
|
|||||||
run: dotnet pack --configuration Release <my project>
|
run: dotnet pack --configuration Release <my project>
|
||||||
- name: Publish the package to GPR
|
- name: Publish the package to GPR
|
||||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||||
```
|
|
||||||
|
|
||||||
### Azure Artifacts
|
# Authenticates packages to push to Azure Artifacts
|
||||||
```yml
|
- uses: actions/setup-dotnet@v2
|
||||||
- uses: actions/setup-dotnet@v3
|
|
||||||
with:
|
with:
|
||||||
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
||||||
env:
|
env:
|
||||||
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
||||||
- name: Publish the package to Azure Artifacts
|
- name: Publish the package to Azure Artifacts
|
||||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||||
```
|
|
||||||
|
|
||||||
### nuget.org
|
# Authenticates packages to push to nuget.org.
|
||||||
```yml
|
# It's only the way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.1.x
|
dotnet-version: 3.1.x
|
||||||
- name: Publish the package to nuget.org
|
- name: Publish the package to nuget.org
|
||||||
@@ -221,97 +134,32 @@ steps:
|
|||||||
env:
|
env:
|
||||||
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
||||||
```
|
```
|
||||||
> **Note**: It's the only way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
|
|
||||||
|
|
||||||
# Outputs and environment variables
|
## Environment Variables to use with dotnet
|
||||||
|
|
||||||
## Outputs
|
|
||||||
|
|
||||||
### `dotnet-version`
|
|
||||||
|
|
||||||
Using the **dotnet-version** output it's possible to get the installed by the action .NET SDK version.
|
|
||||||
|
|
||||||
**Single version installation**
|
|
||||||
|
|
||||||
In case of a single version installation, the `dotnet-version` output contains the version that is installed by the action.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: actions/setup-dotnet@v3
|
|
||||||
id: stepid
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.422
|
|
||||||
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 3.1.422
|
|
||||||
```
|
|
||||||
|
|
||||||
**Multiple version installation**
|
|
||||||
|
|
||||||
In case of a multiple version installation, the `dotnet-version` output contains the latest version that is installed by the action.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: actions/setup-dotnet@v3
|
|
||||||
id: stepid
|
|
||||||
with:
|
|
||||||
dotnet-version: |
|
|
||||||
3.1.422
|
|
||||||
5.0.408
|
|
||||||
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 5.0.408
|
|
||||||
```
|
|
||||||
**Installation from global.json**
|
|
||||||
|
|
||||||
When the `dotnet-version` input is used along with the `global-json-file` input, the `dotnet-version` output contains the version resolved from the `global.json`.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
- uses: actions/setup-dotnet@v3
|
|
||||||
id: stepid
|
|
||||||
with:
|
|
||||||
dotnet-version: |
|
|
||||||
3.1.422
|
|
||||||
5.0.408
|
|
||||||
global-json-file: "./global.json" # contains version 2.2.207
|
|
||||||
- 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
|
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
|
||||||
|
|
||||||
| **Env.variable** | **Description** | **Default value** |
|
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false)
|
||||||
| ----------- | ----------- | ----------- |
|
- DOTNET_CLI_TELEMETRY_OPTOUT - opt-out of telemetry being sent to Microsoft (default: false)
|
||||||
| DOTNET_INSTALL_DIR |Specifies a directory where .NET SDKs should be installed by the action.|*default value for each OS* |
|
- DOTNET_MULTILEVEL_LOOKUP - configures whether the global install location is used as a fall-back (default: true)
|
||||||
| 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:
|
Example usage:
|
||||||
| **Operation system** | `DOTNET_INSTALL_DIR` | `NUGET_PACKAGES` |
|
```yaml
|
||||||
| ----------- | ----------- | ----------- |
|
|
||||||
| **Windows** | `C:\Program Files\dotnet` | `%userprofile%\.nuget\packages` |
|
|
||||||
| **Ubuntu** | `/usr/share/dotnet` | `~/.nuget/packages` |
|
|
||||||
| **macOS** | `/Users/runner/.dotnet` | `~/.nuget/packages` |
|
|
||||||
|
|
||||||
**Example usage of environment variable**:
|
|
||||||
```yml
|
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
DOTNET_INSTALL_DIR: "path/to/directory"
|
DOTNET_NOLOGO: true
|
||||||
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@main
|
- uses: actions/checkout@main
|
||||||
- uses: actions/setup-dotnet@v3
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.x'
|
dotnet-version: '3.1.x' # SDK Version to use.
|
||||||
cache: true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
# License
|
||||||
|
|
||||||
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
The scripts and documentation in this project are released under the [MIT License](LICENSE)
|
||||||
|
|
||||||
## Contributions
|
# Contributions
|
||||||
|
|
||||||
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
|
Contributions are welcome! See [Contributor's Guide](docs/contributors.md)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// 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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -15,7 +15,7 @@ exports[`authutil tests existing config not in repo root, sets up a partial NuGe
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -30,7 +30,7 @@ exports[`authutil tests existing config w/ Azure Artifacts source and NuGet.org,
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -45,7 +45,7 @@ exports[`authutil tests existing config w/ GPR source and NuGet.org, sets up a p
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -63,7 +63,7 @@ exports[`authutil tests existing config w/ no GPR sources, sets up a full NuGet.
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -81,7 +81,7 @@ exports[`authutil tests existing config w/ no sources, sets up a full NuGet.conf
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -96,7 +96,7 @@ exports[`authutil tests existing config w/ only Azure Artifacts source, sets up
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -111,7 +111,7 @@ exports[`authutil tests existing config w/ only GPR source, sets up a partial Nu
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -130,7 +130,7 @@ exports[`authutil tests existing config w/ two GPR sources, sets up a partial Nu
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -148,7 +148,7 @@ exports[`authutil tests no existing config, sets up a full NuGet.config with URL
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@@ -166,7 +166,7 @@ exports[`authutil tests no existing config, sets up a full NuGet.config with URL
|
|||||||
</configuration>"
|
</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\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
|
|||||||
@@ -1,336 +1,340 @@
|
|||||||
import * as io from '@actions/io';
|
import io = require('@actions/io');
|
||||||
import fs from 'fs';
|
import fs = require('fs');
|
||||||
import path from 'path';
|
import path = require('path');
|
||||||
|
|
||||||
const fakeSourcesDirForTesting = path.join(
|
const fakeSourcesDirForTesting = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
'runner',
|
'runner',
|
||||||
path.join(Math.random().toString(36).substring(7)),
|
path.join(
|
||||||
's'
|
Math.random()
|
||||||
);
|
.toString(36)
|
||||||
|
.substring(7)
|
||||||
const invalidNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>`;
|
),
|
||||||
|
's'
|
||||||
const emptyNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
);
|
||||||
<configuration>
|
|
||||||
</configuration>`;
|
const invalidNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>`;
|
||||||
|
|
||||||
const nugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
const emptyNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
|
||||||
</packageSources>
|
const nugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</configuration>`;
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
const gprnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<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" />
|
const gprnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</packageSources>
|
<configuration>
|
||||||
</configuration>`;
|
<packageSources>
|
||||||
|
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
const gprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
|
||||||
</packageSources>
|
const gprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</configuration>`;
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
const twogprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<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" />
|
const twogprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</packageSources>
|
<configuration>
|
||||||
</configuration>`;
|
<packageSources>
|
||||||
|
<add key="GPR-GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
const spaceNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="GPR-Actions" value="https://nuget.pkg.github.com/actions/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
|
||||||
</packageSources>
|
const spaceNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</configuration>`;
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
const azureartifactsNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
|
||||||
</packageSources>
|
const azureartifactsNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</configuration>`;
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
const azureartifactsnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||||
<configuration>
|
</packageSources>
|
||||||
<packageSources>
|
</configuration>`;
|
||||||
<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" />
|
const azureartifactsnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
</packageSources>
|
<configuration>
|
||||||
</configuration>`;
|
<packageSources>
|
||||||
|
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||||
// 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.
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
</packageSources>
|
||||||
|
</configuration>`;
|
||||||
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
|
||||||
import * as auth from '../src/authutil';
|
// 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');
|
||||||
describe('authutil tests', () => {
|
|
||||||
beforeEach(async () => {
|
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
||||||
await io.rmRF(fakeSourcesDirForTesting);
|
import * as auth from '../src/authutil';
|
||||||
await io.mkdirP(fakeSourcesDirForTesting);
|
|
||||||
}, 30000);
|
describe('authutil tests', () => {
|
||||||
|
beforeEach(async () => {
|
||||||
afterAll(async () => {
|
await io.rmRF(fakeSourcesDirForTesting);
|
||||||
await io.rmRF(fakeSourcesDirForTesting);
|
await io.mkdirP(fakeSourcesDirForTesting);
|
||||||
}, 30000);
|
}, 30000);
|
||||||
|
|
||||||
beforeEach(() => {
|
afterAll(async () => {
|
||||||
if (fs.existsSync(nugetConfigFile)) {
|
await io.rmRF(fakeSourcesDirForTesting);
|
||||||
fs.unlinkSync(nugetConfigFile);
|
}, 30000);
|
||||||
}
|
|
||||||
process.env['INPUT_OWNER'] = '';
|
beforeEach(() => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = '';
|
if (fs.existsSync(nugetConfigFile)) {
|
||||||
});
|
fs.unlinkSync(nugetConfigFile);
|
||||||
|
}
|
||||||
it('no existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
process.env['INPUT_OWNER'] = '';
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = '';
|
||||||
auth.configAuthentication(
|
});
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
|
||||||
'',
|
it('No existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||||
fakeSourcesDirForTesting
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('no existing config, auth token environment variable not provided, throws', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
let thrown = false;
|
).toMatchSnapshot();
|
||||||
try {
|
});
|
||||||
auth.configAuthentication(
|
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
it('No existing config, auth token environment variable not provided, throws', async () => {
|
||||||
'',
|
let thrown = false;
|
||||||
fakeSourcesDirForTesting
|
try {
|
||||||
);
|
await auth.configAuthentication(
|
||||||
} catch {
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
thrown = true;
|
'',
|
||||||
}
|
fakeSourcesDirForTesting
|
||||||
expect(thrown).toBe(true);
|
);
|
||||||
});
|
} catch {
|
||||||
|
thrown = 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';
|
expect(thrown).toBe(true);
|
||||||
process.env['INPUT_OWNER'] = 'otherorg';
|
});
|
||||||
auth.configAuthentication(
|
|
||||||
'https://nuget.pkg.github.com/otherorg/index.json',
|
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';
|
||||||
fakeSourcesDirForTesting
|
process.env['INPUT_OWNER'] = 'otherorg';
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
it('Existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
||||||
);
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
let thrown = false;
|
fakeSourcesDirForTesting,
|
||||||
try {
|
'nuget.config'
|
||||||
auth.configAuthentication(
|
);
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
||||||
'',
|
let thrown = false;
|
||||||
fakeSourcesDirForTesting
|
try {
|
||||||
);
|
await auth.configAuthentication(
|
||||||
} catch {
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
thrown = true;
|
'',
|
||||||
}
|
fakeSourcesDirForTesting
|
||||||
expect(thrown).toBe(true);
|
);
|
||||||
});
|
} catch {
|
||||||
|
thrown = 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';
|
expect(thrown).toBe(true);
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://nuget.pkg.github.com',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ spaces in key, throws for now', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
it('Existing config w/ spaces in key, throws for now', async () => {
|
||||||
);
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
let thrown = false;
|
fakeSourcesDirForTesting,
|
||||||
try {
|
'nuget.config'
|
||||||
auth.configAuthentication(
|
);
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
||||||
'',
|
let thrown = false;
|
||||||
fakeSourcesDirForTesting
|
try {
|
||||||
);
|
await auth.configAuthentication(
|
||||||
} catch {
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
thrown = true;
|
'',
|
||||||
}
|
fakeSourcesDirForTesting
|
||||||
expect(thrown).toBe(true);
|
);
|
||||||
});
|
} catch {
|
||||||
|
thrown = 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';
|
expect(thrown).toBe(true);
|
||||||
const inputNuGetConfigDirectory: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'subfolder'
|
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 inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigDirectory: string = path.join(
|
||||||
inputNuGetConfigDirectory,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'subfolder'
|
||||||
);
|
);
|
||||||
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
inputNuGetConfigDirectory,
|
||||||
auth.configAuthentication(
|
'nuget.config'
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
);
|
||||||
'subfolder/nuget.config',
|
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
expect(
|
'subfolder/nuget.config',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
const inputNuGetConfigPath: string = path.join(
|
});
|
||||||
fakeSourcesDirForTesting,
|
|
||||||
'nuget.config'
|
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';
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
const inputNuGetConfigPath: string = path.join(
|
||||||
auth.configAuthentication(
|
fakeSourcesDirForTesting,
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
'nuget.config'
|
||||||
'',
|
);
|
||||||
fakeSourcesDirForTesting
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
|
expect(
|
||||||
it('no existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
).toMatchSnapshot();
|
||||||
auth.configAuthentication(
|
});
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
|
||||||
'',
|
it('No existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
||||||
fakeSourcesDirForTesting
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
);
|
await auth.configAuthentication(
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
expect(
|
'',
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fakeSourcesDirForTesting
|
||||||
).toMatchSnapshot();
|
);
|
||||||
});
|
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,23 @@
|
|||||||
import cscFile from '../.github/csc.json';
|
import fs = require('fs');
|
||||||
|
|
||||||
describe('csc tests', () => {
|
describe('csc tests', () => {
|
||||||
test('regular expression in csc.json is valid', async () => {
|
it('Valid regular expression', async () => {
|
||||||
const regexPattern = cscFile['problemMatcher'][0]['pattern'][0]['regexp'];
|
var cscFile = require('../.github/csc.json');
|
||||||
const regexResultsMap = cscFile['problemMatcher'][0]['pattern'][0];
|
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]',
|
'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]"
|
"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) => {
|
stringsToMatch.forEach(string => {
|
||||||
const matchedResultsArray = string.match(regex);
|
var matchStr = string.match(re);
|
||||||
for (const propName in expectedResults[index]) {
|
console.log(matchStr);
|
||||||
const propertyIndex = regexResultsMap[propName];
|
expect(matchStr).toEqual(expect.anything());
|
||||||
const expectedPropValue = expectedResults[index][propName];
|
|
||||||
const matchedPropValue = matchedResultsArray![propertyIndex];
|
|
||||||
expect(matchedPropValue).toEqual(expectedPropValue);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}, 10000);
|
}, 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,151 @@
|
|||||||
import each from 'jest-each';
|
import io = require('@actions/io');
|
||||||
import semver from 'semver';
|
import fs = require('fs');
|
||||||
import fs from 'fs';
|
import os = require('os');
|
||||||
import fspromises from 'fs/promises';
|
import path = require('path');
|
||||||
import * as exec from '@actions/exec';
|
import hc = require('@actions/http-client');
|
||||||
import * as core from '@actions/core';
|
|
||||||
import * as io from '@actions/io';
|
const toolDir = path.join(__dirname, 'runner', 'tools');
|
||||||
|
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||||
|
|
||||||
|
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||||
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
import * as installer from '../src/installer';
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
import {IS_WINDOWS} from '../src/utils';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
import {QualityOptions} from '../src/setup-dotnet';
|
|
||||||
|
|
||||||
describe('installer tests', () => {
|
describe('installer tests', () => {
|
||||||
const env = process.env;
|
beforeAll(async () => {
|
||||||
|
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||||
beforeEach(() => {
|
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||||
jest.resetModules();
|
process.env.RUNNER_TEMP = tempDir;
|
||||||
process.env = {...env};
|
process.env.DOTNET_ROOT = '';
|
||||||
|
await io.rmRF(toolDir);
|
||||||
|
await io.rmRF(tempDir);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DotnetCoreInstaller tests', () => {
|
afterAll(async () => {
|
||||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
try {
|
||||||
const warningSpy = jest.spyOn(core, 'warning');
|
await io.rmRF(toolDir);
|
||||||
const whichSpy = jest.spyOn(io, 'which');
|
await io.rmRF(tempDir);
|
||||||
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
} catch {
|
||||||
const chmodSyncSpy = jest.spyOn(fs, 'chmodSync');
|
console.log('Failed to remove test directories');
|
||||||
const readdirSpy = jest.spyOn(fspromises, 'readdir');
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
describe('installDotnet() tests', () => {
|
it('Aquires multiple versions of dotnet', async () => {
|
||||||
beforeAll(() => {
|
const versions = ['2.2.207', '3.1.120'];
|
||||||
whichSpy.mockImplementation(() => Promise.resolve('PathToShell'));
|
|
||||||
chmodSyncSpy.mockImplementation(() => {});
|
|
||||||
readdirSpy.mockImplementation(() => Promise.resolve([]));
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(() => {
|
for (const version of versions) {
|
||||||
jest.resetAllMocks();
|
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 throw the error in case of non-zero exit code of the installation script. The error message should contain logs.', async () => {
|
if (IS_WINDOWS) {
|
||||||
const inputVersion = '3.1.100';
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
const inputQuality = '' as QualityOptions;
|
} else {
|
||||||
const errorMessage = 'fictitious error message!';
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
|
}
|
||||||
|
|
||||||
getExecOutputSpy.mockImplementation(() => {
|
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||||
return Promise.resolve({
|
expect(process.env.PATH).toBeDefined;
|
||||||
exitCode: 1,
|
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||||
stdout: '',
|
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||||
stderr: errorMessage
|
}, 600000);
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
it('Acquires version of dotnet if no matching version is installed', async () => {
|
||||||
inputVersion,
|
await getDotnet('3.1.201');
|
||||||
inputQuality
|
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
||||||
);
|
if (IS_WINDOWS) {
|
||||||
await expect(dotnetInstaller.installDotnet()).rejects.toThrow(
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
`Failed to install dotnet, exit code: 1. ${errorMessage}`
|
} else {
|
||||||
);
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
});
|
}
|
||||||
|
|
||||||
it('should return version of .NET SDK after installation complete', async () => {
|
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||||
const inputVersion = '3.1.100';
|
expect(process.env.PATH).toBeDefined;
|
||||||
const inputQuality = '' as QualityOptions;
|
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||||
getExecOutputSpy.mockImplementation(() => {
|
}, 600000); //This needs some time to download on "slower" internet connections
|
||||||
return Promise.resolve({
|
|
||||||
exitCode: 0,
|
|
||||||
stdout: `${stdout}`,
|
|
||||||
stderr: ''
|
|
||||||
});
|
|
||||||
});
|
|
||||||
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
|
||||||
|
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
it('Acquires generic version of dotnet if no matching version is installed', async () => {
|
||||||
inputVersion,
|
await getDotnet('3.1');
|
||||||
inputQuality
|
var directory = fs
|
||||||
);
|
.readdirSync(path.join(toolDir, 'sdk'))
|
||||||
const installedVersion = await dotnetInstaller.installDotnet();
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
expect(installedVersion).toBe(inputVersion);
|
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
|
||||||
|
|
||||||
it(`should supply 'version' argument to the installation script if supplied version is in A.B.C syntax`, async () => {
|
it('Throws if no location contains correct dotnet version', async () => {
|
||||||
const inputVersion = '6.0.300';
|
let thrown = false;
|
||||||
const inputQuality = '' as QualityOptions;
|
try {
|
||||||
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
await getDotnet('1000.0.0');
|
||||||
|
} catch {
|
||||||
|
thrown = true;
|
||||||
|
}
|
||||||
|
expect(thrown).toBe(true);
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
getExecOutputSpy.mockImplementation(() => {
|
it('Uses an up to date bash download script', async () => {
|
||||||
return Promise.resolve({
|
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||||
exitCode: 0,
|
allowRetries: true,
|
||||||
stdout: `${stdout}`,
|
maxRetries: 3
|
||||||
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
|
|
||||||
? `-Version ${inputVersion}`
|
|
||||||
: `--version ${inputVersion}`;
|
|
||||||
|
|
||||||
expect(scriptArguments).toContain(expectedArgument);
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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.`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
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`;
|
|
||||||
|
|
||||||
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(['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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
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']}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
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);
|
||||||
|
|
||||||
describe('addToPath() tests', () => {
|
it('Uses an up to date powershell download script', async () => {
|
||||||
it(`should export DOTNET_ROOT env.var with value from DOTNET_INSTALL_DIR env.var`, async () => {
|
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||||
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
|
allowRetries: true,
|
||||||
installer.DotnetCoreInstaller.addToPath();
|
maxRetries: 3
|
||||||
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']);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||||
|
'https://dot.net/v1/dotnet-install.ps1'
|
||||||
describe('DotnetVersionResolver tests', () => {
|
);
|
||||||
describe('createDotNetVersion() tests', () => {
|
expect(response.message.statusCode).toBe(200);
|
||||||
each([
|
const upToDateContents: string = await response.readBody();
|
||||||
'3.1',
|
const currentContents: string = fs
|
||||||
'3.x',
|
.readFileSync(
|
||||||
'3.1.x',
|
path.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||||
'3.1.*',
|
)
|
||||||
'3.1.X',
|
.toString();
|
||||||
'3.1.2',
|
expect(normalizeFileContents(currentContents)).toBe(
|
||||||
'3.1.0-preview1',
|
normalizeFileContents(upToDateContents)
|
||||||
'6.0.2xx'
|
);
|
||||||
]).test(
|
}, 30000);
|
||||||
'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): Promise<void> {
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
installer.DotnetCoreInstaller.addToPath();
|
||||||
|
}
|
||||||
|
|||||||
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,71 @@
|
|||||||
import * as core from '@actions/core';
|
import io = require('@actions/io');
|
||||||
import fs from 'fs';
|
import fs = require('fs');
|
||||||
import semver from 'semver';
|
import os = require('os');
|
||||||
import * as auth from '../src/authutil';
|
import path = require('path');
|
||||||
|
|
||||||
|
const toolDir = path.join(__dirname, 'runner', 'tools2');
|
||||||
|
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||||
|
|
||||||
import * as setup from '../src/setup-dotnet';
|
import * as setup from '../src/setup-dotnet';
|
||||||
import {DotnetCoreInstaller} from '../src/installer';
|
import * as dotnetInstaller from '../src/installer';
|
||||||
import * as cacheUtils from '../src/cache-utils';
|
|
||||||
import * as cacheRestore from '../src/cache-restore';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
describe('setup-dotnet tests', () => {
|
describe('setup-dotnet tests', () => {
|
||||||
const inputs = {} as any;
|
beforeAll(async () => {
|
||||||
|
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||||
const getInputSpy = jest.spyOn(core, 'getInput');
|
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||||
const getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
|
process.env.RUNNER_TEMP = tempDir;
|
||||||
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
process.env['INPUT_INCLUDE-PRERELEASE'] = 'false';
|
||||||
const setFailedSpy = jest.spyOn(core, 'setFailed');
|
await io.rmRF(toolDir);
|
||||||
const warningSpy = jest.spyOn(core, 'warning');
|
await io.rmRF(tempDir);
|
||||||
const debugSpy = jest.spyOn(core, 'debug');
|
|
||||||
const infoSpy = jest.spyOn(core, 'info');
|
|
||||||
const setOutputSpy = jest.spyOn(core, 'setOutput');
|
|
||||||
|
|
||||||
const existsSyncSpy = jest.spyOn(fs, 'existsSync');
|
|
||||||
|
|
||||||
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
|
||||||
|
|
||||||
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');
|
|
||||||
|
|
||||||
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]);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jest.clearAllMocks();
|
|
||||||
jest.resetAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
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'] = [];
|
|
||||||
|
|
||||||
const expectedErrorMessage = `The specified global.json file '${inputs['global-json-file']}' does not exist`;
|
|
||||||
|
|
||||||
await setup.run();
|
|
||||||
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
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'] = [];
|
|
||||||
|
|
||||||
maxSatisfyingSpy.mockImplementation(() => null);
|
|
||||||
setOutputSpy.mockImplementation(() => {});
|
|
||||||
|
|
||||||
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.`;
|
|
||||||
|
|
||||||
await setup.run();
|
|
||||||
|
|
||||||
expect(debugSpy).toHaveBeenCalledWith(expectedDebugMessage);
|
|
||||||
expect(existsSyncSpy).toHaveBeenCalled();
|
|
||||||
expect(infoSpy).toHaveBeenCalledWith(expectedInfoMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
try {
|
||||||
|
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
||||||
|
await io.rmRF(toolDir);
|
||||||
|
await io.rmRF(tempDir);
|
||||||
|
} catch {
|
||||||
|
console.log('Failed to remove test directories');
|
||||||
|
}
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
|
it('Acquires version of dotnet 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();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
it('Acquires version of dotnet from global.json with rollForward option, install the latest patch', async () => {
|
||||||
|
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||||
|
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version":"3.1.201",${os.EOL}"rollForward":"latestFeature"${os.EOL}}${os.EOL}}`;
|
||||||
|
if (!fs.existsSync(globalJsonPath)) {
|
||||||
|
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = '3.1';
|
||||||
|
const installer = new dotnetInstaller.DotnetCoreInstaller(version);
|
||||||
|
const patchVersion = await installer.resolveVersion(
|
||||||
|
new dotnetInstaller.DotNetVersionInfo(version)
|
||||||
|
);
|
||||||
|
await setup.run();
|
||||||
|
|
||||||
|
expect(fs.existsSync(path.join(toolDir, 'sdk', patchVersion))).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);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,117 +1,73 @@
|
|||||||
<#
|
if (!$args[0])
|
||||||
.DESCRIPTION
|
{
|
||||||
Verifies that installed on the machine .NET SDK versions match the input patterns.
|
throw "Must supply dotnet version argument"
|
||||||
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."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "These patterns were supplied to the script: $($PatternsList -join ', ')."
|
|
||||||
$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path }
|
$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
|
if($args.count -eq 1)
|
||||||
$Versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
|
||||||
Write-Host "Found installed versions: $($Versions -join ', ')."
|
|
||||||
$InstalledVersionCount = $Versions.Count
|
|
||||||
|
|
||||||
foreach($version in $Versions)
|
|
||||||
{
|
{
|
||||||
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)
|
Write-Host "PATH='$env:PATH'"
|
||||||
{
|
throw "Unexpected version"
|
||||||
$PatternsList.Remove($pattern)
|
}
|
||||||
$InstalledVersionCount--
|
}
|
||||||
break
|
|
||||||
|
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
|
Write-Host "Testing compiled app"
|
||||||
$testProjectDir = "./__tests__/e2e-test-csproj"
|
$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
|
||||||
Write-Host "Changing directory to the $testProjectDir"
|
Write-Host "Sample output: $sample_output"
|
||||||
Set-Location $testProjectDir
|
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
||||||
|
if ($args[1])
|
||||||
$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)
|
|
||||||
{
|
{
|
||||||
# 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.
|
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
|
||||||
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"))
|
|
||||||
{
|
{
|
||||||
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
|
||||||
17
__tests__/verify-no-unstaged-changes.sh
Executable file
17
__tests__/verify-no-unstaged-changes.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if [[ "$(git status --porcelain)" != "" ]]; then
|
||||||
|
echo ----------------------------------------
|
||||||
|
echo git status
|
||||||
|
echo ----------------------------------------
|
||||||
|
git status
|
||||||
|
echo ----------------------------------------
|
||||||
|
echo git diff
|
||||||
|
echo ----------------------------------------
|
||||||
|
git diff
|
||||||
|
echo ----------------------------------------
|
||||||
|
echo Troubleshooting
|
||||||
|
echo ----------------------------------------
|
||||||
|
echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && npm ci && npm run pre-checkin"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
91
__tests__/versionutil.test.ts
Normal file
91
__tests__/versionutil.test.ts
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import each from 'jest-each';
|
||||||
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
|
describe('version tests', () => {
|
||||||
|
each(['3.1.999', '3.1.101-preview.3']).test(
|
||||||
|
"Exact version '%s' should be the same",
|
||||||
|
vers => {
|
||||||
|
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||||
|
|
||||||
|
expect(versInfo.isExactVersion()).toBe(true);
|
||||||
|
expect(versInfo.version()).toBe(vers);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each([
|
||||||
|
['3.x', '3.x'],
|
||||||
|
['3.*', '3.*'],
|
||||||
|
['3.1.x', '3.1'],
|
||||||
|
['1.1.*', '1.1'],
|
||||||
|
['2.0', '2.0']
|
||||||
|
]).test("Generic version '%s' should be '%s'", (vers, resVers) => {
|
||||||
|
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||||
|
|
||||||
|
expect(versInfo.isExactVersion()).toBe(false);
|
||||||
|
expect(versInfo.version()).toBe(resVers);
|
||||||
|
});
|
||||||
|
|
||||||
|
each([
|
||||||
|
'',
|
||||||
|
'.',
|
||||||
|
'..',
|
||||||
|
' . ',
|
||||||
|
'. ',
|
||||||
|
' .',
|
||||||
|
' . . ',
|
||||||
|
' .. ',
|
||||||
|
' . ',
|
||||||
|
'-1.-1',
|
||||||
|
'-1',
|
||||||
|
'-1.-1.-1',
|
||||||
|
'..3',
|
||||||
|
'1..3',
|
||||||
|
'1..',
|
||||||
|
'.2.3',
|
||||||
|
'.2.x',
|
||||||
|
'1',
|
||||||
|
'*.*.1',
|
||||||
|
'*.1',
|
||||||
|
'*.',
|
||||||
|
'1.2.',
|
||||||
|
'1.2.-abc',
|
||||||
|
'a.b',
|
||||||
|
'a.b.c',
|
||||||
|
'a.b.c-preview',
|
||||||
|
' 0 . 1 . 2 '
|
||||||
|
]).test("Malformed version '%s' should throw", vers => {
|
||||||
|
expect(() => new installer.DotNetVersionInfo(vers)).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
each([
|
||||||
|
['3.1.x', '3.1.'],
|
||||||
|
['3.1.*', '3.1.'],
|
||||||
|
['3.1', '3.1.'],
|
||||||
|
['5.0.0-preview.6', '5.0.0-preview.6'],
|
||||||
|
['3.1.201', '3.1.201']
|
||||||
|
]).test(
|
||||||
|
"Resolving version '%s' as '%s'",
|
||||||
|
async (input, expectedVersion) => {
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(input);
|
||||||
|
let versInfo = await dotnetInstaller.resolveVersion(
|
||||||
|
new installer.DotNetVersionInfo(input)
|
||||||
|
);
|
||||||
|
console.log(versInfo);
|
||||||
|
|
||||||
|
expect(versInfo.startsWith(expectedVersion));
|
||||||
|
},
|
||||||
|
100000
|
||||||
|
);
|
||||||
|
|
||||||
|
it('Resolving a nonexistent generic version fails', async () => {
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
|
||||||
|
try {
|
||||||
|
await dotnetInstaller.resolveVersion(
|
||||||
|
new installer.DotNetVersionInfo('999.1.x')
|
||||||
|
);
|
||||||
|
fail();
|
||||||
|
} catch {
|
||||||
|
expect(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user