You've already forked setup-dotnet
mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-07-10 00:50:33 +07:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
45c9f236cf | |||
c7e7147fd3 | |||
0705ef0281 | |||
a351d9ea84 | |||
857c316a9d | |||
bba8299c35 | |||
fd4e15fa44 | |||
95e7de77d1 | |||
52c3199a78 | |||
2d9def7067 | |||
df51eabf53 | |||
e4b2fcaa19 | |||
d45c10e6f7 | |||
4d1b6c2c63 | |||
4cb4764ae2 | |||
d33e605efe | |||
f7747565a1 | |||
2f75d1de25 | |||
e6a9a96293 | |||
025aba53b2 | |||
37b00c4fc5 | |||
c2dac7f367 | |||
c5267f5e54 | |||
ba5e53c61d | |||
043fb8900f | |||
cb04ff8cb3 | |||
bac4044d91 | |||
d26ead4cf0 | |||
e81cd4d454 | |||
ee11c4faa4 | |||
8bf1fb6084 | |||
c0d4ad69d8 | |||
afe2daba1f | |||
fb09b12527 | |||
5cc895510b | |||
158737d5b1 | |||
fcf565ec50 | |||
f078482971 | |||
0fb87b12d2 | |||
4fe7a196b5 | |||
9283a8cf7a | |||
53d632b5c0 | |||
9211491ffb | |||
edfd7b3266 | |||
9744af7b74 | |||
7016f85f93 | |||
d292011f5d |
13
.github/workflows/check-dist.yml
vendored
13
.github/workflows/check-dist.yml
vendored
@ -21,15 +21,16 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
- name: Set Node.js 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
node-version: 16.x
|
||||
cache: npm
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
run: npm ci --ignore-scripts
|
||||
|
||||
- name: Rebuild the dist/ directory
|
||||
run: npm run build
|
||||
@ -44,7 +45,7 @@ jobs:
|
||||
id: diff
|
||||
|
||||
# If index.js was different than expected, upload the expected version as an artifact
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||
with:
|
||||
name: dist
|
||||
|
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
# 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:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ main ]
|
||||
schedule:
|
||||
- cron: '23 19 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
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
|
6
.github/workflows/licensed.yml
vendored
6
.github/workflows/licensed.yml
vendored
@ -14,12 +14,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check licenses
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci
|
||||
- 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.3.1/licensed-3.3.1-linux-x64.tar.gz
|
||||
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
|
||||
|
@ -22,7 +22,7 @@ jobs:
|
||||
steps:
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
id: update-major-tag
|
||||
uses: actions/publish-action@v0.1.0
|
||||
uses: actions/publish-action@v0.2.0
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||
|
4
.github/workflows/test-dotnet.yml
vendored
4
.github/workflows/test-dotnet.yml
vendored
@ -17,11 +17,11 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0']
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
198
.github/workflows/workflow.yml
vendored
198
.github/workflows/workflow.yml
vendored
@ -17,31 +17,32 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-13]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Set Node.js 12
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/checkout@v3
|
||||
- name: Set Node.js 16
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 12.x
|
||||
- run: npm ci
|
||||
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]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
@ -49,9 +50,9 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: |
|
||||
2.2.402
|
||||
3.1.404
|
||||
3.0.x
|
||||
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'
|
||||
@ -61,10 +62,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macos-13]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
@ -77,7 +78,7 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.201
|
||||
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place
|
||||
# We are including this 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
|
||||
@ -94,10 +95,10 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
@ -113,16 +114,40 @@ jobs:
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
|
||||
test-setup-prerelease-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet '2.2'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '2.2'
|
||||
- name: Setup dotnet '3.1.100-preview1-014459'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '3.1.100-preview1-014459'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1.100-preview1-014459
|
||||
|
||||
test-setup-latest-patch-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
@ -130,23 +155,23 @@ jobs:
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
- name: Setup dotnet 2.2.x
|
||||
- name: Setup dotnet 2.2.X
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 2.2.x
|
||||
dotnet-version: 2.2.X
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
run: __tests__/verify-dotnet.ps1 '2.2' '3.1'
|
||||
|
||||
test-setup-with-wildcard:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-22.04, windows-latest, macOS-latest]
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
@ -162,30 +187,133 @@ jobs:
|
||||
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-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: 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-setup-with-dotnet-quality:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 7.0 with preview quality
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: "7.0"
|
||||
dotnet-quality: "preview"
|
||||
- name: Verify preview version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" }
|
||||
|
||||
test-dotnet-version-output-during-single-version-installation:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.401
|
||||
uses: ./
|
||||
id: step1
|
||||
with:
|
||||
dotnet-version: "6.0.401"
|
||||
|
||||
- name: Verify value of the dotnet-version output
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
|
||||
|
||||
test-dotnet-version-output-during-multiple-version-installation:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
|
||||
- name: Setup dotnet 6.0.401, 5.0.408, 7.0.100-rc.1.22431.12
|
||||
uses: ./
|
||||
id: step2
|
||||
with:
|
||||
dotnet-version: |
|
||||
7.0.100-rc.1.22431.12
|
||||
6.0.401
|
||||
5.0.408
|
||||
|
||||
- name: 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-20.04
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ubuntu:20.04
|
||||
image: mcr.microsoft.com/dotnet/core/runtime-deps:3.0-bionic
|
||||
options: --dns 127.0.0.1
|
||||
services:
|
||||
squid-proxy:
|
||||
image: ubuntu/squid:latest
|
||||
image: datadog/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@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear tool cache
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Install curl
|
||||
run: |
|
||||
apt update
|
||||
apt -y install curl libssl-dev
|
||||
apt -y install curl
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
@ -197,13 +325,13 @@ jobs:
|
||||
run: __tests__/verify-dotnet.sh 3.1.201
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
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
|
||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Clear tool cache
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Setup dotnet 3.1.201
|
||||
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npm run format
|
5
.husky/pre-push
Executable file
5
.husky/pre-push
Executable file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
# Tests are not run at push time since they can take 2-4 minutes to complete
|
||||
npm run format-check
|
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: "@actions/core"
|
||||
version: 1.6.0
|
||||
version: 1.9.1
|
||||
type: npm
|
||||
summary: Actions core lib
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/core
|
||||
|
30
.licenses/npm/@actions/exec.dep.yml
generated
30
.licenses/npm/@actions/exec.dep.yml
generated
@ -1,30 +1,20 @@
|
||||
---
|
||||
name: "@actions/exec"
|
||||
version: 1.0.4
|
||||
version: 1.1.1
|
||||
type: npm
|
||||
summary: Actions exec lib
|
||||
homepage: https://github.com/actions/toolkit/tree/master/packages/exec
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/exec
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: Auto-generated MIT license text
|
||||
text: |
|
||||
MIT License
|
||||
- sources: LICENSE.md
|
||||
text: |-
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Copyright 2019 GitHub
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
notices: []
|
||||
|
32
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
32
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
@ -1,32 +0,0 @@
|
||||
---
|
||||
name: "@actions/http-client"
|
||||
version: 1.0.8
|
||||
type: npm
|
||||
summary: Actions Http Client
|
||||
homepage: https://github.com/actions/http-client#readme
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
||||
text: |
|
||||
Actions Http Client for Node.js
|
||||
|
||||
Copyright (c) GitHub, Inc.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
notices: []
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
name: "@actions/http-client"
|
||||
version: 1.0.11
|
||||
version: 2.0.1
|
||||
type: npm
|
||||
summary: Actions Http Client
|
||||
homepage: https://github.com/actions/http-client#readme
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE
|
30
.licenses/npm/@actions/io.dep.yml
generated
30
.licenses/npm/@actions/io.dep.yml
generated
@ -1,30 +1,20 @@
|
||||
---
|
||||
name: "@actions/io"
|
||||
version: 1.0.2
|
||||
version: 1.1.2
|
||||
type: npm
|
||||
summary: Actions io lib
|
||||
homepage: https://github.com/actions/toolkit/tree/master/packages/io
|
||||
homepage: https://github.com/actions/toolkit/tree/main/packages/io
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: Auto-generated MIT license text
|
||||
text: |
|
||||
MIT License
|
||||
- sources: LICENSE.md
|
||||
text: |-
|
||||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Copyright 2019 GitHub
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
notices: []
|
||||
|
2
.licenses/npm/node-fetch.dep.yml
generated
2
.licenses/npm/node-fetch.dep.yml
generated
@ -1,6 +1,6 @@
|
||||
---
|
||||
name: node-fetch
|
||||
version: 2.6.1
|
||||
version: 2.6.7
|
||||
type: npm
|
||||
summary: A light-weight module that brings window.fetch to node.js
|
||||
homepage: https://github.com/bitinn/node-fetch
|
||||
|
30
.licenses/npm/tr46.dep.yml
generated
Normal file
30
.licenses/npm/tr46.dep.yml
generated
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
name: tr46
|
||||
version: 0.0.3
|
||||
type: npm
|
||||
summary: An implementation of the Unicode TR46 spec
|
||||
homepage: https://github.com/Sebmaster/tr46.js#readme
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: Auto-generated MIT license text
|
||||
text: |
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
notices: []
|
20
.licenses/npm/uuid.dep.yml
generated
Normal file
20
.licenses/npm/uuid.dep.yml
generated
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: uuid
|
||||
version: 8.3.2
|
||||
type: npm
|
||||
summary: RFC4122 (v1, v4, and v5) UUIDs
|
||||
homepage:
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE.md
|
||||
text: |
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2010-2020 Robert Kieffer and other contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
notices: []
|
23
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
23
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
name: webidl-conversions
|
||||
version: 3.0.1
|
||||
type: npm
|
||||
summary: Implements the WebIDL algorithms for converting to and from JavaScript values
|
||||
homepage:
|
||||
license: bsd-2-clause
|
||||
licenses:
|
||||
- sources: LICENSE.md
|
||||
text: |
|
||||
# The BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2014, Domenic Denicola
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
notices: []
|
32
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
32
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
name: whatwg-url
|
||||
version: 5.0.0
|
||||
type: npm
|
||||
summary: An implementation of the WHATWG URL Standard's URL API and parsing machinery
|
||||
homepage:
|
||||
license: mit
|
||||
licenses:
|
||||
- sources: LICENSE.txt
|
||||
text: |
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015–2016 Sebastian Mayr
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
notices: []
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at opensource+actions/setup-dotnet@github.com. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
191
README.md
191
README.md
@ -1,8 +1,6 @@
|
||||
# setup-dotnet
|
||||
|
||||
<p align="left">
|
||||
<a href="https://github.com/actions/setup-dotnet"><img alt="GitHub Actions status" src="https://github.com/actions/setup-dotnet/workflows/Main%20workflow/badge.svg"></a>
|
||||
</p>
|
||||
[](https://github.com/actions/setup-dotnet)
|
||||
|
||||
This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for use in actions by:
|
||||
|
||||
@ -10,52 +8,82 @@ This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for
|
||||
- registering problem matchers for error output
|
||||
- setting up authentication to private package sources like GitHub Packages
|
||||
|
||||
Please Note: GitHub hosted runners have some versions of the .NET SDK
|
||||
> **Note**: GitHub hosted runners have some versions of the .NET SDK
|
||||
preinstalled. Installed versions are subject to change. Please refer to the
|
||||
documentation
|
||||
[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.
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
See [action.yml](action.yml)
|
||||
|
||||
Basic:
|
||||
**Basic**:
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '3.1.x' # SDK Version to use; x will use the latest version of the 3.1 channel
|
||||
dotnet-version: '3.1.x'
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
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
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: |
|
||||
3.1.x
|
||||
5.0.x
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
Preview version:
|
||||
> **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.
|
||||
|
||||
## Supported version syntax
|
||||
|
||||
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)
|
||||
|
||||
|
||||
## 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' and 'A.x' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
|
||||
|
||||
```yml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
include-prerelease: true
|
||||
dotnet-quality: 'preview'
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
|
||||
Matrix Testing:
|
||||
```yaml
|
||||
## 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
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
global-json-file: csharp/global.json
|
||||
- run: dotnet build <my project>
|
||||
working-directory: csharp
|
||||
```
|
||||
|
||||
## 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:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
@ -64,42 +92,22 @@ jobs:
|
||||
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
|
||||
name: Dotnet ${{ matrix.dotnet }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet }}
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
## Setting up authentication for nuget feeds
|
||||
|
||||
Side by Side Testing:
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Dotnet Side by Side testing sample
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '2.1.x'
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.x'
|
||||
- run: dotnet build <my project>
|
||||
- run: dotnet test <my project>
|
||||
```
|
||||
|
||||
Authentication for nuget feeds:
|
||||
```yaml
|
||||
### Github Package Registry (GPR)
|
||||
```yml
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
# Authenticates packages to push to GPR
|
||||
- uses: actions/setup-dotnet@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '3.1.x' # SDK Version to use.
|
||||
dotnet-version: '3.1.x'
|
||||
source-url: https://nuget.pkg.github.com/<owner>/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
@ -108,19 +116,22 @@ steps:
|
||||
run: dotnet pack --configuration Release <my project>
|
||||
- name: Publish the package to GPR
|
||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||
```
|
||||
|
||||
# Authenticates packages to push to Azure Artifacts
|
||||
- uses: actions/setup-dotnet@v1
|
||||
### Azure Artifacts
|
||||
```yml
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
||||
- name: Publish the package to Azure Artifacts
|
||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||
```
|
||||
|
||||
# Authenticates packages to push to nuget.org.
|
||||
# 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@v1
|
||||
### nuget.org
|
||||
```yml
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
- name: Publish the package to nuget.org
|
||||
@ -128,32 +139,84 @@ steps:
|
||||
env:
|
||||
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.
|
||||
|
||||
## Environment Variables to use with dotnet
|
||||
# Outputs and environment variables
|
||||
|
||||
## 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: cp310
|
||||
with:
|
||||
dotnet-version: 3.1.422
|
||||
- run: echo '${{ steps.cp310.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: cp310
|
||||
with:
|
||||
dotnet-version: |
|
||||
3.1.422
|
||||
5.0.408
|
||||
- run: echo '${{ steps.cp310.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: cp310
|
||||
with:
|
||||
dotnet-version: |
|
||||
3.1.422
|
||||
5.0.408
|
||||
global-json-file: "./global.json" # contains version 2.2.207
|
||||
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 2.2.207
|
||||
```
|
||||
|
||||
## 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
|
||||
|
||||
- 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_MULTILEVEL_LOOKUP - configures whether the global install location is used as a fall-back (default: true)
|
||||
| **Env.variable** | **Description** | **Default value** |
|
||||
| ----------- | ----------- | ----------- |
|
||||
| DOTNET_INSTALL_DIR |Specifies a directory where .NET SDKs should be installed by the action|*isn't set*|
|
||||
| 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*|
|
||||
|
||||
Example usage:
|
||||
```yaml
|
||||
**Example usage**:
|
||||
```yml
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOTNET_NOLOGO: true
|
||||
DOTNET_INSTALL_DIR: "path/to/directory"
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- uses: actions/setup-dotnet@v1
|
||||
- uses: actions/setup-dotnet@v3
|
||||
with:
|
||||
dotnet-version: '3.1.x' # SDK Version to use.
|
||||
dotnet-version: '3.1.x'
|
||||
```
|
||||
|
||||
# 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 @@
|
||||
import io = require('@actions/io');
|
||||
import fs = require('fs');
|
||||
import path = require('path');
|
||||
import * as io from '@actions/io';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const fakeSourcesDirForTesting = path.join(
|
||||
__dirname,
|
||||
|
@ -1,5 +1,3 @@
|
||||
import fs = require('fs');
|
||||
|
||||
describe('csc tests', () => {
|
||||
it('Valid regular expression', async () => {
|
||||
var cscFile = require('../.github/csc.json');
|
||||
|
@ -1,34 +1,55 @@
|
||||
import io = require('@actions/io');
|
||||
import fs = require('fs');
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
import hc = require('@actions/http-client');
|
||||
import * as io from '@actions/io';
|
||||
import * as os from 'os';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import each from 'jest-each';
|
||||
import * as hc from '@actions/http-client';
|
||||
import * as installer from '../src/installer';
|
||||
import {QualityOptions} from '../src/setup-dotnet';
|
||||
|
||||
const toolDir = path.join(__dirname, 'runner', 'tools');
|
||||
import {IS_WINDOWS} from '../src/utils';
|
||||
import {IS_LINUX} from '../src/utils';
|
||||
|
||||
let toolDir: string;
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
|
||||
} else if (IS_LINUX) {
|
||||
toolDir = '/usr/share/dotnet';
|
||||
} else {
|
||||
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
|
||||
}
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||
|
||||
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||
process.env['RUNNER_TEMP'] = tempDir;
|
||||
import * as installer from '../src/installer';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
describe('installer tests', () => {
|
||||
describe('DotnetCoreInstaller tests', () => {
|
||||
beforeAll(async () => {
|
||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||
process.env.RUNNER_TEMP = tempDir;
|
||||
process.env.DOTNET_ROOT = '';
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
try {
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
} catch {
|
||||
console.log('Failed to remove test directories');
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Failed to remove test directories, check the error message:${os.EOL}`,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Failed to remove test directories, check the error message:${os.EOL}`,
|
||||
err.message
|
||||
);
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
@ -86,14 +107,19 @@ describe('installer tests', () => {
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
it('Returns string with installed SDK version', async () => {
|
||||
const version = '3.1.120';
|
||||
let installedVersion: string;
|
||||
|
||||
installedVersion = await getDotnet(version);
|
||||
|
||||
expect(installedVersion).toBe('3.1.120');
|
||||
}, 600000);
|
||||
|
||||
it('Throws if no location contains correct dotnet version', async () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
await expect(async () => {
|
||||
await getDotnet('1000.0.0');
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
}).rejects.toThrow();
|
||||
}, 30000);
|
||||
|
||||
it('Uses an up to date bash download script', async () => {
|
||||
@ -137,6 +163,112 @@ describe('installer tests', () => {
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
describe('DotnetVersionResolver tests', () => {
|
||||
each([
|
||||
'3.1',
|
||||
'3.x',
|
||||
'3.1.x',
|
||||
'3.1.*',
|
||||
'3.1.X',
|
||||
'3.1.2',
|
||||
'3.1.0-preview1'
|
||||
]).test(
|
||||
"if valid version: '%s' is supplied, it should return version object with some value",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(!!versionObject.value).toBeTruthy;
|
||||
}
|
||||
);
|
||||
|
||||
each([
|
||||
'.',
|
||||
'..',
|
||||
' . ',
|
||||
'. ',
|
||||
' .',
|
||||
' . . ',
|
||||
' .. ',
|
||||
' . ',
|
||||
'-1.-1',
|
||||
'-1',
|
||||
'-1.-1.-1',
|
||||
'..3',
|
||||
'1..3',
|
||||
'1..',
|
||||
'.2.3',
|
||||
'.2.x',
|
||||
'*.',
|
||||
'1.2.',
|
||||
'1.2.-abc',
|
||||
'a.b',
|
||||
'a.b.c',
|
||||
'a.b.c-preview',
|
||||
' 0 . 1 . 2 ',
|
||||
'invalid'
|
||||
]).test(
|
||||
"if invalid version: '%s' is supplied, it should throw",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
|
||||
await expect(
|
||||
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||
).rejects.toThrow();
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1', '3.1.x', '3.1.*', '3.1.X']).test(
|
||||
"if version: '%s' that can be resolved to 'channel' option is supplied, it should set quality flag to 'true' and type to 'channel' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('channel')).toBeTruthy;
|
||||
expect(versionObject.qualityFlag).toBeTruthy;
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1.0-preview1']).test(
|
||||
"if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object",
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
|
||||
expect(versionObject.type.toLowerCase().includes('version')).toBeTruthy;
|
||||
expect(versionObject.qualityFlag).toBeFalsy;
|
||||
}
|
||||
);
|
||||
|
||||
each(['3.1.2', '3.1']).test(
|
||||
'it should create proper line arguments for powershell/bash installation scripts',
|
||||
async version => {
|
||||
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||
version
|
||||
);
|
||||
const versionObject = await dotnetVersionResolver.createDotNetVersion();
|
||||
const windowsRegEx = new RegExp(/^-[VC]/);
|
||||
const nonWindowsRegEx = new RegExp(/^--[vc]/);
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
expect(windowsRegEx.test(versionObject.type)).toBeTruthy;
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBeFalsy;
|
||||
} else {
|
||||
expect(nonWindowsRegEx.test(versionObject.type)).toBeTruthy;
|
||||
expect(windowsRegEx.test(versionObject.type)).toBeFalsy;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function normalizeFileContents(contents: string): string {
|
||||
return contents
|
||||
.trim()
|
||||
@ -144,8 +276,15 @@ function normalizeFileContents(contents: string): string {
|
||||
.replace(new RegExp('\r', 'g'), '\n');
|
||||
}
|
||||
|
||||
async function getDotnet(version: string): Promise<void> {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
||||
await dotnetInstaller.installDotnet();
|
||||
async function getDotnet(
|
||||
version: string,
|
||||
quality: string = ''
|
||||
): Promise<string> {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
version,
|
||||
quality as QualityOptions
|
||||
);
|
||||
const installedVersion = await dotnetInstaller.installDotnet();
|
||||
installer.DotnetCoreInstaller.addToPath();
|
||||
return installedVersion;
|
||||
}
|
||||
|
@ -1,31 +1,52 @@
|
||||
import io = require('@actions/io');
|
||||
import fs = require('fs');
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
|
||||
const toolDir = path.join(__dirname, 'runner', 'tools2');
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||
import * as io from '@actions/io';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
|
||||
import * as setup from '../src/setup-dotnet';
|
||||
import * as dotnetInstaller from '../src/installer';
|
||||
import {IS_WINDOWS} from '../src/utils';
|
||||
import {IS_LINUX} from '../src/utils';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
let toolDir: string;
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
|
||||
} else if (IS_LINUX) {
|
||||
toolDir = '/usr/share/dotnet';
|
||||
} else {
|
||||
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
|
||||
}
|
||||
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||
|
||||
describe('setup-dotnet tests', () => {
|
||||
let getInputSpy = jest.spyOn(core, 'getInput');
|
||||
let getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
|
||||
let setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||
|
||||
let inputs = {} as any;
|
||||
|
||||
beforeAll(async () => {
|
||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||
process.env.RUNNER_TEMP = tempDir;
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
});
|
||||
try {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
} catch {
|
||||
await io.rmRF(`${toolDir}/*`);
|
||||
await io.rmRF(`${tempDir}/*`);
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 30000);
|
||||
@ -46,25 +67,32 @@ describe('setup-dotnet tests', () => {
|
||||
}
|
||||
}, 400000);
|
||||
|
||||
it('Acquires version of dotnet from global.json with rollForward option, install the latest patch', async () => {
|
||||
it("Sets output with the latest installed by action version if global.json file isn't specified", async () => {
|
||||
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
|
||||
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
await setup.run();
|
||||
|
||||
expect(setOutputSpy).toBeCalledWith('dotnet-version', '6.0.401');
|
||||
}, 400000);
|
||||
|
||||
it("Sets output with the version specified in global.json, if it's present", async () => {
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version":"3.1.201",${os.EOL}"rollForward":"latestFeature"${os.EOL}}${os.EOL}}`;
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.0.103"${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)
|
||||
);
|
||||
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
|
||||
inputs['global-json-file'] = './global.json';
|
||||
|
||||
getMultilineInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
getInputSpy.mockImplementation(input => inputs[input]);
|
||||
|
||||
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);
|
||||
}
|
||||
expect(setOutputSpy).toBeCalledWith('dotnet-version', '3.0.103');
|
||||
}, 400000);
|
||||
});
|
||||
|
@ -1,17 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ "$(git status --porcelain)" != "" ]]; then
|
||||
echo ----------------------------------------
|
||||
echo git status
|
||||
echo ----------------------------------------
|
||||
git status
|
||||
echo ----------------------------------------
|
||||
echo git diff
|
||||
echo ----------------------------------------
|
||||
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||
echo "Detected uncommitted changes after build. See status below:"
|
||||
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
|
||||
|
@ -1,91 +0,0 @@
|
||||
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);
|
||||
});
|
14
action.yml
14
action.yml
@ -6,16 +6,20 @@ branding:
|
||||
color: green
|
||||
inputs:
|
||||
dotnet-version:
|
||||
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x'
|
||||
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x, 3.x'
|
||||
dotnet-quality:
|
||||
description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.'
|
||||
global-json-file:
|
||||
description: 'Optional global.json location, if your global.json isn''t located in the root of the repo.'
|
||||
source-url:
|
||||
description: 'Optional package source for which to set up authentication. Will consult any existing NuGet.config in the root of the repo and provide a temporary NuGet.config using the NUGET_AUTH_TOKEN environment variable as a ClearTextPassword'
|
||||
owner:
|
||||
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
|
||||
config-file:
|
||||
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
|
||||
include-prerelease:
|
||||
description: 'Whether prerelease versions should be matched with non-exact versions (for example 5.0.0-preview.6 being matched by 5, 5.0, 5.x or 5.0.x). Defaults to false if not provided.'
|
||||
required: False
|
||||
outputs:
|
||||
dotnet-version:
|
||||
description: 'Contains the installed by action .NET SDK version for reuse.'
|
||||
runs:
|
||||
using: 'node12'
|
||||
using: 'node16'
|
||||
main: 'dist/index.js'
|
||||
|
34821
dist/index.js
vendored
34821
dist/index.js
vendored
File diff suppressed because one or more lines are too long
57
docs/adrs/v3-setup-dotnet.md
Normal file
57
docs/adrs/v3-setup-dotnet.md
Normal file
@ -0,0 +1,57 @@
|
||||
# v3 setup-dotnet
|
||||
|
||||
Date: 2022-08-25
|
||||
Status: Accepted
|
||||
|
||||
# Context
|
||||
- GitHub-hosted Ubuntu and Windows runners have .NET versions pre-installed in system directories
|
||||
- Ubuntu:`/usr/share/dotnet`
|
||||
- Windows:`C:\Program Files\dotnet`
|
||||
- V1 version of Action installs .NET to the user's directory
|
||||
- Ubuntu:`/home/runner/.dotnet`
|
||||
- Windows: `C:\Users\runneradmin\AppData\Local\Microsoft\dotnet`
|
||||
- It means that action always downloads and installs .NET version even if it is pre-installed. Also after using the action all pre-installed .NET versions are unavailable because `DOTNET_ROOT` is overridden to the user's directory.
|
||||
The behavior is different for macOS runners because the pre-installation directory matches the one that is used by action. It means action can use pre-installed versions if they exist, which speeds up the customer's workflow.
|
||||
|
||||
- The different behavior of the setup task on Ubuntu, Windows and macOS runners is unclear and confusing for customers.
|
||||
|
||||
- .NET supports installing and using multiple versions of .NET SDK and .NET runtime side-by-side. .NET CLI will use the latest installed .NET SDK and .NET runtime versions if there is no global.json file containing a different version. This behavior is defined by .NET design (https://docs.microsoft.com/en-us/dotnet/core/versions/selection).
|
||||
|
||||
- The action contains logic to handle inputs with wildcards, for example `5.0.x`, `5.0.*`, `5.x` or `5.*`. This logic uses metadata from `https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json` to retrieve the list of available releases and get the latest release version for the specified major and/or minor version from the input. After that, installer script (`dotnet-install.ps1` for Windows or `dotnet-install.sh` for Linux and macOS) installs the required SDK using exact version as a parameter.
|
||||
|
||||
# Proposal
|
||||
|
||||
- Change .NET installation path for Windows and Ubuntu images to match the location of pre-installed versions by using `-InstallDir` (Windows) and `--install-dir` (Ubuntu) properties for installer scripts:
|
||||
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script
|
||||
|
||||
- Simplify and in some cases fully get rid of logic for resolving wildcard versions and start relying on [official installer scripts provided by .NET Core team](https://github.com/dotnet/install-scripts).
|
||||
The execution `dotnet-install.ps1 -Channel 5.0` installs the latest patch version for 5.0 SDK. If SDK is in the prerelease phase, the latest prerelease version (preview or rc) will be installed.
|
||||
|
||||
Inputs with wildcards in the patch tag (`5.0.x` or `5.0.*`) can be handled by passing major and minor versions to the installer script directly as a `channel` parameter. This parameter supports two-part version in `X.Y` format as input value ([see installer scripts documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script)).
|
||||
|
||||
Inputs with wildcards in the minor tag (`3.x` or `3.*`) can be handled like that:
|
||||
1. The request is sent to MS dist and the `releases.json` file is got
|
||||
2. The action gets the latest possible channel version out of retrieved `releases.json` that satisfies input major tag (e.g. for `3.x` nowadays it's `3.1`)
|
||||
3. Retrieved channel version is passed to installer script directly as `channel` parameter.
|
||||
|
||||
> **Note:** Using the `channel` parameter of the MS .NET installer scripts will allow us to use the `quality` parameter as well. This functionality is also asked for by our customers.
|
||||
|
||||
# Breaking changes
|
||||
- The presence of pre-installed .NET versions that are higher than the version that the users specify in the setup task can be breaking for some customers, who expect only one installed .NET version on the runner after using the setup task. If a user doesn't have .NET version specified in project file, the `dotnet` will use the latest installed version instead of provided in the setup task.
|
||||
> **Note:** It is the biggest deal in this ADR.
|
||||
|
||||
Previously, when a user would specify a .NET version, this exact version was used by the `dotnet` command by default (because it was installed in a separate folder and there were no other.NET versions in that folder)
|
||||
In the proposal, the specified version will be installed on the machine but the latest version will be used by the `dotnet` command by default (because specified version will be installed alongside with pre-installed .NET versions).
|
||||
Based on [official .NET documentation](https://docs.microsoft.com/en-us/dotnet/core/versions/selection), it is expected behavior and how it works on user's local machine with multiple installed .NET versions but some customer's workflows could be broken because they already rely on current behavior.
|
||||
|
||||
To avoid breaking customers, we will need to release a new major task version (v3).
|
||||
|
||||
# v3-preview
|
||||
There will be a v3-preview branch that will be created for development and testing. Any changes will first be merged into the v3-preview branch. After a period of testing & verification, the v3-preview branch will be merged into the main branch and a v3 tag will be created. Any GitHub public documentation and starter workflows that mention setup-dotnet will then be updated to use v3 instead of v2:
|
||||
- [README.md](https://github.com/actions/setup-dotnet/blob/main/README.md)
|
||||
- [action.yml](https://github.com/actions/setup-dotnet/blob/main/action.yml)
|
||||
- [GitHub docs](https://docs.github.com/en/actions/guides/building-and-testing-net#using-a-specific-net-version)
|
||||
- Starter-workflow yamls: [#1](https://github.com/actions/starter-workflows/blob/main/ci/dotnet.yml#L17), [#2](https://github.com/actions/starter-workflows/blob/main/ci/dotnet-desktop.yml#L72)
|
||||
|
||||
# Consequences
|
||||
- Customers will be able to use pre-installed .NET versions with setup-dotnet action on Windows and Ubuntu
|
@ -1,34 +1,113 @@
|
||||
# Contributors
|
||||
|
||||
Thank you for contributing! This action is targetted around setting up the dotnet cli and related sdks for GitHub actions. As part of that we use proxy settings (for self-hosted runners) and set-up nuget authentication for private feeds.
|
||||
Thank you for contributing!
|
||||
|
||||
If you would like to contribute there are a few things to consider:
|
||||
We have prepared a short guide so that the process of making your contribution is as simple and clear as possible. Please check it out before you contribute!
|
||||
|
||||
## Commands to use
|
||||
## How can I contribute...
|
||||
|
||||
- npm run build - Compiles the action into a single js file at dist/index.js (Please check in the changes made by this command)
|
||||
- npm run test - Runs all tests under __tests__
|
||||
- npm run format - Runs formatting required to pass the lint test (Please check in the changes made by this command)
|
||||
- npm run update-installers - Updates the install-dotnet scripts in externals (Please check in the changes made by this command)
|
||||
* [Contribute Documentation:green_book:](#contribute-documentation)
|
||||
|
||||
## To check in or not to check in
|
||||
* [Contribute Code :computer:](#contribute-code)
|
||||
|
||||
- Do check in source (src)
|
||||
- Do check in index file (dist)
|
||||
- Do check in updates to install-dotnet scripts (externals)
|
||||
- Do not check in build output (lib)
|
||||
- Do not check in runtime (node_modules)
|
||||
* [Provide Support on Issues:pencil:](#provide-support-on-issues)
|
||||
|
||||
## Writing tests
|
||||
* [Review Pull Requests:mag:](#review-pull-requests)
|
||||
|
||||
With any contribution please take time to consider how this can be tested to maintain high quality. Current tests can be found in the folder __tests__ for examples.
|
||||
## Contribute documentation
|
||||
|
||||
## Creating new version
|
||||
Documentation is a super important, critical part of this project. Docs are how we keep track of what we're doing, how, and why. It's how we stay on the same page about our policies and how we tell others everything they need to be able to use this project or contribute to it.
|
||||
|
||||
Details on versioning can be found here: https://github.com/actions/toolkit/blob/main/docs/action-versioning.md
|
||||
Create a new release using the UI. Version format should be `v1.x.x`. Creating a new major version requires reaction from users and should be done only with breaking changes.
|
||||
Once the new release is created, the v1 tag needs to be updated as well.
|
||||
```
|
||||
git tag -fa v1 -m "Update v1 tag"
|
||||
git push origin v1 --force
|
||||
```
|
||||
Documentation contributions of any size are welcome! Feel free to contribute even if you're just rewording a sentence to be more clear, or fixing a spelling mistake!
|
||||
|
||||
**How to contribute:**
|
||||
|
||||
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a convenient way of commenting and amending the proposed changes.
|
||||
|
||||
- Please check that no one else has already created a pull request with these or similar changes
|
||||
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
||||
- Make sure your changes are formatted properly and consistently with the rest of the documentation
|
||||
- Re-read what you wrote, and run a spellchecker on it to make sure you didn't miss anything
|
||||
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
||||
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
||||
|
||||
**Once you've filed the pull request:**
|
||||
|
||||
- Maintainers will review your pull request
|
||||
- If a maintainer requests changes, first of all, try to think about this request critically and only after that implement and request another review
|
||||
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action and updating the major tag
|
||||
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
||||
|
||||
## Contribute code
|
||||
|
||||
We like code commits a lot! They're super handy, and they keep the project going and doing the work it needs to do to be useful to others.
|
||||
|
||||
Code contributions of just about any size are acceptable!
|
||||
|
||||
The main difference between code contributions and documentation contributions is that contributing code requires the inclusion of relevant tests for the code being added or changed. Contributions without accompanying tests will be held off until a test is added unless the maintainers consider the specific tests to be either impossible or way too much of a burden for such a contribution.
|
||||
|
||||
**How to contribute:**
|
||||
|
||||
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a convenient way of commenting and amending the proposed changes.
|
||||
|
||||
- Please check that no one else has already created a pull request with these or similar changes
|
||||
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
||||
- Format, build and test changes
|
||||
- Make sure your changes are well formatted and that all tests are passing
|
||||
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
||||
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
||||
|
||||
**Learn more about how to work with the repository:**
|
||||
|
||||
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
|
||||
- To comply with the code style, **you need to run the `format` script**
|
||||
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
|
||||
|
||||
**Learn more about how to implement tests:**
|
||||
|
||||
Adding or changing tests is an integral part of making a change to the code.
|
||||
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [workflow.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/workflow.yml).
|
||||
|
||||
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality
|
||||
- Tests should cover a successful execution, as well as some edge cases and possible errors
|
||||
- As already mentioned, pull requests without tests will be considered more carefully by maintainers. If you are sure that in this situation the tests are not needed or cannot be implemented with a commensurate effort - please add this clarification message to your pull request
|
||||
|
||||
**Once you've filed the pull request:**
|
||||
|
||||
- CI will start automatically with some checks. Wait until the end of the execution and make sure that all checks passed successfully. If some checks fail, you can open them one by one, try to find the reason for failing and make changes to your code to resolve the problem
|
||||
> Sometimes you may need to update the installers you can do this with the `npm run update-installers` command
|
||||
- Maintainers will review your pull request
|
||||
- If a maintainer requests changes, first of all, try to think about his request critically and only after that implement and request another review
|
||||
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action and updating the major tag
|
||||
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
||||
|
||||
## Provide support on issues
|
||||
|
||||
Helping out other users with their questions is an awesome way of contributing to any community. It's not uncommon for most of the issues on open source projects to be support-related questions by users trying to understand something they ran into or find their way around a known bug.
|
||||
|
||||
**To help other folks out with their questions:**
|
||||
|
||||
- Go to the [issue tracker](https://github.com/actions/setup-dotnet/issues)
|
||||
- Read through the list until you find something that you're familiar enough with to answer to
|
||||
- Respond to the issue with whatever details are needed to clarify the question, or get more details about what's going on
|
||||
- Once the discussion wraps up and things are clarified, ask the original issue filer (or a maintainer) to close it for you
|
||||
|
||||
*Some notes on picking up support issues:*
|
||||
|
||||
- Avoid responding to issues you don't know you can answer accurately
|
||||
- Try to refer to past issues with accepted answers as much as possible. Link to them from your replies
|
||||
- Be kind and patient with users. Often, folks who have run into confusing things might be upset or impatient. This is natural. If you feel uncomfortable in conversation with them, it's better to stay away or withdraw from the issue.
|
||||
|
||||
> If some user is violating our code of conduct [standards](https://github.com/actions/setup-dotnet/blob/main/CODE_OF_CONDUCT.md#our-standards), refer to the [Enforcement](https://github.com/actions/setup-dotnet/blob/main/CODE_OF_CONDUCT.md#enforcement) section of the Code of Conduct to resolve the conflict
|
||||
|
||||
## Review pull requests
|
||||
|
||||
Another great way to contribute is to review pull request. Please, be extra kind: people who submit code/doc contributions are putting themselves in a pretty vulnerable position, and have put time and care into what they've done (even if that's not obvious to you!) Please, always respond with respect, and be understanding, but don't feel like you need to sacrifice your standards for their sake, either.
|
||||
|
||||
**How to review:**
|
||||
|
||||
- Go to the [pull requests](https://github.com/actions/setup-dotnet/pulls)
|
||||
- Make sure you're familiar with the code or documentation is updated, unless it's a minor change (spellchecking, minor formatting, etc.)
|
||||
- Review changes using the GitHub functionality. You can ask a clarifying question, point out an error or suggest an alternative.
|
||||
> Note: You may ask for minor changes - "nitpicks", but consider whether they are real blockers to merging or not
|
||||
- Submit your review, which may include comments, an approval, or a changes request
|
3099
externals/install-dotnet.ps1
vendored
3099
externals/install-dotnet.ps1
vendored
File diff suppressed because it is too large
Load Diff
342
externals/install-dotnet.sh
vendored
342
externals/install-dotnet.sh
vendored
@ -298,20 +298,11 @@ get_machine_architecture() {
|
||||
if command -v uname > /dev/null; then
|
||||
CPUName=$(uname -m)
|
||||
case $CPUName in
|
||||
armv1*|armv2*|armv3*|armv4*|armv5*|armv6*)
|
||||
echo "armv6-or-below"
|
||||
return 0
|
||||
;;
|
||||
armv*l)
|
||||
echo "arm"
|
||||
return 0
|
||||
;;
|
||||
aarch64|arm64)
|
||||
if [ "$(getconf LONG_BIT)" -lt 64 ]; then
|
||||
# This is 32-bit OS running on 64-bit CPU (for example Raspberry Pi OS)
|
||||
echo "arm"
|
||||
return 0
|
||||
fi
|
||||
echo "arm64"
|
||||
return 0
|
||||
;;
|
||||
@ -319,22 +310,6 @@ get_machine_architecture() {
|
||||
echo "s390x"
|
||||
return 0
|
||||
;;
|
||||
ppc64le)
|
||||
echo "ppc64le"
|
||||
return 0
|
||||
;;
|
||||
loongarch64)
|
||||
echo "loongarch64"
|
||||
return 0
|
||||
;;
|
||||
riscv64)
|
||||
echo "riscv64"
|
||||
return 0
|
||||
;;
|
||||
powerpc|ppc)
|
||||
echo "ppc"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@ -351,13 +326,7 @@ get_normalized_architecture_from_architecture() {
|
||||
local architecture="$(to_lowercase "$1")"
|
||||
|
||||
if [[ $architecture == \<auto\> ]]; then
|
||||
machine_architecture="$(get_machine_architecture)"
|
||||
if [[ "$machine_architecture" == "armv6-or-below" ]]; then
|
||||
say_err "Architecture \`$machine_architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo $machine_architecture
|
||||
echo "$(get_machine_architecture)"
|
||||
return 0
|
||||
fi
|
||||
|
||||
@ -378,14 +347,6 @@ get_normalized_architecture_from_architecture() {
|
||||
echo "s390x"
|
||||
return 0
|
||||
;;
|
||||
ppc64le)
|
||||
echo "ppc64le"
|
||||
return 0
|
||||
;;
|
||||
loongarch64)
|
||||
echo "loongarch64"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
|
||||
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||
@ -423,17 +384,11 @@ get_normalized_architecture_for_specific_sdk_version() {
|
||||
# args:
|
||||
# version or channel - $1
|
||||
is_arm64_supported() {
|
||||
# Extract the major version by splitting on the dot
|
||||
major_version="${1%%.*}"
|
||||
|
||||
# Check if the major version is a valid number and less than 6
|
||||
case "$major_version" in
|
||||
[0-9]*)
|
||||
if [ "$major_version" -lt 6 ]; then
|
||||
echo false
|
||||
return 0
|
||||
fi
|
||||
;;
|
||||
#any channel or version that starts with the specified versions
|
||||
case "$1" in
|
||||
( "1"* | "2"* | "3"* | "4"* | "5"*)
|
||||
echo false
|
||||
return 0
|
||||
esac
|
||||
|
||||
echo true
|
||||
@ -452,13 +407,8 @@ get_normalized_os() {
|
||||
echo "$osname"
|
||||
return 0
|
||||
;;
|
||||
macos)
|
||||
osname='osx'
|
||||
echo "$osname"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, macos, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||
say_err "'$user_defined_os' is not a supported value for --os option, supported values are: osx, linux, linux-musl, freebsd, rhel.6. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
@ -501,10 +451,6 @@ get_normalized_channel() {
|
||||
|
||||
local channel="$(to_lowercase "$1")"
|
||||
|
||||
if [[ $channel == current ]]; then
|
||||
say_warning 'Value "Current" is deprecated for -Channel option. Use "STS" instead.'
|
||||
fi
|
||||
|
||||
if [[ $channel == release/* ]]; then
|
||||
say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.';
|
||||
fi
|
||||
@ -515,14 +461,6 @@ get_normalized_channel() {
|
||||
echo "LTS"
|
||||
return 0
|
||||
;;
|
||||
sts)
|
||||
echo "STS"
|
||||
return 0
|
||||
;;
|
||||
current)
|
||||
echo "STS"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "$channel"
|
||||
return 0
|
||||
@ -588,40 +526,6 @@ is_dotnet_package_installed() {
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# downloaded file - $1
|
||||
# remote_file_size - $2
|
||||
validate_remote_local_file_sizes()
|
||||
{
|
||||
eval $invocation
|
||||
|
||||
local downloaded_file="$1"
|
||||
local remote_file_size="$2"
|
||||
local file_size=''
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
file_size="$(stat -c '%s' "$downloaded_file")"
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# hardcode in order to avoid conflicts with GNU stat
|
||||
file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
|
||||
fi
|
||||
|
||||
if [ -n "$file_size" ]; then
|
||||
say "Downloaded file size is $file_size bytes."
|
||||
|
||||
if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
|
||||
if [ "$remote_file_size" -ne "$file_size" ]; then
|
||||
say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
|
||||
else
|
||||
say "The remote and local file sizes are equal."
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
say "Either downloaded or local package size can not be measured. One of them may be corrupted."
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# channel - $2
|
||||
@ -956,37 +860,6 @@ get_absolute_path() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# override - $1 (boolean, true or false)
|
||||
get_cp_options() {
|
||||
eval $invocation
|
||||
|
||||
local override="$1"
|
||||
local override_switch=""
|
||||
|
||||
if [ "$override" = false ]; then
|
||||
override_switch="-n"
|
||||
|
||||
# create temporary files to check if 'cp -u' is supported
|
||||
tmp_dir="$(mktemp -d)"
|
||||
tmp_file="$tmp_dir/testfile"
|
||||
tmp_file2="$tmp_dir/testfile2"
|
||||
|
||||
touch "$tmp_file"
|
||||
|
||||
# use -u instead of -n if it's available
|
||||
if cp -u "$tmp_file" "$tmp_file2" 2>/dev/null; then
|
||||
override_switch="-u"
|
||||
fi
|
||||
|
||||
# clean up
|
||||
rm -f "$tmp_file" "$tmp_file2"
|
||||
rm -rf "$tmp_dir"
|
||||
fi
|
||||
|
||||
echo "$override_switch"
|
||||
}
|
||||
|
||||
# args:
|
||||
# input_files - stdin
|
||||
# root_path - $1
|
||||
@ -998,7 +871,15 @@ copy_files_or_dirs_from_list() {
|
||||
local root_path="$(remove_trailing_slash "$1")"
|
||||
local out_path="$(remove_trailing_slash "$2")"
|
||||
local override="$3"
|
||||
local override_switch="$(get_cp_options "$override")"
|
||||
local osname="$(get_current_os_name)"
|
||||
local override_switch=$(
|
||||
if [ "$override" = false ]; then
|
||||
if [ "$osname" = "linux-musl" ]; then
|
||||
printf -- "-u";
|
||||
else
|
||||
printf -- "-n";
|
||||
fi
|
||||
fi)
|
||||
|
||||
cat | uniq | while read -r file_path; do
|
||||
local path="$(remove_beginning_slash "${file_path#$root_path}")"
|
||||
@ -1013,39 +894,14 @@ copy_files_or_dirs_from_list() {
|
||||
done
|
||||
}
|
||||
|
||||
# args:
|
||||
# zip_uri - $1
|
||||
get_remote_file_size() {
|
||||
local zip_uri="$1"
|
||||
|
||||
if machine_has "curl"; then
|
||||
file_size=$(curl -sI "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
|
||||
elif machine_has "wget"; then
|
||||
file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
|
||||
else
|
||||
say "Neither curl nor wget is available on this system."
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -n "$file_size" ]; then
|
||||
say "Remote file $zip_uri size is $file_size bytes."
|
||||
echo "$file_size"
|
||||
else
|
||||
say_verbose "Content-Length header was not extracted for $zip_uri."
|
||||
echo ""
|
||||
fi
|
||||
}
|
||||
|
||||
# args:
|
||||
# zip_path - $1
|
||||
# out_path - $2
|
||||
# remote_file_size - $3
|
||||
extract_dotnet_package() {
|
||||
eval $invocation
|
||||
|
||||
local zip_path="$1"
|
||||
local out_path="$2"
|
||||
local remote_file_size="$3"
|
||||
|
||||
local temp_out_path="$(mktemp -d "$temporary_file_template")"
|
||||
|
||||
@ -1055,13 +911,9 @@ extract_dotnet_package() {
|
||||
local folders_with_version_regex='^.*/[0-9]+\.[0-9]+[^/]+/'
|
||||
find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
|
||||
find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
|
||||
|
||||
validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
|
||||
|
||||
|
||||
rm -rf "$temp_out_path"
|
||||
if [ -z ${keep_zip+x} ]; then
|
||||
rm -f "$zip_path" && say_verbose "Temporary archive file $zip_path was removed"
|
||||
fi
|
||||
rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
say_err "Extraction failed"
|
||||
@ -1272,69 +1124,13 @@ downloadwget() {
|
||||
return 0
|
||||
}
|
||||
|
||||
extract_stem() {
|
||||
local url="$1"
|
||||
# extract the protocol
|
||||
proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
|
||||
# remove the protocol
|
||||
url="${1/$proto/}"
|
||||
# extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
|
||||
full_path="$(echo $url | grep / | cut -d/ -f2-)"
|
||||
path="$(echo $full_path | cut -d/ -f2-)"
|
||||
echo $path
|
||||
}
|
||||
|
||||
check_url_exists() {
|
||||
eval $invocation
|
||||
local url="$1"
|
||||
|
||||
local code=""
|
||||
if machine_has "curl"
|
||||
then
|
||||
code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
|
||||
elif machine_has "wget"
|
||||
then
|
||||
# get the http response, grab the status code
|
||||
server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
|
||||
code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
|
||||
fi
|
||||
if [ $code = "200" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
sanitize_redirect_url() {
|
||||
eval $invocation
|
||||
|
||||
local url_stem
|
||||
url_stem=$(extract_stem "$1")
|
||||
say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
|
||||
|
||||
for feed in "${feeds[@]}"
|
||||
do
|
||||
local trial_url="$feed/$url_stem"
|
||||
say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
|
||||
if check_url_exists "$trial_url"; then
|
||||
say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
|
||||
echo "$trial_url"
|
||||
return 0
|
||||
else
|
||||
say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
get_download_link_from_aka_ms() {
|
||||
eval $invocation
|
||||
|
||||
#quality is not supported for LTS or STS channel
|
||||
#STS maps to current
|
||||
if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "STS") ]]; then
|
||||
#quality is not supported for LTS or current channel
|
||||
if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "current") ]]; then
|
||||
normalized_quality=""
|
||||
say_warning "Specifying quality for STS or LTS channel is not supported, the quality will be ignored."
|
||||
say_warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored."
|
||||
fi
|
||||
|
||||
say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
|
||||
@ -1363,12 +1159,6 @@ get_download_link_from_aka_ms() {
|
||||
http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
|
||||
# They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
|
||||
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
|
||||
# The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
|
||||
# In this case it should not exclude the last.
|
||||
last_http_code=$( echo "$http_codes" | tail -n 1 )
|
||||
if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
|
||||
broken_redirects=$( echo "$http_codes" | grep -v '301' )
|
||||
fi
|
||||
|
||||
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
|
||||
if [[ -z "$broken_redirects" ]]; then
|
||||
@ -1379,11 +1169,6 @@ get_download_link_from_aka_ms() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
|
||||
if [[ -n "$sanitized_redirect_url" ]]; then
|
||||
aka_ms_download_link="$sanitized_redirect_url"
|
||||
fi
|
||||
|
||||
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
|
||||
return 0
|
||||
else
|
||||
@ -1395,16 +1180,23 @@ get_download_link_from_aka_ms() {
|
||||
get_feeds_to_use()
|
||||
{
|
||||
feeds=(
|
||||
"https://builds.dotnet.microsoft.com/dotnet"
|
||||
"https://ci.dot.net/public"
|
||||
"https://dotnetcli.azureedge.net/dotnet"
|
||||
"https://dotnetbuilds.azureedge.net/public"
|
||||
)
|
||||
|
||||
if [[ -n "$azure_feed" ]]; then
|
||||
feeds=("$azure_feed")
|
||||
fi
|
||||
|
||||
if [[ -n "$uncached_feed" ]]; then
|
||||
feeds=("$uncached_feed")
|
||||
if [[ "$no_cdn" == "true" ]]; then
|
||||
feeds=(
|
||||
"https://dotnetcli.blob.core.windows.net/dotnet"
|
||||
"https://dotnetbuilds.blob.core.windows.net/public"
|
||||
)
|
||||
|
||||
if [[ -n "$uncached_feed" ]]; then
|
||||
feeds=("$uncached_feed")
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
@ -1447,7 +1239,7 @@ generate_akams_links() {
|
||||
|
||||
normalized_version="$(to_lowercase "$version")"
|
||||
if [[ "$normalized_version" != "latest" ]] && [ -n "$normalized_quality" ]; then
|
||||
say_err "Quality and Version options are not allowed to be specified simultaneously. See https://learn.microsoft.com/dotnet/core/tools/dotnet-install-script#options for details."
|
||||
say_err "Quality and Version options are not allowed to be specified simultaneously. See https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script#options for details."
|
||||
return 1
|
||||
fi
|
||||
|
||||
@ -1536,7 +1328,7 @@ generate_regular_links() {
|
||||
link_types+=("legacy")
|
||||
else
|
||||
legacy_download_link=""
|
||||
say_verbose "Could not construct a legacy_download_link; omitting..."
|
||||
say_verbose "Cound not construct a legacy_download_link; omitting..."
|
||||
fi
|
||||
|
||||
# Check if the SDK version is already installed.
|
||||
@ -1614,11 +1406,10 @@ install_dotnet() {
|
||||
eval $invocation
|
||||
local download_failed=false
|
||||
local download_completed=false
|
||||
local remote_file_size=0
|
||||
|
||||
mkdir -p "$install_root"
|
||||
zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
|
||||
say_verbose "Archive path: $zip_path"
|
||||
zip_path="$(mktemp "$temporary_file_template")"
|
||||
say_verbose "Zip path: $zip_path"
|
||||
|
||||
for link_index in "${!download_links[@]}"
|
||||
do
|
||||
@ -1639,10 +1430,10 @@ install_dotnet() {
|
||||
say "The resource at $link_type link '$download_link' is not available."
|
||||
;;
|
||||
*)
|
||||
say "Failed to download $link_type link '$download_link': $http_code $download_error_msg"
|
||||
say "Failed to download $link_type link '$download_link': $download_error_msg"
|
||||
;;
|
||||
esac
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
|
||||
else
|
||||
download_completed=true
|
||||
break
|
||||
@ -1655,10 +1446,8 @@ install_dotnet() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
remote_file_size="$(get_remote_file_size "$download_link")"
|
||||
|
||||
say "Extracting archive from $download_link"
|
||||
extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
|
||||
say "Extracting zip from $download_link"
|
||||
extract_dotnet_package "$zip_path" "$install_root" || return 1
|
||||
|
||||
# Check if the SDK version is installed; if not, fail the installation.
|
||||
# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
|
||||
@ -1700,6 +1489,7 @@ install_dir="<auto>"
|
||||
architecture="<auto>"
|
||||
dry_run=false
|
||||
no_path=false
|
||||
no_cdn=false
|
||||
azure_feed=""
|
||||
uncached_feed=""
|
||||
feed_credential=""
|
||||
@ -1772,6 +1562,10 @@ do
|
||||
verbose=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--no-cdn|-[Nn]o[Cc]dn)
|
||||
no_cdn=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--azure-feed|-[Aa]zure[Ff]eed)
|
||||
shift
|
||||
azure_feed="$1"
|
||||
@ -1803,42 +1597,25 @@ do
|
||||
override_non_versioned_files=false
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--keep-zip|-[Kk]eep[Zz]ip)
|
||||
keep_zip=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
--zip-path|-[Zz]ip[Pp]ath)
|
||||
shift
|
||||
zip_path="$1"
|
||||
;;
|
||||
-?|--?|-h|--help|-[Hh]elp)
|
||||
script_name="dotnet-install.sh"
|
||||
script_name="$(basename "$0")"
|
||||
echo ".NET Tools Installer"
|
||||
echo "Usage:"
|
||||
echo " # Install a .NET SDK of a given Quality from a given Channel"
|
||||
echo " $script_name [-c|--channel <CHANNEL>] [-q|--quality <QUALITY>]"
|
||||
echo " # Install a .NET SDK of a specific public version"
|
||||
echo " $script_name [-v|--version <VERSION>]"
|
||||
echo "Usage: $script_name [-c|--channel <CHANNEL>] [-v|--version <VERSION>] [-p|--prefix <DESTINATION>]"
|
||||
echo " $script_name -h|-?|--help"
|
||||
echo ""
|
||||
echo "$script_name is a simple command line interface for obtaining dotnet cli."
|
||||
echo " Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
echo " - The SDK needs to be installed without user interaction and without admin rights."
|
||||
echo " - The SDK installation doesn't need to persist across multiple CI runs."
|
||||
echo " To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -c,--channel <CHANNEL> Download from the channel specified, Defaults to \`$channel\`."
|
||||
echo " -Channel"
|
||||
echo " Possible values:"
|
||||
echo " - STS - the most recent Standard Term Support release"
|
||||
echo " - LTS - the most recent Long Term Support release"
|
||||
echo " - Current - most current release"
|
||||
echo " - LTS - most current supported release"
|
||||
echo " - 2-part version in a format A.B - represents a specific release"
|
||||
echo " examples: 2.0; 1.0"
|
||||
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
|
||||
echo " examples: 5.0.1xx, 5.0.2xx."
|
||||
echo " Supported since 5.0 release"
|
||||
echo " Warning: Value 'Current' is deprecated for the Channel parameter. Use 'STS' instead."
|
||||
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used."
|
||||
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
|
||||
echo " -Version"
|
||||
@ -1849,7 +1626,7 @@ do
|
||||
echo " -q,--quality <quality> Download the latest build of specified quality in the channel."
|
||||
echo " -Quality"
|
||||
echo " The possible values are: daily, signed, validated, preview, GA."
|
||||
echo " Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used."
|
||||
echo " Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used."
|
||||
echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
|
||||
echo " Supported since 5.0 release."
|
||||
echo " Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality."
|
||||
@ -1860,7 +1637,7 @@ do
|
||||
echo " -InstallDir"
|
||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||
echo " --arch,-Architecture,-Arch"
|
||||
echo " Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
|
||||
echo " Possible values: x64, arm, arm64 and s390x"
|
||||
echo " --os <system> Specifies operating system to be used when selecting the installer."
|
||||
echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
|
||||
echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
|
||||
@ -1876,14 +1653,15 @@ do
|
||||
echo " --verbose,-Verbose Display diagnostics information."
|
||||
echo " --azure-feed,-AzureFeed For internal use only."
|
||||
echo " Allows using a different storage to download SDK archives from."
|
||||
echo " This parameter is only used if --no-cdn is false."
|
||||
echo " --uncached-feed,-UncachedFeed For internal use only."
|
||||
echo " Allows using a different storage to download SDK archives from."
|
||||
echo " This parameter is only used if --no-cdn is true."
|
||||
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||
echo " -SkipNonVersionedFiles"
|
||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
|
||||
echo " Note: global.json must have a value for 'SDK:Version'"
|
||||
echo " --keep-zip,-KeepZip If set, downloaded file is kept."
|
||||
echo " --zip-path, -ZipPath If set, downloaded file is stored at the specified path."
|
||||
echo " -?,--?,-h,--help,-Help Shows this help message"
|
||||
echo ""
|
||||
echo "Install Location:"
|
||||
@ -1902,10 +1680,10 @@ do
|
||||
shift
|
||||
done
|
||||
|
||||
say_verbose "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
say_verbose "- The SDK needs to be installed without user interaction and without admin rights."
|
||||
say_verbose "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||
say_verbose "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||
say "Note that the intended use of this script is for Continuous Integration (CI) scenarios, where:"
|
||||
say "- The SDK needs to be installed without user interaction and without admin rights."
|
||||
say "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||
say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||
|
||||
if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
|
||||
message="Provide credentials via --feed-credential parameter."
|
||||
@ -1938,5 +1716,5 @@ else
|
||||
fi
|
||||
|
||||
say "Note that the script does not resolve dependencies during installation."
|
||||
say "To check the list of dependencies, go to https://learn.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
||||
say "Installation finished successfully."
|
||||
say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install, select your operating system and check the \"Dependencies\" section."
|
||||
say "Installation finished successfully."
|
||||
|
4937
package-lock.json
generated
4937
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
22
package.json
22
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "setup-dotnet",
|
||||
"version": "1.0.0",
|
||||
"version": "3.0.1",
|
||||
"private": true,
|
||||
"description": "setup dotnet action",
|
||||
"main": "lib/setup-dotnet.js",
|
||||
@ -8,16 +8,10 @@
|
||||
"build": "tsc && ncc build",
|
||||
"format": "prettier --write **/*.ts",
|
||||
"format-check": "prettier --check **/*.ts",
|
||||
"test": "jest",
|
||||
"prepare": "husky install",
|
||||
"test": "jest --coverage --config ./jest.config.js",
|
||||
"update-installers": "nwget https://dot.net/v1/dotnet-install.ps1 -O externals/install-dotnet.ps1 && nwget https://dot.net/v1/dotnet-install.sh -O externals/install-dotnet.sh"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"//": "Tests are not run at push time since they can take 2-4 minutes to complete",
|
||||
"pre-commit": "npm run format",
|
||||
"pre-push": "npm run format-check"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/actions/setup-dotnet.git"
|
||||
@ -30,10 +24,10 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.6.0",
|
||||
"@actions/core": "^1.9.1",
|
||||
"@actions/exec": "^1.0.4",
|
||||
"@actions/github": "^1.1.0",
|
||||
"@actions/http-client": "^1.0.8",
|
||||
"@actions/http-client": "^2.0.1",
|
||||
"@actions/io": "^1.0.2",
|
||||
"fast-xml-parser": "^3.15.1",
|
||||
"semver": "^6.3.0",
|
||||
@ -41,10 +35,10 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.0.2",
|
||||
"@types/node": "^12.12.62",
|
||||
"@types/node": "^16.11.25",
|
||||
"@types/semver": "^6.2.2",
|
||||
"@zeit/ncc": "^0.21.1",
|
||||
"husky": "^7.0.2",
|
||||
"@vercel/ncc": "^0.33.4",
|
||||
"husky": "^8.0.1",
|
||||
"jest": "^27.2.5",
|
||||
"jest-circus": "^27.2.5",
|
||||
"prettier": "^1.19.1",
|
||||
|
@ -4,7 +4,6 @@ import * as core from '@actions/core';
|
||||
import * as github from '@actions/github';
|
||||
import * as xmlbuilder from 'xmlbuilder';
|
||||
import * as xmlParser from 'fast-xml-parser';
|
||||
import {ProcessEnvOptions} from 'child_process';
|
||||
|
||||
export function configAuthentication(
|
||||
feedUrl: string,
|
||||
@ -47,7 +46,7 @@ function writeFeedToFile(
|
||||
existingFileLocation: string,
|
||||
tempFileLocation: string
|
||||
) {
|
||||
console.log(
|
||||
core.info(
|
||||
`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`
|
||||
);
|
||||
let xml: xmlbuilder.XMLElement;
|
||||
@ -58,7 +57,7 @@ function writeFeedToFile(
|
||||
owner = github.context.repo.owner;
|
||||
}
|
||||
|
||||
if (!process.env.NUGET_AUTH_TOKEN || process.env.NUGET_AUTH_TOKEN == '') {
|
||||
if (!process.env.NUGET_AUTH_TOKEN) {
|
||||
throw new Error(
|
||||
'The NUGET_AUTH_TOKEN environment variable was not provided. In this step, add the following: \r\nenv:\r\n NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}'
|
||||
);
|
||||
@ -67,22 +66,22 @@ function writeFeedToFile(
|
||||
if (fs.existsSync(existingFileLocation)) {
|
||||
// get key from existing NuGet.config so NuGet/dotnet can match credentials
|
||||
const curContents: string = fs.readFileSync(existingFileLocation, 'utf8');
|
||||
var json = xmlParser.parse(curContents, {ignoreAttributes: false});
|
||||
const json = xmlParser.parse(curContents, {ignoreAttributes: false});
|
||||
|
||||
if (typeof json.configuration == 'undefined') {
|
||||
if (typeof json.configuration === 'undefined') {
|
||||
throw new Error(`The provided NuGet.config seems invalid.`);
|
||||
}
|
||||
if (typeof json.configuration.packageSources != 'undefined') {
|
||||
if (typeof json.configuration.packageSources.add != 'undefined') {
|
||||
// file has at least one <add>
|
||||
if (typeof json.configuration.packageSources.add[0] == 'undefined') {
|
||||
if (typeof json.configuration.packageSources.add[0] === 'undefined') {
|
||||
// file has only one <add>
|
||||
if (
|
||||
json.configuration.packageSources.add['@_value']
|
||||
.toLowerCase()
|
||||
.includes(feedUrl.toLowerCase())
|
||||
) {
|
||||
let key = json.configuration.packageSources.add['@_key'];
|
||||
const key = json.configuration.packageSources.add['@_key'];
|
||||
sourceKeys.push(key);
|
||||
core.debug(`Found a URL with key ${key}`);
|
||||
}
|
||||
@ -97,7 +96,7 @@ function writeFeedToFile(
|
||||
const value = source['@_value'];
|
||||
core.debug(`source '${value}'`);
|
||||
if (value.toLowerCase().includes(feedUrl.toLowerCase())) {
|
||||
let key = source['@_key'];
|
||||
const key = source['@_key'];
|
||||
sourceKeys.push(key);
|
||||
core.debug(`Found a URL with key ${key}`);
|
||||
}
|
||||
@ -114,7 +113,7 @@ function writeFeedToFile(
|
||||
.up()
|
||||
.up();
|
||||
|
||||
if (sourceKeys.length == 0) {
|
||||
if (!sourceKeys.length) {
|
||||
let keystring = 'Source';
|
||||
xml = xml
|
||||
.ele('packageSources')
|
||||
@ -150,6 +149,6 @@ function writeFeedToFile(
|
||||
// ? '%NUGET_AUTH_TOKEN%'
|
||||
// : '$NUGET_AUTH_TOKEN'
|
||||
|
||||
var output = xml.end({pretty: true});
|
||||
const output = xml.end({pretty: true});
|
||||
fs.writeFileSync(tempFileLocation, output);
|
||||
}
|
||||
|
479
src/installer.ts
479
src/installer.ts
@ -2,173 +2,125 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import hc = require('@actions/http-client');
|
||||
import * as hc from '@actions/http-client';
|
||||
import {chmodSync} from 'fs';
|
||||
import * as path from 'path';
|
||||
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
||||
import * as semver from 'semver';
|
||||
import {readdir} from 'fs/promises';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
import {IS_LINUX, IS_WINDOWS} from './utils';
|
||||
import {QualityOptions} from './setup-dotnet';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
export interface DotnetVersion {
|
||||
type: string;
|
||||
value: string;
|
||||
qualityFlag: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the inputted version information
|
||||
*/
|
||||
export class DotNetVersionInfo {
|
||||
public inputVersion: string;
|
||||
private fullversion: string;
|
||||
private isExactVersionSet: boolean = false;
|
||||
export class DotnetVersionResolver {
|
||||
private inputVersion: string;
|
||||
private resolvedArgument: DotnetVersion;
|
||||
|
||||
constructor(version: string) {
|
||||
this.inputVersion = version;
|
||||
|
||||
// Check for exact match
|
||||
if (semver.valid(semver.clean(version) || '') != null) {
|
||||
this.fullversion = semver.clean(version) as string;
|
||||
this.isExactVersionSet = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const parts: string[] = version.split('.');
|
||||
|
||||
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
|
||||
|
||||
if (parts.length == 3 && parts[2] !== 'x' && parts[2] !== '*') {
|
||||
this.throwInvalidVersionFormat();
|
||||
}
|
||||
|
||||
const major = this.getVersionNumberOrThrow(parts[0]);
|
||||
const minor = ['x', '*'].includes(parts[1])
|
||||
? parts[1]
|
||||
: this.getVersionNumberOrThrow(parts[1]);
|
||||
|
||||
this.fullversion = major + '.' + minor;
|
||||
this.inputVersion = version.trim();
|
||||
this.resolvedArgument = {type: '', value: '', qualityFlag: false};
|
||||
}
|
||||
|
||||
private getVersionNumberOrThrow(input: string): number {
|
||||
try {
|
||||
if (!input || input.trim() === '') this.throwInvalidVersionFormat();
|
||||
private async resolveVersionInput(): Promise<void> {
|
||||
if (!semver.validRange(this.inputVersion)) {
|
||||
throw new Error(
|
||||
`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x`
|
||||
);
|
||||
}
|
||||
if (semver.valid(this.inputVersion)) {
|
||||
this.resolvedArgument.type = 'version';
|
||||
this.resolvedArgument.value = this.inputVersion;
|
||||
} else {
|
||||
const [major, minor] = this.inputVersion.split('.');
|
||||
|
||||
let number = Number(input);
|
||||
|
||||
if (Number.isNaN(number) || number < 0) this.throwInvalidVersionFormat();
|
||||
|
||||
return number;
|
||||
} catch {
|
||||
this.throwInvalidVersionFormat();
|
||||
return -1;
|
||||
if (this.isNumericTag(major)) {
|
||||
this.resolvedArgument.type = 'channel';
|
||||
if (this.isNumericTag(minor)) {
|
||||
this.resolvedArgument.value = `${major}.${minor}`;
|
||||
} else {
|
||||
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
this.resolvedArgument.value = await this.getLatestVersion(
|
||||
httpClient,
|
||||
[major, minor]
|
||||
);
|
||||
}
|
||||
}
|
||||
this.resolvedArgument.qualityFlag = +major >= 6 ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
private throwInvalidVersionFormat() {
|
||||
throw new Error(
|
||||
'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*'
|
||||
private isNumericTag(versionTag): boolean {
|
||||
return /^\d+$/.test(versionTag);
|
||||
}
|
||||
|
||||
public async createDotNetVersion(): Promise<{
|
||||
type: string;
|
||||
value: string;
|
||||
qualityFlag: boolean;
|
||||
}> {
|
||||
await this.resolveVersionInput();
|
||||
if (!this.resolvedArgument.type) {
|
||||
return this.resolvedArgument;
|
||||
}
|
||||
if (IS_WINDOWS) {
|
||||
this.resolvedArgument.type =
|
||||
this.resolvedArgument.type === 'channel' ? '-Channel' : '-Version';
|
||||
} else {
|
||||
this.resolvedArgument.type =
|
||||
this.resolvedArgument.type === 'channel' ? '--channel' : '--version';
|
||||
}
|
||||
return this.resolvedArgument;
|
||||
}
|
||||
|
||||
private async getLatestVersion(
|
||||
httpClient: hc.HttpClient,
|
||||
versionParts: string[]
|
||||
): Promise<string> {
|
||||
const response = await httpClient.getJson<any>(
|
||||
DotnetVersionResolver.DotNetCoreIndexUrl
|
||||
);
|
||||
const result = response.result || {};
|
||||
let releasesInfo: any[] = result['releases-index'];
|
||||
|
||||
let releaseInfo = releasesInfo.find(info => {
|
||||
let sdkParts: string[] = info['channel-version'].split('.');
|
||||
return sdkParts[0] === versionParts[0];
|
||||
});
|
||||
|
||||
if (!releaseInfo) {
|
||||
throw new Error(
|
||||
`Could not find info for version ${versionParts.join('.')} at ${
|
||||
DotnetVersionResolver.DotNetCoreIndexUrl
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
return releaseInfo['channel-version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* If true exacatly one version should be resolved
|
||||
*/
|
||||
public isExactVersion(): boolean {
|
||||
return this.isExactVersionSet;
|
||||
}
|
||||
|
||||
public version(): string {
|
||||
return this.fullversion;
|
||||
}
|
||||
static DotNetCoreIndexUrl: string =
|
||||
'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json';
|
||||
}
|
||||
|
||||
export class DotnetCoreInstaller {
|
||||
constructor(version: string, includePrerelease: boolean = false) {
|
||||
this.version = version;
|
||||
this.includePrerelease = includePrerelease;
|
||||
}
|
||||
|
||||
public async installDotnet() {
|
||||
let output = '';
|
||||
let resultCode = 0;
|
||||
|
||||
let calculatedVersion = await this.resolveVersion(
|
||||
new DotNetVersionInfo(this.version)
|
||||
);
|
||||
|
||||
var envVariables: {[key: string]: string} = {};
|
||||
for (let key in process.env) {
|
||||
if (process.env[key]) {
|
||||
let value: any = process.env[key];
|
||||
envVariables[key] = value;
|
||||
}
|
||||
}
|
||||
if (IS_WINDOWS) {
|
||||
let escapedScript = path
|
||||
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||
.replace(/'/g, "''");
|
||||
let command = `& '${escapedScript}'`;
|
||||
if (calculatedVersion) {
|
||||
command += ` -Version ${calculatedVersion}`;
|
||||
}
|
||||
if (process.env['https_proxy'] != null) {
|
||||
command += ` -ProxyAddress ${process.env['https_proxy']}`;
|
||||
}
|
||||
// This is not currently an option
|
||||
if (process.env['no_proxy'] != null) {
|
||||
command += ` -ProxyBypassList ${process.env['no_proxy']}`;
|
||||
}
|
||||
|
||||
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
||||
const powershellPath = await io.which('powershell', true);
|
||||
|
||||
var options: ExecOptions = {
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
output += data.toString();
|
||||
}
|
||||
},
|
||||
env: envVariables
|
||||
};
|
||||
|
||||
resultCode = await exec.exec(
|
||||
`"${powershellPath}"`,
|
||||
[
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
],
|
||||
options
|
||||
);
|
||||
} else {
|
||||
let escapedScript = path
|
||||
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||
.replace(/'/g, "''");
|
||||
chmodSync(escapedScript, '777');
|
||||
|
||||
const scriptPath = await io.which(escapedScript, true);
|
||||
|
||||
let scriptArguments: string[] = [];
|
||||
if (calculatedVersion) {
|
||||
scriptArguments.push('--version', calculatedVersion);
|
||||
}
|
||||
|
||||
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
||||
resultCode = await exec.exec(`"${scriptPath}"`, scriptArguments, {
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
output += data.toString();
|
||||
}
|
||||
},
|
||||
env: envVariables
|
||||
});
|
||||
}
|
||||
|
||||
if (resultCode != 0) {
|
||||
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
||||
}
|
||||
}
|
||||
private version: string;
|
||||
private quality: QualityOptions;
|
||||
private static readonly installationDirectoryWindows = path.join(
|
||||
process.env['PROGRAMFILES'] + '',
|
||||
'dotnet'
|
||||
);
|
||||
private static readonly installationDirectoryLinux = '/usr/share/dotnet';
|
||||
private static readonly installationDirectoryMac = path.join(
|
||||
process.env['HOME'] + '',
|
||||
'.dotnet'
|
||||
);
|
||||
|
||||
static addToPath() {
|
||||
if (process.env['DOTNET_INSTALL_DIR']) {
|
||||
@ -176,128 +128,145 @@ export class DotnetCoreInstaller {
|
||||
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
|
||||
} else {
|
||||
if (IS_WINDOWS) {
|
||||
// This is the default set in install-dotnet.ps1
|
||||
core.addPath(
|
||||
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
|
||||
);
|
||||
core.addPath(DotnetCoreInstaller.installationDirectoryWindows);
|
||||
core.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
|
||||
DotnetCoreInstaller.installationDirectoryWindows
|
||||
);
|
||||
} else if (IS_LINUX) {
|
||||
core.addPath(DotnetCoreInstaller.installationDirectoryLinux);
|
||||
core.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
DotnetCoreInstaller.installationDirectoryLinux
|
||||
);
|
||||
} else {
|
||||
// This is the default set in install-dotnet.sh
|
||||
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
|
||||
core.addPath(DotnetCoreInstaller.installationDirectoryMac);
|
||||
core.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
path.join(process.env['HOME'] + '', '.dotnet')
|
||||
DotnetCoreInstaller.installationDirectoryMac
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(process.env['PATH']);
|
||||
}
|
||||
|
||||
// versionInfo - versionInfo of the SDK/Runtime
|
||||
async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
|
||||
if (versionInfo.isExactVersion()) {
|
||||
return versionInfo.version();
|
||||
}
|
||||
|
||||
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
});
|
||||
|
||||
const releasesJsonUrl: string = await this.getReleasesJsonUrl(
|
||||
httpClient,
|
||||
versionInfo.version().split('.')
|
||||
);
|
||||
|
||||
const releasesResponse = await httpClient.getJson<any>(releasesJsonUrl);
|
||||
const releasesResult = releasesResponse.result || {};
|
||||
let releasesInfo: any[] = releasesResult['releases'];
|
||||
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
|
||||
return (
|
||||
semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version(), {
|
||||
includePrerelease: this.includePrerelease
|
||||
}) ||
|
||||
semver.satisfies(
|
||||
releaseInfo['sdk']['version-display'],
|
||||
versionInfo.version(),
|
||||
{
|
||||
includePrerelease: this.includePrerelease
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// Exclude versions that are newer than the latest if using not exact
|
||||
let latestSdk: string = releasesResult['latest-sdk'];
|
||||
|
||||
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
|
||||
semver.lte(releaseInfo['sdk']['version'], latestSdk, {
|
||||
includePrerelease: this.includePrerelease
|
||||
})
|
||||
);
|
||||
|
||||
// Sort for latest version
|
||||
releasesInfo = releasesInfo.sort((a, b) =>
|
||||
semver.rcompare(a['sdk']['version'], b['sdk']['version'], {
|
||||
includePrerelease: this.includePrerelease
|
||||
})
|
||||
);
|
||||
|
||||
if (releasesInfo.length == 0) {
|
||||
throw new Error(
|
||||
`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`
|
||||
);
|
||||
}
|
||||
|
||||
let release = releasesInfo[0];
|
||||
return release['sdk']['version'];
|
||||
constructor(version: string, quality: QualityOptions) {
|
||||
this.version = version;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
private async getReleasesJsonUrl(
|
||||
httpClient: hc.HttpClient,
|
||||
versionParts: string[]
|
||||
): Promise<string> {
|
||||
const response = await httpClient.getJson<any>(DotNetCoreIndexUrl);
|
||||
const result = response.result || {};
|
||||
let releasesInfo: any[] = result['releases-index'];
|
||||
|
||||
releasesInfo = releasesInfo.filter((info: any) => {
|
||||
// channel-version is the first 2 elements of the version (e.g. 2.1), filter out versions that don't match 2.1.x.
|
||||
const sdkParts: string[] = info['channel-version'].split('.');
|
||||
if (
|
||||
versionParts.length >= 2 &&
|
||||
!(versionParts[1] == 'x' || versionParts[1] == '*')
|
||||
) {
|
||||
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
|
||||
}
|
||||
return versionParts[0] == sdkParts[0];
|
||||
});
|
||||
|
||||
if (releasesInfo.length === 0) {
|
||||
throw new Error(
|
||||
`Could not find info for version ${versionParts.join(
|
||||
'.'
|
||||
)} at ${DotNetCoreIndexUrl}`
|
||||
);
|
||||
}
|
||||
|
||||
const releaseInfo = releasesInfo[0];
|
||||
if (releaseInfo['support-phase'] === 'eol') {
|
||||
private setQuality(
|
||||
dotnetVersion: DotnetVersion,
|
||||
scriptArguments: string[]
|
||||
): void {
|
||||
const option = IS_WINDOWS ? '-Quality' : '--quality';
|
||||
if (dotnetVersion.qualityFlag) {
|
||||
scriptArguments.push(option, this.quality);
|
||||
} else {
|
||||
core.warning(
|
||||
`${releaseInfo['product']} ${releaseInfo['channel-version']} is no longer supported and will not receive security updates in the future. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy.`
|
||||
`'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A and A.x formats where the major tag is higher than 5. You specified: ${this.version}. 'dotnet-quality' input is ignored.`
|
||||
);
|
||||
}
|
||||
|
||||
return releaseInfo['releases.json'];
|
||||
}
|
||||
|
||||
private version: string;
|
||||
private includePrerelease: boolean;
|
||||
}
|
||||
public async installDotnet(): Promise<string> {
|
||||
const windowsDefaultOptions = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command'
|
||||
];
|
||||
const scriptName = IS_WINDOWS ? 'install-dotnet.ps1' : 'install-dotnet.sh';
|
||||
const escapedScript = path
|
||||
.join(__dirname, '..', 'externals', scriptName)
|
||||
.replace(/'/g, "''");
|
||||
let scriptArguments: string[];
|
||||
let scriptPath = '';
|
||||
|
||||
const DotNetCoreIndexUrl: string =
|
||||
'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json';
|
||||
const versionResolver = new DotnetVersionResolver(this.version);
|
||||
const dotnetVersion = await versionResolver.createDotNetVersion();
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
scriptArguments = ['&', `'${escapedScript}'`];
|
||||
|
||||
if (dotnetVersion.type) {
|
||||
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
|
||||
}
|
||||
|
||||
if (this.quality) {
|
||||
this.setQuality(dotnetVersion, scriptArguments);
|
||||
}
|
||||
|
||||
if (process.env['https_proxy'] != null) {
|
||||
scriptArguments.push(`-ProxyAddress ${process.env['https_proxy']}`);
|
||||
}
|
||||
// This is not currently an option
|
||||
if (process.env['no_proxy'] != null) {
|
||||
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
|
||||
}
|
||||
|
||||
if (!process.env['DOTNET_INSTALL_DIR']) {
|
||||
process.env['DOTNET_INSTALL_DIR'] =
|
||||
DotnetCoreInstaller.installationDirectoryWindows;
|
||||
}
|
||||
|
||||
scriptPath =
|
||||
(await io.which('pwsh', false)) || (await io.which('powershell', true));
|
||||
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
|
||||
} else {
|
||||
chmodSync(escapedScript, '777');
|
||||
scriptPath = await io.which(escapedScript, true);
|
||||
scriptArguments = [];
|
||||
|
||||
if (dotnetVersion.type) {
|
||||
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
|
||||
}
|
||||
|
||||
if (this.quality) {
|
||||
this.setQuality(dotnetVersion, scriptArguments);
|
||||
}
|
||||
|
||||
if (!process.env['DOTNET_INSTALL_DIR']) {
|
||||
process.env['DOTNET_INSTALL_DIR'] = IS_LINUX
|
||||
? DotnetCoreInstaller.installationDirectoryLinux
|
||||
: DotnetCoreInstaller.installationDirectoryMac;
|
||||
}
|
||||
}
|
||||
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
||||
const getExecOutputOptions = {
|
||||
ignoreReturnCode: true,
|
||||
env: process.env as {string: string}
|
||||
};
|
||||
const {exitCode, stdout} = await exec.getExecOutput(
|
||||
`"${scriptPath}"`,
|
||||
scriptArguments,
|
||||
getExecOutputOptions
|
||||
);
|
||||
if (exitCode) {
|
||||
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
|
||||
}
|
||||
|
||||
return this.outputDotnetVersion(
|
||||
dotnetVersion.value,
|
||||
process.env['DOTNET_INSTALL_DIR']
|
||||
);
|
||||
}
|
||||
|
||||
private async outputDotnetVersion(
|
||||
version,
|
||||
installationPath
|
||||
): Promise<string> {
|
||||
let versionsOnRunner: string[] = await readdir(
|
||||
path.join(installationPath.replace(/'/g, ''), 'sdk')
|
||||
);
|
||||
|
||||
let installedVersion = semver.maxSatisfying(versionsOnRunner, version, {
|
||||
includePrerelease: true
|
||||
})!;
|
||||
|
||||
return installedVersion;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,45 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as installer from './installer';
|
||||
import {DotnetCoreInstaller} from './installer';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
import * as auth from './authutil';
|
||||
|
||||
const qualityOptions = [
|
||||
'daily',
|
||||
'signed',
|
||||
'validated',
|
||||
'preview',
|
||||
'ga'
|
||||
] as const;
|
||||
|
||||
export type QualityOptions = typeof qualityOptions[number];
|
||||
|
||||
export async function run() {
|
||||
try {
|
||||
//
|
||||
// dotnet-version is optional, but needs to be provided for most use cases.
|
||||
// If supplied, install / use from the tool cache.
|
||||
// global-version-file may be specified to point to a specific global.json
|
||||
// and will be used to install an additional version.
|
||||
// If not supplied, look for version in ./global.json.
|
||||
// If a valid version still can't be identified, nothing will be installed.
|
||||
// Proxy, auth, (etc) are still set up, even if no version is identified
|
||||
//
|
||||
let versions = core.getMultilineInput('dotnet-version');
|
||||
const versions = core.getMultilineInput('dotnet-version');
|
||||
const installedDotnetVersions: string[] = [];
|
||||
|
||||
const globalJsonFileInput = core.getInput('global-json-file');
|
||||
if (globalJsonFileInput) {
|
||||
const globalJsonPath = path.join(process.cwd(), globalJsonFileInput);
|
||||
if (!fs.existsSync(globalJsonPath)) {
|
||||
throw new Error(
|
||||
`The specified global.json file '${globalJsonFileInput}' does not exist`
|
||||
);
|
||||
}
|
||||
versions.push(getVersionFromGlobalJson(globalJsonPath));
|
||||
}
|
||||
|
||||
if (!versions.length) {
|
||||
// Try to fall back to global.json
|
||||
core.debug('No version found, trying to find version from global.json');
|
||||
@ -24,18 +50,22 @@ export async function run() {
|
||||
}
|
||||
|
||||
if (versions.length) {
|
||||
const includePrerelease: boolean =
|
||||
(core.getInput('include-prerelease') || 'false').toLowerCase() ===
|
||||
'true';
|
||||
let dotnetInstaller!: installer.DotnetCoreInstaller;
|
||||
for (const version of new Set<string>(versions)) {
|
||||
dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
version,
|
||||
includePrerelease
|
||||
const quality = core.getInput('dotnet-quality') as QualityOptions;
|
||||
|
||||
if (quality && !qualityOptions.includes(quality)) {
|
||||
throw new Error(
|
||||
`${quality} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`
|
||||
);
|
||||
await dotnetInstaller.installDotnet();
|
||||
}
|
||||
installer.DotnetCoreInstaller.addToPath();
|
||||
|
||||
let dotnetInstaller: DotnetCoreInstaller;
|
||||
const uniqueVersions = new Set<string>(versions);
|
||||
for (const version of uniqueVersions) {
|
||||
dotnetInstaller = new DotnetCoreInstaller(version, quality);
|
||||
const installedVersion = await dotnetInstaller.installDotnet();
|
||||
installedDotnetVersions.push(installedVersion);
|
||||
}
|
||||
DotnetCoreInstaller.addToPath();
|
||||
}
|
||||
|
||||
const sourceUrl: string = core.getInput('source-url');
|
||||
@ -44,8 +74,22 @@ export async function run() {
|
||||
auth.configAuthentication(sourceUrl, configFile);
|
||||
}
|
||||
|
||||
const comparisonRange: string = globalJsonFileInput
|
||||
? versions[versions.length - 1]!
|
||||
: '*';
|
||||
|
||||
const versionToOutput = semver.maxSatisfying(
|
||||
installedDotnetVersions,
|
||||
comparisonRange,
|
||||
{
|
||||
includePrerelease: true
|
||||
}
|
||||
);
|
||||
|
||||
core.setOutput('dotnet-version', versionToOutput);
|
||||
|
||||
const matchersPath = path.join(__dirname, '..', '.github');
|
||||
console.log(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`);
|
||||
core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`);
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
|
2
src/utils.ts
Normal file
2
src/utils.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export const IS_WINDOWS = process.platform === 'win32';
|
||||
export const IS_LINUX = process.platform === 'linux';
|
Reference in New Issue
Block a user