mirror of
https://github.com/actions/setup-dotnet.git
synced 2026-03-22 14:42:20 +08:00
Compare commits
157 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a71d1eb2c8 | ||
|
|
b50d70502b | ||
|
|
d8cff32ae5 | ||
|
|
7b2009794e | ||
|
|
53d6483af8 | ||
|
|
34c59b7d0b | ||
|
|
bd485b6bd1 | ||
|
|
23fa2c1473 | ||
|
|
291588df6a | ||
|
|
87189a16c7 | ||
|
|
cde58ab948 | ||
|
|
20e68089c2 | ||
|
|
7790315509 | ||
|
|
c47e26f841 | ||
|
|
3edf2e9363 | ||
|
|
a8c97016ef | ||
|
|
07b4a80293 | ||
|
|
d08d2193f9 | ||
|
|
632ccbdfb9 | ||
|
|
b81836a248 | ||
|
|
3b539379a8 | ||
|
|
596753d72c | ||
|
|
f9d7f16c00 | ||
|
|
56d96e897e | ||
|
|
5a201f5e82 | ||
|
|
13ccc115f4 | ||
|
|
f2eb44dadd | ||
|
|
8dcf1ee9bc | ||
|
|
3707a44789 | ||
|
|
385512c5e5 | ||
|
|
083d63a2ff | ||
|
|
6930747f7f | ||
|
|
20afff9c90 | ||
|
|
36fa9877a9 | ||
|
|
77a48bbb85 | ||
|
|
4f71fcfa81 | ||
|
|
768b4eb7db | ||
|
|
ba7e1e2155 | ||
|
|
6803d4b94d | ||
|
|
3c80e97cbd | ||
|
|
8d30c127da | ||
|
|
2d101adc9f | ||
|
|
c8b60fb6bf | ||
|
|
bea420f2fd | ||
|
|
3a3dbe976e | ||
|
|
ce38f90a9a | ||
|
|
c32ed2108b | ||
|
|
d99c06115d | ||
|
|
f311b6d978 | ||
|
|
9427b17c42 | ||
|
|
f39691d155 | ||
|
|
19e6ad3fe0 | ||
|
|
efeb86e5ce | ||
|
|
8e5c71c8f8 | ||
|
|
c0d7255256 | ||
|
|
c1ca14bb7b | ||
|
|
e1655545c1 | ||
|
|
2a58294d0c | ||
|
|
92ffa484b1 | ||
|
|
3698118d95 | ||
|
|
cfb7e25be1 | ||
|
|
5865234247 | ||
|
|
0cb99b2a12 | ||
|
|
4a01d86a5b | ||
|
|
1c7be1087d | ||
|
|
ac1baccba4 | ||
|
|
92451e3d46 | ||
|
|
a841c568fd | ||
|
|
5d1a72cb19 | ||
|
|
8889c6748f | ||
|
|
f4159a6d20 | ||
|
|
7164f75e01 | ||
|
|
44b8627225 | ||
|
|
054db1cac2 | ||
|
|
1317beb53a | ||
|
|
fabe7d52fe | ||
|
|
993f819e3d | ||
|
|
831e0d4070 | ||
|
|
bb2233aaa5 | ||
|
|
24ed2d0102 | ||
|
|
059f1aa99b | ||
|
|
5c5ac76dc6 | ||
|
|
a0f70ab98c | ||
|
|
5dcd27b0bc | ||
|
|
79735df611 | ||
|
|
a1105722ad | ||
|
|
131ac602dc | ||
|
|
c8cb48ba8b | ||
|
|
7bbfec324f | ||
|
|
6b7d951977 | ||
|
|
c7eaa2ec00 | ||
|
|
8807004b20 | ||
|
|
2d640ec739 | ||
|
|
53b5bae1f6 | ||
|
|
45c0959fcd | ||
|
|
d33a835564 | ||
|
|
347456b934 | ||
|
|
76a91b1af8 | ||
|
|
9d49fb8e98 | ||
|
|
10ad86dc12 | ||
|
|
71f0d4bd07 | ||
|
|
7669e56997 | ||
|
|
c8cf369c29 | ||
|
|
6ade6c061b | ||
|
|
843b5197ce | ||
|
|
a3d47e556c | ||
|
|
7261940ea5 | ||
|
|
8ada5b5558 | ||
|
|
62230c5409 | ||
|
|
51b6fb2610 | ||
|
|
c47b497cff | ||
|
|
975b958e4c | ||
|
|
13bccd131e | ||
|
|
daad66578a | ||
|
|
29c0c6cee8 | ||
|
|
5551aab1c3 | ||
|
|
9a46dbb681 | ||
|
|
8336fd394b | ||
|
|
51f68377c1 | ||
|
|
7a98346f51 | ||
|
|
8aad93f856 | ||
|
|
9d7c66c348 | ||
|
|
a1c7110c2a | ||
|
|
352338157c | ||
|
|
3569a93d9f | ||
|
|
985d576ba0 | ||
|
|
52dbd90938 | ||
|
|
d50c2980a5 | ||
|
|
b409ac80d1 | ||
|
|
4f53c95c39 | ||
|
|
bc0200672b | ||
|
|
3fdf140cf1 | ||
|
|
221e7bcc3b | ||
|
|
37b9e8b54a | ||
|
|
bedd981d16 | ||
|
|
422ae8cdee | ||
|
|
e3d81d9453 | ||
|
|
c7a4f4e270 | ||
|
|
55885b7a99 | ||
|
|
7a84008633 | ||
|
|
b8681684f4 | ||
|
|
908a1a8267 | ||
|
|
9e01770f11 | ||
|
|
9bdaa47c80 | ||
|
|
7621179156 | ||
|
|
81ca5f786c | ||
|
|
257d9b2a19 | ||
|
|
61ee7d7a72 | ||
|
|
3af4b91f2c | ||
|
|
fe319a6b7f | ||
|
|
20a4db787c | ||
|
|
80a21d447c | ||
|
|
4114018c87 | ||
|
|
a40afdb08e | ||
|
|
3c9d15de90 | ||
|
|
400e687804 | ||
|
|
8388fb6ff7 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.licenses/** -diff linguist-generated=true
|
||||
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* @actions/virtual-environments-owners
|
||||
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -2,22 +2,31 @@
|
||||
name: Bug report
|
||||
about: Create a bug report
|
||||
title: ''
|
||||
labels: ''
|
||||
labels: bug, needs triage
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
### Description
|
||||
**Description:**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
<!--
|
||||
* Please share short description of the problem
|
||||
-->
|
||||
**Task version:**
|
||||
Specify the task version
|
||||
|
||||
### Details
|
||||
**Platform:**
|
||||
- [ ] Ubuntu
|
||||
- [ ] macOS
|
||||
- [ ] Windows
|
||||
|
||||
<!--
|
||||
* Include the relevant yaml, platform, and dotnet versions in use
|
||||
* If an error occurred on a public action, please share a link
|
||||
* Include any error messages received in text (search does not work for images)
|
||||
* Was this a regression from previous behavior?
|
||||
-->
|
||||
**Runner type:**
|
||||
- [ ] Hosted
|
||||
- [ ] Self-hosted
|
||||
|
||||
**Repro steps:**
|
||||
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
|
||||
|
||||
**Expected behavior:**
|
||||
A description of what you expected to happen.
|
||||
|
||||
**Actual behavior:**
|
||||
A description of what is actually happening.
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: .NET issues
|
||||
url: https://github.com/dotnet/runtime#filing-issues
|
||||
|
||||
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: feature request, needs triage
|
||||
assignees: ''
|
||||
---
|
||||
|
||||
**Description:**
|
||||
Describe your proposal.
|
||||
|
||||
**Justification:**
|
||||
Justification or a use case for your proposal.
|
||||
|
||||
**Are you willing to submit a PR?**
|
||||
<!--- We accept contributions! -->
|
||||
9
.github/pull_request_template.md
vendored
Normal file
9
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
**Description:**
|
||||
Describe your changes.
|
||||
|
||||
**Related issue:**
|
||||
Add link to the related issue.
|
||||
|
||||
**Check list:**
|
||||
- [ ] Mark if documentation changes are required.
|
||||
- [ ] Mark if tests were added or updated to cover the changes.
|
||||
20
.github/workflows/licensed.yml
vendored
Normal file
20
.github/workflows/licensed.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: Licensed
|
||||
|
||||
on:
|
||||
push: {branches: main}
|
||||
pull_request: {branches: main}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check licenses
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: npm ci
|
||||
- name: Install licensed
|
||||
run: |
|
||||
cd $RUNNER_TEMP
|
||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
||||
sudo tar -xzf licensed.tar.gz
|
||||
sudo mv licensed /usr/local/bin/licensed
|
||||
- run: licensed status
|
||||
37
.github/workflows/test-dotnet.yml
vendored
Normal file
37
.github/workflows/test-dotnet.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Validate dotnet
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- releases/*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
setup-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
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
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet ${{ matrix.dotnet-version }}
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet-version }}
|
||||
- name: Check installed version
|
||||
shell: pwsh
|
||||
run: |
|
||||
$version = & dotnet --version
|
||||
Write-Host "Installed version: $version"
|
||||
if (-not $version.StartsWith("${{ matrix.dotnet-version }}")) { throw "Unexpected version" }
|
||||
143
.github/workflows/workflow.yml
vendored
143
.github/workflows/workflow.yml
vendored
@@ -2,15 +2,20 @@ name: Main workflow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- releases/*
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
@@ -19,7 +24,7 @@ jobs:
|
||||
- name: Set Node.js 12
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
version: 12.x
|
||||
node-version: 12.x
|
||||
- run: npm ci
|
||||
- run: npm run build
|
||||
- run: npm run format-check
|
||||
@@ -28,26 +33,111 @@ jobs:
|
||||
if: runner.os != 'windows'
|
||||
run: __tests__/verify-no-unstaged-changes.sh
|
||||
|
||||
test:
|
||||
test-setup-full-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@v2
|
||||
- name: Clear tool cache
|
||||
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
||||
- name: Setup dotnet 3.0.100
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
# Side-by-side install of 2.2 and 3.1 used for the test project
|
||||
- name: Setup dotnet 2.2.402
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.0.100
|
||||
dotnet-version: 2.2.402
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.201
|
||||
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify nuget config file
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-Not (Test-Path "../nuget.config")) { throw "nuget file not generated correctly" }
|
||||
- name: Verify dotnet
|
||||
if: runner.os != 'windows'
|
||||
run: __tests__/verify-dotnet.sh 3.0.100
|
||||
- name: Verify dotnet (Windows)
|
||||
if: runner.os == 'windows'
|
||||
run: __tests__/verify-dotnet.ps1 3.0.100
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1.201 2.2.402
|
||||
|
||||
test-setup-without-patch-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
# 2.0, 3.0, 5.0 needs to be in single quotes to interpret as a string instead of as an integer
|
||||
- name: Setup dotnet '3.1'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '3.1'
|
||||
- name: Setup dotnet '2.2'
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: '2.2'
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
test-setup-latest-patch-version:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet 3.1.x
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
- name: Setup dotnet 2.2.x
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 2.2.x
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
test-setup-with-wildcard:
|
||||
runs-on: ${{ matrix.operating-system }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Clear toolcache
|
||||
shell: pwsh
|
||||
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||
- name: Setup dotnet 3.1.*
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.1.*
|
||||
- name: Setup dotnet 2.2.*
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 2.2.*
|
||||
- name: Verify dotnet
|
||||
shell: pwsh
|
||||
run: __tests__/verify-dotnet.ps1 3.1 2.2
|
||||
|
||||
test-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -61,31 +151,42 @@ jobs:
|
||||
- 3128:3128
|
||||
env:
|
||||
https_proxy: http://squid-proxy:3128
|
||||
http_proxy: http://squid-proxy:3128
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Clear tool cache
|
||||
run: rm -rf $RUNNER_TOOL_CACHE/*
|
||||
- name: Setup dotnet 3.0.100
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Install curl
|
||||
run: |
|
||||
apt update
|
||||
apt -y install curl
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.0.100
|
||||
dotnet-version: 3.1.201
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify dotnet
|
||||
run: __tests__/verify-dotnet.sh 3.0.100
|
||||
run: __tests__/verify-dotnet.sh 3.1.201
|
||||
|
||||
test-bypass-proxy:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
https_proxy: http://no-such-proxy:3128
|
||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org
|
||||
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
|
||||
- name: Clear tool cache
|
||||
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
||||
- name: Setup dotnet 3.0.100
|
||||
run: rm -rf "/usr/share/dotnet"
|
||||
- name: Setup dotnet 3.1.201
|
||||
uses: ./
|
||||
with:
|
||||
dotnet-version: 3.0.100
|
||||
dotnet-version: 3.1.201
|
||||
source-url: https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||
- name: Verify dotnet
|
||||
run: __tests__/verify-dotnet.sh 3.0.100
|
||||
run: __tests__/verify-dotnet.sh 3.1.201
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -95,4 +95,5 @@ typings/
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
.vscode/*
|
||||
# Ignore .vscode files
|
||||
.vscode/
|
||||
14
.licensed.yml
Normal file
14
.licensed.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
sources:
|
||||
npm: true
|
||||
|
||||
allowed:
|
||||
- apache-2.0
|
||||
- bsd-2-clause
|
||||
- bsd-3-clause
|
||||
- isc
|
||||
- mit
|
||||
- cc0-1.0
|
||||
- unlicense
|
||||
|
||||
reviewed:
|
||||
npm:
|
||||
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
Normal file
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/once.dep.yml
generated
Normal file
BIN
.licenses/npm/once.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-6.3.0.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-6.3.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/which.dep.yml
generated
Normal file
BIN
.licenses/npm/which.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
Normal file
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
Normal file
Binary file not shown.
53
README.md
53
README.md
@@ -10,6 +10,12 @@ This action sets up a [dotnet core cli](https://github.com/dotnet/cli) environme
|
||||
- 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
|
||||
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
|
||||
|
||||
See [action.yml](action.yml)
|
||||
@@ -17,24 +23,35 @@ See [action.yml](action.yml)
|
||||
Basic:
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.x' # SDK Version to use; x will use the latest version of the 3.1 channel
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
|
||||
Preview version:
|
||||
```yml
|
||||
steps:
|
||||
- uses: actions@checkout@v2
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '6.0.x'
|
||||
include-prerelease: true
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
|
||||
Matrix Testing:
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-16.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dotnet: [ '2.2.103', '3.0', '3.1.x' ]
|
||||
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
|
||||
name: Dotnet ${{ matrix.dotnet }} sample
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
@@ -42,10 +59,30 @@ jobs:
|
||||
- run: dotnet build <my project>
|
||||
```
|
||||
|
||||
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
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
# Authenticates packages to push to GPR
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
@@ -78,16 +115,16 @@ Some environment variables may be necessary for your particular case or to impro
|
||||
- DOTNET_MULTILEVEL_LOOKUP - configures whether the global install location is used as a fall-back (default: true)
|
||||
|
||||
Example usage:
|
||||
```
|
||||
```yaml
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
DOTNET_NOLOGO: true
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@main
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '3.1.100' # SDK Version to use.
|
||||
dotnet-version: '3.1.x' # SDK Version to use.
|
||||
```
|
||||
|
||||
# License
|
||||
|
||||
@@ -75,14 +75,17 @@ const azureartifactsnugetorgNuGetConfig: string = `<?xml version="1.0" encoding=
|
||||
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
||||
|
||||
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
||||
process.env['RUNNER_TEMP'] = fakeSourcesDirForTesting;
|
||||
import * as auth from '../src/authutil';
|
||||
|
||||
describe('authutil tests', () => {
|
||||
beforeEach(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
await io.mkdirP(fakeSourcesDirForTesting);
|
||||
}, 100000);
|
||||
}, 30000);
|
||||
|
||||
afterAll(async () => {
|
||||
await io.rmRF(fakeSourcesDirForTesting);
|
||||
}, 30000);
|
||||
|
||||
beforeEach(() => {
|
||||
if (fs.existsSync(nugetConfigFile)) {
|
||||
@@ -95,7 +98,9 @@ describe('authutil tests', () => {
|
||||
it('No existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -107,7 +112,9 @@ describe('authutil tests', () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
@@ -119,7 +126,9 @@ describe('authutil tests', () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
process.env['INPUT_OWNER'] = 'otherorg';
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/otherorg/index.json'
|
||||
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -137,7 +146,9 @@ describe('authutil tests', () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
@@ -153,7 +164,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -169,7 +182,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -185,7 +200,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -201,7 +218,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -216,7 +235,11 @@ describe('authutil tests', () => {
|
||||
'nuget.config'
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||
await auth.configAuthentication('https://nuget.pkg.github.com');
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||
@@ -233,7 +256,9 @@ describe('authutil tests', () => {
|
||||
let thrown = false;
|
||||
try {
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
} catch {
|
||||
thrown = true;
|
||||
@@ -255,7 +280,8 @@ describe('authutil tests', () => {
|
||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||
'subfolder/nuget.config'
|
||||
'subfolder/nuget.config',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -271,7 +297,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json'
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -287,7 +315,9 @@ describe('authutil tests', () => {
|
||||
);
|
||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json'
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
@@ -298,7 +328,9 @@ describe('authutil tests', () => {
|
||||
it('No existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||
await auth.configAuthentication(
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json'
|
||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||
'',
|
||||
fakeSourcesDirForTesting
|
||||
);
|
||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||
expect(
|
||||
|
||||
13
__tests__/clear-toolcache.ps1
Normal file
13
__tests__/clear-toolcache.ps1
Normal file
@@ -0,0 +1,13 @@
|
||||
$dotnetPaths = @{
|
||||
Linux = @("/usr/share/dotnet")
|
||||
macOS = @("$env:HOME/.dotnet")
|
||||
Windows = @("$env:ProgramFiles\dotnet/*",
|
||||
"$env:LocalAppData\Microsoft\dotnet/*")
|
||||
}
|
||||
|
||||
foreach ($path in $dotnetPaths[$args[0]]) {
|
||||
if (Test-Path $path) {
|
||||
Write-Host "Clear $path path"
|
||||
Remove-Item $path -Recurse -Force
|
||||
}
|
||||
}
|
||||
@@ -4,75 +4,21 @@ import os = require('os');
|
||||
import path = require('path');
|
||||
import hc = require('@actions/http-client');
|
||||
|
||||
import each from 'jest-each';
|
||||
|
||||
const toolDir = path.join(__dirname, 'runner', 'tools');
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||
|
||||
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||
process.env['RUNNER_TEMP'] = tempDir;
|
||||
import * as setup from '../src/setup-dotnet';
|
||||
import * as installer from '../src/installer';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
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.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',
|
||||
'2.x',
|
||||
'*.*.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();
|
||||
});
|
||||
});
|
||||
|
||||
describe('installer 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);
|
||||
});
|
||||
@@ -84,83 +30,40 @@ describe('installer tests', () => {
|
||||
} catch {
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 100000);
|
||||
|
||||
it('Resolving a normal generic version works', async () => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.x');
|
||||
let versInfo = await dotnetInstaller.resolveInfos(
|
||||
['win-x64'],
|
||||
new installer.DotNetVersionInfo('3.1.x')
|
||||
);
|
||||
|
||||
expect(versInfo.resolvedVersion.startsWith('3.1.'));
|
||||
}, 100000);
|
||||
|
||||
it('Resolving a nonexistent generic version fails', async () => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
|
||||
try {
|
||||
await dotnetInstaller.resolveInfos(
|
||||
['win-x64'],
|
||||
new installer.DotNetVersionInfo('999.1.x')
|
||||
);
|
||||
fail();
|
||||
} catch {
|
||||
expect(true);
|
||||
}
|
||||
}, 100000);
|
||||
|
||||
it('Resolving a exact stable version works', async () => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.201');
|
||||
let versInfo = await dotnetInstaller.resolveInfos(
|
||||
['win-x64'],
|
||||
new installer.DotNetVersionInfo('3.1.201')
|
||||
);
|
||||
|
||||
expect(versInfo.resolvedVersion).toBe('3.1.201');
|
||||
}, 100000);
|
||||
|
||||
it('Resolving a exact preview version works', async () => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
'5.0.0-preview.4'
|
||||
);
|
||||
let versInfo = await dotnetInstaller.resolveInfos(
|
||||
['win-x64'],
|
||||
new installer.DotNetVersionInfo('5.0.0-preview.4')
|
||||
);
|
||||
|
||||
expect(versInfo.resolvedVersion).toBe('5.0.0-preview.4');
|
||||
}, 100000);
|
||||
}, 30000);
|
||||
|
||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
||||
await getDotnet('2.2.205');
|
||||
const dotnetDir = path.join(toolDir, 'dncs', '2.2.205', os.arch());
|
||||
|
||||
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true);
|
||||
await getDotnet('3.1.201');
|
||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
||||
if (IS_WINDOWS) {
|
||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
}, 400000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
||||
const dotnetDir = path.join(toolDir, 'dncs', '2.2.105', os.arch());
|
||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||
expect(process.env.PATH).toBeDefined;
|
||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "2.2.105"${os.EOL}}${os.EOL}}`;
|
||||
if (!fs.existsSync(globalJsonPath)) {
|
||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||
}
|
||||
await setup.run();
|
||||
|
||||
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true);
|
||||
it('Acquires generic version of dotnet if no matching version is installed', async () => {
|
||||
await getDotnet('3.1');
|
||||
var directory = fs
|
||||
.readdirSync(path.join(toolDir, 'sdk'))
|
||||
.filter(fn => fn.startsWith('3.1.'));
|
||||
expect(directory.length > 0).toBe(true);
|
||||
if (IS_WINDOWS) {
|
||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true);
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
fs.unlinkSync(globalJsonPath);
|
||||
}, 100000);
|
||||
|
||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||
expect(process.env.PATH).toBeDefined;
|
||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||
}, 600000); //This needs some time to download on "slower" internet connections
|
||||
|
||||
it('Throws if no location contains correct dotnet version', async () => {
|
||||
let thrown = false;
|
||||
@@ -170,30 +73,7 @@ describe('installer tests', () => {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
}, 100000);
|
||||
|
||||
it('Uses version of dotnet installed in cache', async () => {
|
||||
const dotnetDir: string = path.join(toolDir, 'dncs', '250.0.0', os.arch());
|
||||
await io.mkdirP(dotnetDir);
|
||||
fs.writeFileSync(`${dotnetDir}.complete`, 'hello');
|
||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
||||
await getDotnet('250.0.0');
|
||||
return;
|
||||
});
|
||||
|
||||
it('Doesnt use version of dotnet that was only partially installed in cache', async () => {
|
||||
const dotnetDir: string = path.join(toolDir, 'dncs', '251.0.0', os.arch());
|
||||
await io.mkdirP(dotnetDir);
|
||||
let thrown = false;
|
||||
try {
|
||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
||||
await getDotnet('251.0.0');
|
||||
} catch {
|
||||
thrown = true;
|
||||
}
|
||||
expect(thrown).toBe(true);
|
||||
return;
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
it('Uses an up to date bash download script', async () => {
|
||||
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||
@@ -213,7 +93,7 @@ describe('installer tests', () => {
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
}, 100000);
|
||||
}, 30000);
|
||||
|
||||
it('Uses an up to date powershell download script', async () => {
|
||||
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||
@@ -233,7 +113,7 @@ describe('installer tests', () => {
|
||||
expect(normalizeFileContents(currentContents)).toBe(
|
||||
normalizeFileContents(upToDateContents)
|
||||
);
|
||||
}, 100000);
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
function normalizeFileContents(contents: string): string {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
|
||||
namespace sample_csproj
|
||||
{
|
||||
class Program
|
||||
[TestClass]
|
||||
public class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
[TestMethod]
|
||||
public void TestMethod1()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(new[] {"Hello", "World!" });
|
||||
Console.WriteLine(json);
|
||||
Console.WriteLine("Hello, World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"configProperties": {
|
||||
"System.Globalization.Invariant": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<TargetFrameworks>netcoreapp3.1;netcoreapp2.2</TargetFrameworks>
|
||||
<RootNamespace>sample_csproj</RootNamespace>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<!-- These packages will be downloaded over the network for testing proxy settings -->
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
47
__tests__/setup-dotnet.test.ts
Normal file
47
__tests__/setup-dotnet.test.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import io = require('@actions/io');
|
||||
import fs = require('fs');
|
||||
import os = require('os');
|
||||
import path = require('path');
|
||||
|
||||
const toolDir = path.join(__dirname, 'runner', 'tools2');
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||
|
||||
import * as setup from '../src/setup-dotnet';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
describe('setup-dotnet tests', () => {
|
||||
beforeAll(async () => {
|
||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||
process.env.RUNNER_TEMP = tempDir;
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
try {
|
||||
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
||||
await io.rmRF(toolDir);
|
||||
await io.rmRF(tempDir);
|
||||
} catch {
|
||||
console.log('Failed to remove test directories');
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
it('Acquires version of dotnet from global.json if no matching version is installed', async () => {
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.1.201"${os.EOL}}${os.EOL}}`;
|
||||
if (!fs.existsSync(globalJsonPath)) {
|
||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||
}
|
||||
await setup.run();
|
||||
|
||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
||||
if (IS_WINDOWS) {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
}, 400000);
|
||||
});
|
||||
@@ -8,13 +8,32 @@ Write-Host "Found '$dotnet'"
|
||||
|
||||
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
|
||||
Write-Host "Version $version"
|
||||
# if ($version -ne $args[0])
|
||||
# {
|
||||
# Write-Host "PATH='$env:path'"
|
||||
# Write-Host "gcm dotnet:"
|
||||
# gcm dotnet | fl
|
||||
# throw "Unexpected version"
|
||||
# }
|
||||
if (-not ($version.StartsWith($args[0].ToString())))
|
||||
{
|
||||
Write-Host "PATH='$env:PATH'"
|
||||
throw "Unexpected version"
|
||||
}
|
||||
|
||||
if ($args[1])
|
||||
{
|
||||
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
||||
$versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
||||
Write-Host "Installed versions: $versions"
|
||||
$isInstalledVersion = $false
|
||||
foreach ($version in $versions)
|
||||
{
|
||||
if ($version.StartsWith($args[1].ToString()))
|
||||
{
|
||||
$isInstalledVersion = $true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (-not $isInstalledVersion)
|
||||
{
|
||||
Write-Host "PATH='$env:PATH'"
|
||||
throw "Unexpected version"
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Building sample csproj"
|
||||
& $dotnet build __tests__/sample-csproj/ --no-cache
|
||||
@@ -24,9 +43,20 @@ if ($LASTEXITCODE -ne 0)
|
||||
}
|
||||
|
||||
Write-Host "Testing compiled app"
|
||||
$sample_output = "$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample.exe)".Trim()
|
||||
$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
|
||||
Write-Host "Sample output: $sample_output"
|
||||
if ($sample_output -notlike "*Hello*World*")
|
||||
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
||||
if ($args[1])
|
||||
{
|
||||
throw "Unexpected output"
|
||||
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
|
||||
{
|
||||
throw "Unexpected output"
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($sample_output -notlike "*Test Run Successful.*")
|
||||
{
|
||||
throw "Unexpected output"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@ if [ -z "$1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "../nuget.config" ]; then
|
||||
echo "nuget file not generated correctly"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dotnet_version="$(dotnet --version)"
|
||||
echo "Found dotnet version '$dotnet_version'"
|
||||
if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
||||
@@ -10,13 +15,30 @@ if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
dotnet_version="$(dotnet --list-sdks)"
|
||||
echo "Found dotnet version '$dotnet_version'"
|
||||
if [ -z "$(echo $dotnet_version | grep $2)" ]; then
|
||||
echo "Unexpected version"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Building sample csproj"
|
||||
dotnet build __tests__/sample-csproj/ --no-cache || exit 1
|
||||
|
||||
echo "Testing compiled app"
|
||||
sample_output="$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample)"
|
||||
sample_output=$(dotnet test __tests__/sample-csproj/ --no-build)
|
||||
echo "Sample output: $sample_output"
|
||||
if [ -z "$(echo $sample_output | grep Hello)" ]; then
|
||||
echo "Unexpected output"
|
||||
exit 1
|
||||
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
||||
if [ -n "$2" ]; then
|
||||
if [ -z "$(echo $sample_output | grep "Test Run Successful.*Test Run Successful.")" ]; then
|
||||
echo "Unexpected output"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then
|
||||
echo "Unexpected output"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
91
__tests__/versionutil.test.ts
Normal file
91
__tests__/versionutil.test.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import each from 'jest-each';
|
||||
import * as installer from '../src/installer';
|
||||
|
||||
describe('version tests', () => {
|
||||
each(['3.1.999', '3.1.101-preview.3']).test(
|
||||
"Exact version '%s' should be the same",
|
||||
vers => {
|
||||
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||
|
||||
expect(versInfo.isExactVersion()).toBe(true);
|
||||
expect(versInfo.version()).toBe(vers);
|
||||
}
|
||||
);
|
||||
|
||||
each([
|
||||
['3.x', '3.x'],
|
||||
['3.*', '3.*'],
|
||||
['3.1.x', '3.1'],
|
||||
['1.1.*', '1.1'],
|
||||
['2.0', '2.0']
|
||||
]).test("Generic version '%s' should be '%s'", (vers, resVers) => {
|
||||
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||
|
||||
expect(versInfo.isExactVersion()).toBe(false);
|
||||
expect(versInfo.version()).toBe(resVers);
|
||||
});
|
||||
|
||||
each([
|
||||
'',
|
||||
'.',
|
||||
'..',
|
||||
' . ',
|
||||
'. ',
|
||||
' .',
|
||||
' . . ',
|
||||
' .. ',
|
||||
' . ',
|
||||
'-1.-1',
|
||||
'-1',
|
||||
'-1.-1.-1',
|
||||
'..3',
|
||||
'1..3',
|
||||
'1..',
|
||||
'.2.3',
|
||||
'.2.x',
|
||||
'1',
|
||||
'*.*.1',
|
||||
'*.1',
|
||||
'*.',
|
||||
'1.2.',
|
||||
'1.2.-abc',
|
||||
'a.b',
|
||||
'a.b.c',
|
||||
'a.b.c-preview',
|
||||
' 0 . 1 . 2 '
|
||||
]).test("Malformed version '%s' should throw", vers => {
|
||||
expect(() => new installer.DotNetVersionInfo(vers)).toThrow();
|
||||
});
|
||||
|
||||
each([
|
||||
['3.1.x', '3.1.'],
|
||||
['3.1.*', '3.1.'],
|
||||
['3.1', '3.1.'],
|
||||
['5.0.0-preview.6', '5.0.0-preview.6'],
|
||||
['3.1.201', '3.1.201']
|
||||
]).test(
|
||||
"Resolving version '%s' as '%s'",
|
||||
async (input, expectedVersion) => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(input);
|
||||
let versInfo = await dotnetInstaller.resolveVersion(
|
||||
new installer.DotNetVersionInfo(input)
|
||||
);
|
||||
console.log(versInfo);
|
||||
|
||||
expect(versInfo.startsWith(expectedVersion));
|
||||
},
|
||||
100000
|
||||
);
|
||||
|
||||
it('Resolving a nonexistent generic version fails', async () => {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
|
||||
try {
|
||||
await dotnetInstaller.resolveVersion(
|
||||
new installer.DotNetVersionInfo('999.1.x')
|
||||
);
|
||||
fail();
|
||||
} catch {
|
||||
expect(true);
|
||||
}
|
||||
}, 100000);
|
||||
});
|
||||
11
action.yml
11
action.yml
@@ -4,19 +4,18 @@ author: 'GitHub'
|
||||
branding:
|
||||
icon: play
|
||||
color: green
|
||||
inputs:
|
||||
inputs:
|
||||
dotnet-version:
|
||||
description: 'SDK version to use. Examples: 2.2.104, 3.1, 3.1.x'
|
||||
description: 'Optional SDK version to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x'
|
||||
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.'
|
||||
# Deprecated option, do not use. Will not be supported after October 1, 2019
|
||||
version:
|
||||
description: 'Deprecated. Use dotnet-version instead. Will not be supported after October 1, 2019'
|
||||
deprecationMessage: 'The version property will not be supported after October 1, 2019. Use dotnet-version instead'
|
||||
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
|
||||
runs:
|
||||
using: 'node12'
|
||||
main: 'dist/index.js'
|
||||
|
||||
2280
dist/index.js
vendored
2280
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,34 @@
|
||||
# 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.
|
||||
|
||||
# Checkin
|
||||
If you would like to contribute there are a few things to consider:
|
||||
|
||||
- Do checkin source (src)
|
||||
- Do checkin build output (lib)
|
||||
- Do checkin runtime node_modules
|
||||
- Do not checkin
|
||||
## Commands to use
|
||||
|
||||
# Adding a dev dependency
|
||||
- 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)
|
||||
|
||||
Remember to update .gitignore.
|
||||
## To check in or not to check in
|
||||
|
||||
# Updating toolkit dependency
|
||||
- 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)
|
||||
|
||||
Until released publically, update tgz packages in toolkit
|
||||
## Writing tests
|
||||
|
||||
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.
|
||||
|
||||
## Creating new version
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
192
externals/get-os-distro.sh
vendored
192
externals/get-os-distro.sh
vendored
@@ -1,192 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
#
|
||||
|
||||
# Stop script on NZEC
|
||||
set -e
|
||||
# Stop script if unbound variable found (use ${var:-} if intentional)
|
||||
set -u
|
||||
# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
|
||||
# This is causing it to fail
|
||||
set -o pipefail
|
||||
|
||||
# Use in the the functions: eval $invocation
|
||||
invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
|
||||
|
||||
# standard output may be used as a return value in the functions
|
||||
# we need a way to write text on the screen in the functions so that
|
||||
# it won't interfere with the return value.
|
||||
# Exposing stream 3 as a pipe to standard output of the script itself
|
||||
exec 3>&1
|
||||
|
||||
say_err() {
|
||||
printf "%b\n" "get-os-distro: Error: $1" >&2
|
||||
}
|
||||
|
||||
# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
|
||||
# then and only then should the Linux distribution appear in this list.
|
||||
# Adding a Linux distribution to this list does not imply distribution-specific support.
|
||||
get_legacy_os_name_from_platform() {
|
||||
|
||||
platform="$1"
|
||||
case "$platform" in
|
||||
"centos.7")
|
||||
echo "centos"
|
||||
return 0
|
||||
;;
|
||||
"debian.8")
|
||||
echo "debian"
|
||||
return 0
|
||||
;;
|
||||
"fedora.23")
|
||||
echo "fedora.23"
|
||||
return 0
|
||||
;;
|
||||
"fedora.27")
|
||||
echo "fedora.27"
|
||||
return 0
|
||||
;;
|
||||
"fedora.24")
|
||||
echo "fedora.24"
|
||||
return 0
|
||||
;;
|
||||
"opensuse.13.2")
|
||||
echo "opensuse.13.2"
|
||||
return 0
|
||||
;;
|
||||
"opensuse.42.1")
|
||||
echo "opensuse.42.1"
|
||||
return 0
|
||||
;;
|
||||
"opensuse.42.3")
|
||||
echo "opensuse.42.3"
|
||||
return 0
|
||||
;;
|
||||
"rhel.7"*)
|
||||
echo "rhel"
|
||||
return 0
|
||||
;;
|
||||
"ubuntu.14.04")
|
||||
echo "ubuntu"
|
||||
return 0
|
||||
;;
|
||||
"ubuntu.16.04")
|
||||
echo "ubuntu.16.04"
|
||||
return 0
|
||||
;;
|
||||
"ubuntu.16.10")
|
||||
echo "ubuntu.16.10"
|
||||
return 0
|
||||
;;
|
||||
"ubuntu.18.04")
|
||||
echo "ubuntu.18.04"
|
||||
return 0
|
||||
;;
|
||||
"alpine.3.4.3")
|
||||
echo "alpine"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
get_linux_platform_name() {
|
||||
|
||||
if [ -e /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
echo "$ID.$VERSION_ID"
|
||||
return 0
|
||||
elif [ -e /etc/redhat-release ]; then
|
||||
local redhatRelease=$(</etc/redhat-release)
|
||||
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]; then
|
||||
echo "rhel.6"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
say_err "Linux specific platform name and version could not be detected: UName = $uname"
|
||||
return 1
|
||||
}
|
||||
|
||||
get_current_os_name() {
|
||||
|
||||
local uname=$(uname)
|
||||
if [ "$uname" = "Darwin" ]; then
|
||||
echo "osx"
|
||||
return 0
|
||||
elif [ "$uname" = "Linux" ]; then
|
||||
local linux_platform_name
|
||||
linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; }
|
||||
|
||||
if [[ $linux_platform_name == "rhel.6" ]]; then
|
||||
echo "$linux_platform_name"
|
||||
return 0
|
||||
elif [[ $linux_platform_name == alpine* ]]; then
|
||||
echo "linux-musl"
|
||||
return 0
|
||||
else
|
||||
echo "linux"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
say_err "OS name could not be detected: UName = $uname"
|
||||
return 1
|
||||
}
|
||||
|
||||
get_legacy_os_name() {
|
||||
|
||||
local uname=$(uname)
|
||||
if [ "$uname" = "Darwin" ]; then
|
||||
echo "osx"
|
||||
return 0
|
||||
else
|
||||
if [ -e /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
os=$(get_legacy_os_name_from_platform "$ID.$VERSION_ID" || echo "")
|
||||
if [ -n "$os" ]; then
|
||||
echo "$os"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
say_err "Distribution specific OS name and version could not be detected: UName = $uname"
|
||||
return 1
|
||||
}
|
||||
|
||||
get_machine_architecture() {
|
||||
|
||||
if command -v uname > /dev/null; then
|
||||
CPUName=$(uname -m)
|
||||
case $CPUName in
|
||||
armv7l)
|
||||
echo "arm"
|
||||
return 0
|
||||
;;
|
||||
aarch64)
|
||||
echo "arm64"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Always default to 'x64'
|
||||
echo "x64"
|
||||
return 0
|
||||
}
|
||||
|
||||
osName=$(get_current_os_name || echo "")
|
||||
legacyOsName=$(get_legacy_os_name || echo "")
|
||||
arch=$(get_machine_architecture || echo "")
|
||||
|
||||
primaryName="$osName-$arch"
|
||||
legacyName="$legacyOsName"
|
||||
|
||||
echo "Primary:$primaryName"
|
||||
echo "Legacy:$legacyName"
|
||||
|
||||
if [ -z "$osName" ] && [ -z "$legacyOsName" ];then
|
||||
exit 1
|
||||
fi
|
||||
18
externals/get-os-platform.ps1
vendored
18
externals/get-os-platform.ps1
vendored
@@ -1,18 +0,0 @@
|
||||
function Get-Machine-Architecture()
|
||||
{
|
||||
# possible values: AMD64, IA64, x86
|
||||
return $ENV:PROCESSOR_ARCHITECTURE
|
||||
}
|
||||
|
||||
function Get-CLIArchitecture-From-Architecture([string]$Architecture)
|
||||
{
|
||||
switch ($Architecture.ToLower())
|
||||
{
|
||||
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
|
||||
{ $_ -eq "x86" } { return "x86" }
|
||||
default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" }
|
||||
}
|
||||
}
|
||||
|
||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture)
|
||||
Write-Output "Primary:win-$CLIArchitecture"
|
||||
552
externals/install-dotnet.ps1
vendored
552
externals/install-dotnet.ps1
vendored
@@ -23,8 +23,6 @@
|
||||
Default: latest
|
||||
Represents a build version on specific channel. Possible values:
|
||||
- latest - most latest build on specific channel
|
||||
- coherent - most latest coherent build on specific channel
|
||||
coherent applies only to SDK downloads
|
||||
- 3-part version in a format A.B.C - represents specific version of build
|
||||
examples: 2.0.0-preview2-006120, 1.1.0
|
||||
.PARAMETER InstallDir
|
||||
@@ -69,6 +67,8 @@
|
||||
.PARAMETER ProxyUseDefaultCredentials
|
||||
Default: false
|
||||
Use default credentials, when using proxy address.
|
||||
.PARAMETER ProxyBypassList
|
||||
If set with ProxyAddress, will provide the list of comma separated urls that will bypass the proxy
|
||||
.PARAMETER SkipNonVersionedFiles
|
||||
Default: false
|
||||
Skips installing non-versioned files if they already exist, such as dotnet.exe.
|
||||
@@ -96,6 +96,7 @@ param(
|
||||
[string]$FeedCredential,
|
||||
[string]$ProxyAddress,
|
||||
[switch]$ProxyUseDefaultCredentials,
|
||||
[string[]]$ProxyBypassList=@(),
|
||||
[switch]$SkipNonVersionedFiles,
|
||||
[switch]$NoCdn
|
||||
)
|
||||
@@ -119,11 +120,45 @@ $VersionRegEx="/\d+\.\d+[^/]+/"
|
||||
$OverrideNonVersionedFiles = !$SkipNonVersionedFiles
|
||||
|
||||
function Say($str) {
|
||||
Write-Host "dotnet-install: $str"
|
||||
try {
|
||||
Write-Host "dotnet-install: $str"
|
||||
}
|
||||
catch {
|
||||
# Some platforms cannot utilize Write-Host (Azure Functions, for instance). Fall back to Write-Output
|
||||
Write-Output "dotnet-install: $str"
|
||||
}
|
||||
}
|
||||
|
||||
function Say-Warning($str) {
|
||||
try {
|
||||
Write-Warning "dotnet-install: $str"
|
||||
}
|
||||
catch {
|
||||
# Some platforms cannot utilize Write-Warning (Azure Functions, for instance). Fall back to Write-Output
|
||||
Write-Output "dotnet-install: Warning: $str"
|
||||
}
|
||||
}
|
||||
|
||||
# Writes a line with error style settings.
|
||||
# Use this function to show a human-readable comment along with an exception.
|
||||
function Say-Error($str) {
|
||||
try {
|
||||
# Write-Error is quite oververbose for the purpose of the function, let's write one line with error style settings.
|
||||
$Host.UI.WriteErrorLine("dotnet-install: $str")
|
||||
}
|
||||
catch {
|
||||
Write-Output "dotnet-install: Error: $str"
|
||||
}
|
||||
}
|
||||
|
||||
function Say-Verbose($str) {
|
||||
Write-Verbose "dotnet-install: $str"
|
||||
try {
|
||||
Write-Verbose "dotnet-install: $str"
|
||||
}
|
||||
catch {
|
||||
# Some platforms cannot utilize Write-Verbose (Azure Functions, for instance). Fall back to Write-Output
|
||||
Write-Output "dotnet-install: $str"
|
||||
}
|
||||
}
|
||||
|
||||
function Say-Invocation($Invocation) {
|
||||
@@ -137,7 +172,7 @@ function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [in
|
||||
|
||||
while ($true) {
|
||||
try {
|
||||
return $ScriptBlock.Invoke()
|
||||
return & $ScriptBlock
|
||||
}
|
||||
catch {
|
||||
$Attempts++
|
||||
@@ -154,7 +189,16 @@ function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [in
|
||||
function Get-Machine-Architecture() {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
# possible values: amd64, x64, x86, arm64, arm
|
||||
# On PS x86, PROCESSOR_ARCHITECTURE reports x86 even on x64 systems.
|
||||
# To get the correct architecture, we need to use PROCESSOR_ARCHITEW6432.
|
||||
# PS x64 doesn't define this, so we fall back to PROCESSOR_ARCHITECTURE.
|
||||
# Possible values: amd64, x64, x86, arm64, arm
|
||||
|
||||
if( $ENV:PROCESSOR_ARCHITEW6432 -ne $null )
|
||||
{
|
||||
return $ENV:PROCESSOR_ARCHITEW6432
|
||||
}
|
||||
|
||||
return $ENV:PROCESSOR_ARCHITECTURE
|
||||
}
|
||||
|
||||
@@ -167,7 +211,7 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
||||
{ $_ -eq "x86" } { return "x86" }
|
||||
{ $_ -eq "arm" } { return "arm" }
|
||||
{ $_ -eq "arm64" } { return "arm64" }
|
||||
default { throw "Architecture not supported. If you think this is a bug, report it at https://github.com/dotnet/sdk/issues" }
|
||||
default { throw "Architecture '$Architecture' not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +272,11 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
|
||||
if($ProxyAddress) {
|
||||
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
|
||||
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{Address=$ProxyAddress;UseDefaultCredentials=$ProxyUseDefaultCredentials}
|
||||
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{
|
||||
Address=$ProxyAddress;
|
||||
UseDefaultCredentials=$ProxyUseDefaultCredentials;
|
||||
BypassList = $ProxyBypassList;
|
||||
}
|
||||
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
||||
}
|
||||
else {
|
||||
@@ -238,18 +286,41 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
# Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out
|
||||
# 20 minutes allows it to work over much slower connections.
|
||||
$HttpClient.Timeout = New-TimeSpan -Minutes 20
|
||||
$Response = $HttpClient.GetAsync("${Uri}${FeedCredential}").Result
|
||||
if (($Response -eq $null) -or (-not ($Response.IsSuccessStatusCode))) {
|
||||
# The feed credential is potentially sensitive info. Do not log FeedCredential to console output.
|
||||
$ErrorMsg = "Failed to download $Uri."
|
||||
if ($Response -ne $null) {
|
||||
$ErrorMsg += " $Response"
|
||||
$Task = $HttpClient.GetAsync("${Uri}${FeedCredential}").ConfigureAwait("false");
|
||||
$Response = $Task.GetAwaiter().GetResult();
|
||||
|
||||
if (($null -eq $Response) -or (-not ($Response.IsSuccessStatusCode))) {
|
||||
# The feed credential is potentially sensitive info. Do not log FeedCredential to console output.
|
||||
$DownloadException = [System.Exception] "Unable to download $Uri."
|
||||
|
||||
if ($null -ne $Response) {
|
||||
$DownloadException.Data["StatusCode"] = [int] $Response.StatusCode
|
||||
$DownloadException.Data["ErrorMessage"] = "Unable to download $Uri. Returned HTTP status code: " + $DownloadException.Data["StatusCode"]
|
||||
}
|
||||
|
||||
throw $ErrorMsg
|
||||
throw $DownloadException
|
||||
}
|
||||
|
||||
return $Response
|
||||
return $Response
|
||||
}
|
||||
catch [System.Net.Http.HttpRequestException] {
|
||||
$DownloadException = [System.Exception] "Unable to download $Uri."
|
||||
|
||||
# Pick up the exception message and inner exceptions' messages if they exist
|
||||
$CurrentException = $PSItem.Exception
|
||||
$ErrorMsg = $CurrentException.Message + "`r`n"
|
||||
while ($CurrentException.InnerException) {
|
||||
$CurrentException = $CurrentException.InnerException
|
||||
$ErrorMsg += $CurrentException.Message + "`r`n"
|
||||
}
|
||||
|
||||
# Check if there is an issue concerning TLS.
|
||||
if ($ErrorMsg -like "*SSL/TLS*") {
|
||||
$ErrorMsg += "Ensure that TLS 1.2 or higher is enabled to use this script.`r`n"
|
||||
}
|
||||
|
||||
$DownloadException.Data["ErrorMessage"] = $ErrorMsg
|
||||
throw $DownloadException
|
||||
}
|
||||
finally {
|
||||
if ($HttpClient -ne $null) {
|
||||
@@ -259,7 +330,7 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
})
|
||||
}
|
||||
|
||||
function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Coherent) {
|
||||
function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
$VersionFileUrl = $null
|
||||
@@ -269,17 +340,11 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co
|
||||
elseif ($Runtime -eq "aspnetcore") {
|
||||
$VersionFileUrl = "$UncachedFeed/aspnetcore/Runtime/$Channel/latest.version"
|
||||
}
|
||||
# Currently, the WindowsDesktop runtime is manufactured with the .Net core runtime
|
||||
elseif ($Runtime -eq "windowsdesktop") {
|
||||
$VersionFileUrl = "$UncachedFeed/Runtime/$Channel/latest.version"
|
||||
$VersionFileUrl = "$UncachedFeed/WindowsDesktop/$Channel/latest.version"
|
||||
}
|
||||
elseif (-not $Runtime) {
|
||||
if ($Coherent) {
|
||||
$VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.coherent.version"
|
||||
}
|
||||
else {
|
||||
$VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version"
|
||||
}
|
||||
$VersionFileUrl = "$UncachedFeed/Sdk/$Channel/latest.version"
|
||||
}
|
||||
else {
|
||||
throw "Invalid value for `$Runtime"
|
||||
@@ -288,7 +353,8 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel, [bool]$Co
|
||||
$Response = GetHTTPResponse -Uri $VersionFileUrl
|
||||
}
|
||||
catch {
|
||||
throw "Could not resolve version information."
|
||||
Say-Error "Could not resolve version information."
|
||||
throw
|
||||
}
|
||||
$StringContent = $Response.Content.ReadAsStringAsync().Result
|
||||
|
||||
@@ -314,7 +380,8 @@ function Parse-Jsonfile-For-Version([string]$JSonFile) {
|
||||
$JSonContent = Get-Content($JSonFile) -Raw | ConvertFrom-Json | Select-Object -expand "sdk" -ErrorAction SilentlyContinue
|
||||
}
|
||||
catch {
|
||||
throw "Json file unreadable: '$JSonFile'"
|
||||
Say-Error "Json file unreadable: '$JSonFile'"
|
||||
throw
|
||||
}
|
||||
if ($JSonContent) {
|
||||
try {
|
||||
@@ -327,7 +394,8 @@ function Parse-Jsonfile-For-Version([string]$JSonFile) {
|
||||
}
|
||||
}
|
||||
catch {
|
||||
throw "Unable to parse the SDK node in '$JSonFile'"
|
||||
Say-Error "Unable to parse the SDK node in '$JSonFile'"
|
||||
throw
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -343,16 +411,12 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel,
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if (-not $JSonFile) {
|
||||
switch ($Version.ToLower()) {
|
||||
{ $_ -eq "latest" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $False
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
{ $_ -eq "coherent" } {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel -Coherent $True
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
default { return $Version }
|
||||
if ($Version.ToLower() -eq "latest") {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
else {
|
||||
return $Version
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -363,17 +427,29 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel,
|
||||
function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
# If anything fails in this lookup it will default to $SpecificVersion
|
||||
$SpecificProductVersion = Get-Product-Version -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion
|
||||
|
||||
if ($Runtime -eq "dotnet") {
|
||||
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificVersion-win-$CLIArchitecture.zip"
|
||||
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/dotnet-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||
}
|
||||
elseif ($Runtime -eq "aspnetcore") {
|
||||
$PayloadURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/aspnetcore-runtime-$SpecificVersion-win-$CLIArchitecture.zip"
|
||||
$PayloadURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/aspnetcore-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||
}
|
||||
elseif ($Runtime -eq "windowsdesktop") {
|
||||
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificVersion-win-$CLIArchitecture.zip"
|
||||
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
||||
$PayloadURL = "$AzureFeed/Runtime/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||
if ($SpecificVersion -match '^(\d+)\.(.*)$')
|
||||
{
|
||||
$majorVersion = [int]$Matches[1]
|
||||
if ($majorVersion -ge 5)
|
||||
{
|
||||
$PayloadURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/windowsdesktop-runtime-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (-not $Runtime) {
|
||||
$PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificVersion-win-$CLIArchitecture.zip"
|
||||
$PayloadURL = "$AzureFeed/Sdk/$SpecificVersion/dotnet-sdk-$SpecificProductVersion-win-$CLIArchitecture.zip"
|
||||
}
|
||||
else {
|
||||
throw "Invalid value for `$Runtime"
|
||||
@@ -381,7 +457,7 @@ function Get-Download-Link([string]$AzureFeed, [string]$SpecificVersion, [string
|
||||
|
||||
Say-Verbose "Constructed primary named payload URL: $PayloadURL"
|
||||
|
||||
return $PayloadURL
|
||||
return $PayloadURL, $SpecificProductVersion
|
||||
}
|
||||
|
||||
function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [string]$CLIArchitecture) {
|
||||
@@ -402,6 +478,60 @@ function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [
|
||||
return $PayloadURL
|
||||
}
|
||||
|
||||
function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if ($Runtime -eq "dotnet") {
|
||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt"
|
||||
}
|
||||
elseif ($Runtime -eq "aspnetcore") {
|
||||
$ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/productVersion.txt"
|
||||
}
|
||||
elseif ($Runtime -eq "windowsdesktop") {
|
||||
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/productVersion.txt"
|
||||
if ($SpecificVersion -match '^(\d+)\.(.*)')
|
||||
{
|
||||
$majorVersion = [int]$Matches[1]
|
||||
if ($majorVersion -ge 5)
|
||||
{
|
||||
$ProductVersionTxtURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/productVersion.txt"
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif (-not $Runtime) {
|
||||
$ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/productVersion.txt"
|
||||
}
|
||||
else {
|
||||
throw "Invalid value '$Runtime' specified for `$Runtime"
|
||||
}
|
||||
|
||||
Say-Verbose "Checking for existence of $ProductVersionTxtURL"
|
||||
|
||||
try {
|
||||
$productVersionResponse = GetHTTPResponse($productVersionTxtUrl)
|
||||
|
||||
if ($productVersionResponse.StatusCode -eq 200) {
|
||||
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
||||
if ($productVersion -ne $SpecificVersion)
|
||||
{
|
||||
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
||||
}
|
||||
|
||||
return $productVersion
|
||||
}
|
||||
else {
|
||||
Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) trying to get productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion"
|
||||
$productVersion = $SpecificVersion
|
||||
}
|
||||
} catch {
|
||||
Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion (Exception: '$($_.Exception.Message)' )"
|
||||
$productVersion = $SpecificVersion
|
||||
}
|
||||
|
||||
return $productVersion
|
||||
}
|
||||
|
||||
function Get-User-Share-Path() {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
@@ -539,6 +669,23 @@ function DownloadFile($Source, [string]$OutPath) {
|
||||
}
|
||||
}
|
||||
|
||||
function SafeRemoveFile($Path) {
|
||||
try {
|
||||
if (Test-Path $Path) {
|
||||
Remove-Item $Path
|
||||
Say-Verbose "The temporary file `"$Path`" was removed."
|
||||
}
|
||||
else
|
||||
{
|
||||
Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
|
||||
}
|
||||
}
|
||||
|
||||
function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolderRelativePath) {
|
||||
$BinPath = Get-Absolute-Path $(Join-Path -Path $InstallRoot -ChildPath $BinFolderRelativePath)
|
||||
if (-Not $NoPath) {
|
||||
@@ -555,9 +702,14 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde
|
||||
}
|
||||
}
|
||||
|
||||
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.`r`n"
|
||||
|
||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
||||
$DownloadLink = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
$DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
|
||||
$InstallRoot = Resolve-Installation-Path $InstallDir
|
||||
@@ -583,7 +735,12 @@ if ($DryRun) {
|
||||
}
|
||||
}
|
||||
Say "Repeatable invocation: $RepeatableCommand"
|
||||
exit 0
|
||||
if ($SpecificVersion -ne $EffectiveVersion)
|
||||
{
|
||||
Say "NOTE: Due to finding a version manifest with this runtime, it would actually install with version '$EffectiveVersion'"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if ($Runtime -eq "dotnet") {
|
||||
@@ -606,12 +763,18 @@ else {
|
||||
throw "Invalid value for `$Runtime"
|
||||
}
|
||||
|
||||
if ($SpecificVersion -ne $EffectiveVersion)
|
||||
{
|
||||
Say "Performing installation checks for effective version: $EffectiveVersion"
|
||||
$SpecificVersion = $EffectiveVersion
|
||||
}
|
||||
|
||||
# Check if the SDK version is already installed.
|
||||
$isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion
|
||||
if ($isAssetInstalled) {
|
||||
Say "$assetName version $SpecificVersion is already installed."
|
||||
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
|
||||
exit 0
|
||||
return
|
||||
}
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
||||
@@ -619,30 +782,69 @@ New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
|
||||
$installDrive = $((Get-Item $InstallRoot).PSDrive.Name);
|
||||
$diskInfo = Get-PSDrive -Name $installDrive
|
||||
if ($diskInfo.Free / 1MB -le 100) {
|
||||
Say "There is not enough disk space on drive ${installDrive}:"
|
||||
exit 0
|
||||
throw "There is not enough disk space on drive ${installDrive}:"
|
||||
}
|
||||
|
||||
$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
||||
Say-Verbose "Zip path: $ZipPath"
|
||||
|
||||
$DownloadFailed = $false
|
||||
Say "Downloading link: $DownloadLink"
|
||||
|
||||
$PrimaryDownloadStatusCode = 0
|
||||
$LegacyDownloadStatusCode = 0
|
||||
|
||||
$PrimaryDownloadFailedMsg = ""
|
||||
$LegacyDownloadFailedMsg = ""
|
||||
|
||||
Say "Downloading primary link $DownloadLink"
|
||||
try {
|
||||
DownloadFile -Source $DownloadLink -OutPath $ZipPath
|
||||
}
|
||||
catch {
|
||||
Say "Cannot download: $DownloadLink"
|
||||
if ($PSItem.Exception.Data.Contains("StatusCode")) {
|
||||
$PrimaryDownloadStatusCode = $PSItem.Exception.Data["StatusCode"]
|
||||
}
|
||||
|
||||
if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
|
||||
$PrimaryDownloadFailedMsg = $PSItem.Exception.Data["ErrorMessage"]
|
||||
} else {
|
||||
$PrimaryDownloadFailedMsg = $PSItem.Exception.Message
|
||||
}
|
||||
|
||||
if ($PrimaryDownloadStatusCode -eq 404) {
|
||||
Say "The resource at $DownloadLink is not available."
|
||||
} else {
|
||||
Say $PSItem.Exception.Message
|
||||
}
|
||||
|
||||
SafeRemoveFile -Path $ZipPath
|
||||
|
||||
if ($LegacyDownloadLink) {
|
||||
$DownloadLink = $LegacyDownloadLink
|
||||
$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
|
||||
Say-Verbose "Legacy zip path: $ZipPath"
|
||||
Say "Downloading legacy link: $DownloadLink"
|
||||
Say "Downloading legacy link $DownloadLink"
|
||||
try {
|
||||
DownloadFile -Source $DownloadLink -OutPath $ZipPath
|
||||
}
|
||||
catch {
|
||||
Say "Cannot download: $DownloadLink"
|
||||
if ($PSItem.Exception.Data.Contains("StatusCode")) {
|
||||
$LegacyDownloadStatusCode = $PSItem.Exception.Data["StatusCode"]
|
||||
}
|
||||
|
||||
if ($PSItem.Exception.Data.Contains("ErrorMessage")) {
|
||||
$LegacyDownloadFailedMsg = $PSItem.Exception.Data["ErrorMessage"]
|
||||
} else {
|
||||
$LegacyDownloadFailedMsg = $PSItem.Exception.Message
|
||||
}
|
||||
|
||||
if ($LegacyDownloadStatusCode -eq 404) {
|
||||
Say "The resource at $DownloadLink is not available."
|
||||
} else {
|
||||
Say $PSItem.Exception.Message
|
||||
}
|
||||
|
||||
SafeRemoveFile -Path $ZipPath
|
||||
$DownloadFailed = $true
|
||||
}
|
||||
}
|
||||
@@ -652,7 +854,19 @@ catch {
|
||||
}
|
||||
|
||||
if ($DownloadFailed) {
|
||||
throw "Could not find/download: `"$assetName`" with version = $SpecificVersion`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
|
||||
if (($PrimaryDownloadStatusCode -eq 404) -and ((-not $LegacyDownloadLink) -or ($LegacyDownloadStatusCode -eq 404))) {
|
||||
throw "Could not find `"$assetName`" with version = $SpecificVersion`nRefer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
|
||||
} else {
|
||||
# 404-NotFound is an expected response if it goes from only one of the links, do not show that error.
|
||||
# If primary path is available (not 404-NotFound) then show the primary error else show the legacy error.
|
||||
if ($PrimaryDownloadStatusCode -ne 404) {
|
||||
throw "Could not download `"$assetName`" with version = $SpecificVersion`r`n$PrimaryDownloadFailedMsg"
|
||||
}
|
||||
if (($LegacyDownloadLink) -and ($LegacyDownloadStatusCode -ne 404)) {
|
||||
throw "Could not download `"$assetName`" with version = $SpecificVersion`r`n$LegacyDownloadFailedMsg"
|
||||
}
|
||||
throw "Could not download `"$assetName`" with version = $SpecificVersion"
|
||||
}
|
||||
}
|
||||
|
||||
Say "Extracting zip from $DownloadLink"
|
||||
@@ -674,22 +888,24 @@ if (!$isAssetInstalled) {
|
||||
$isAssetInstalled = Is-Dotnet-Package-Installed -InstallRoot $InstallRoot -RelativePathToPackage $dotnetPackageRelativePath -SpecificVersion $SpecificVersion
|
||||
}
|
||||
|
||||
# Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm.
|
||||
if (!$isAssetInstalled) {
|
||||
Say-Error "Failed to verify the version of installed `"$assetName`".`nInstallation source: $DownloadLink.`nInstallation location: $InstallRoot.`nReport the bug at https://github.com/dotnet/install-scripts/issues."
|
||||
throw "`"$assetName`" with version = $SpecificVersion failed to install with an unknown error."
|
||||
}
|
||||
|
||||
Remove-Item $ZipPath
|
||||
SafeRemoveFile -Path $ZipPath
|
||||
|
||||
Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -BinFolderRelativePath $BinFolderRelativePath
|
||||
|
||||
Say "Note that the script does not resolve dependencies during installation."
|
||||
Say "To check the list of dependencies, go to https://docs.microsoft.com/dotnet/core/install/windows#dependencies"
|
||||
Say "Installation finished"
|
||||
exit 0
|
||||
|
||||
# SIG # Begin signature block
|
||||
# MIIjkQYJKoZIhvcNAQcCoIIjgjCCI34CAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||
# MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAwp4UsNdAkvwY3
|
||||
# VhbuN9D6NGOz+qNqW2+62YubWa4qJaCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
|
||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCNsnhcJvx/hXmM
|
||||
# w8KjuvvIMDBFonhg9XJFc1QwfTyH4aCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
|
||||
# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||
@@ -761,119 +977,119 @@ exit 0
|
||||
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
||||
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
||||
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZjCCFWICAQEwgZUwfjELMAkG
|
||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG
|
||||
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
||||
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
||||
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
|
||||
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQga11B1DE+
|
||||
# y9z0lmEO+MC+bhXPKfWALB7Snkn7G/wCUncwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgpT/bxWwe
|
||||
# aW0EinKMWCAzDXUjwXkIHldYzR6lw4/1Pc0wQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
||||
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
||||
# BgkqhkiG9w0BAQEFAASCAQBIgx+sFXkLXf7Xbx7opCD3uhpQGEQ4x/LsqTax0bu1
|
||||
# GC/cxiI+dodUz+T4hKj1ZQyUH0Zlce32GutY048O9tkr7fQyuohoFUgChdIATEOY
|
||||
# qAIESFbDT07i7khJfO2pewlhgM+A5ClvBa8HAvV0wOd+2IVgv3pgow1LEJm0/5NB
|
||||
# E3IFA+hFrqiWALOY0uUep4H20EHMrbqw3YoV3EodIkTj3fC76q4K/bF84EZLUgjY
|
||||
# e4rmXac8n7A9qR18QzGl8usEJej4OHU4nlUT1J734m+AWIFmfb/Zr2MyXED0V4q4
|
||||
# Vbmw3O7xD9STeNYrn5RjPmGPEN04akHxhNUSqLIc9vxQoYIS8DCCEuwGCisGAQQB
|
||||
# gjcDAwExghLcMIIS2AYJKoZIhvcNAQcCoIISyTCCEsUCAQMxDzANBglghkgBZQME
|
||||
# AgEFADCCAVQGCyqGSIb3DQEJEAEEoIIBQwSCAT8wggE7AgEBBgorBgEEAYRZCgMB
|
||||
# MDEwDQYJYIZIAWUDBAIBBQAEIPPK1A0D1n7ZEdgTjKPY4sWiOMtohMqGpFvG55NY
|
||||
# SFHeAgZepuJh/dEYEjIwMjAwNTI5MTYyNzE1LjMxWjAEgAIB9KCB1KSB0TCBzjEL
|
||||
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
|
||||
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWlj
|
||||
# cm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBU
|
||||
# U1MgRVNOOjYwQkMtRTM4My0yNjM1MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T
|
||||
# dGFtcCBTZXJ2aWNloIIORDCCBPUwggPdoAMCAQICEzMAAAEm37pLIrmCggcAAAAA
|
||||
# ASYwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
|
||||
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
|
||||
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAw
|
||||
# HhcNMTkxMjE5MDExNDU5WhcNMjEwMzE3MDExNDU5WjCBzjELMAkGA1UEBhMCVVMx
|
||||
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
|
||||
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9wZXJh
|
||||
# dGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjYwQkMt
|
||||
# RTM4My0yNjM1MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
||||
# MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnjC+hpxO8w2VdBO18X8L
|
||||
# Hk6XdfR9yNQ0y+MuBOY7n5YdgkVunvbk/f6q8UoNFAdYQjVLPSAHbi6tUMiNeMGH
|
||||
# k1U0lUxAkja2W2/szj/ghuFklvfHNBbsuiUShlhRlqcFNS7KXL2iwKDijmOhWJPY
|
||||
# a2bLEr4W/mQLbSXail5p6m138Ttx4MAVEzzuGI0Kwr8ofIL7z6zCeWDiBM57LrNC
|
||||
# qHOA2wboeuMsG4O0Oz2LMAzBLbJZPRPnZAD2HdD4HUL2mzZ8wox74Mekb7RzrUP3
|
||||
# hiHpxXZceJvhIEKfAgVkB5kTZQnio8A1JijMjw8f4TmsJPdJWpi8ei73sexe8/Yj
|
||||
# cwIDAQABo4IBGzCCARcwHQYDVR0OBBYEFEmrrB8XsH6YQo3RWKZfxqM0DmFBMB8G
|
||||
# A1UdIwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeG
|
||||
# RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Rp
|
||||
# bVN0YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH
|
||||
# MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3Rh
|
||||
# UENBXzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYB
|
||||
# BQUHAwgwDQYJKoZIhvcNAQELBQADggEBAECW+51o6W/0J/O/npudfjVzMXq0u0cs
|
||||
# HjqXpdRyH6o03jlmY5MXAui3cmPBKufijJxD2pMRPVMUNh3VA0PQuJeYrP06oFdq
|
||||
# LpLxd3IJARm98vzaMgCz2nCwBDpe9X2M3Js9K1GAX+w4Az8N7J+Z6P1OD0VxHBdq
|
||||
# eTaqDN1lk1vwagTN7t/WitxMXRDz0hRdYiWbATBAVgXXCOfzs3hnEv1n/EDab9HX
|
||||
# OLMXKVY/+alqYKdV9lkuRp8Us1Q1WZy9z72Azu9x4mzft3fJ1puTjBHo5tHfixZo
|
||||
# ummbI+WwjVCrku7pskJahfNi5amSgrqgR6nWAwvpJELccpVLdSxxmG0wggZxMIIE
|
||||
# WaADAgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJV
|
||||
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9v
|
||||
# dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0y
|
||||
# NTA3MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
||||
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
|
||||
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjAN
|
||||
# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RU
|
||||
# ENWlCgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBE
|
||||
# D/FgiIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50
|
||||
# YWeRX4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd
|
||||
# /XcfPfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaR
|
||||
# togINeh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQAB
|
||||
# o4IB5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8
|
||||
# RhvFM2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB
|
||||
# hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO
|
||||
# mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w
|
||||
# a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr
|
||||
# BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv
|
||||
# bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSAB
|
||||
# Af8EgZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3
|
||||
# dy5taWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEF
|
||||
# BQcCAjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBt
|
||||
# AGUAbgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Eh
|
||||
# b7Prpsz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7
|
||||
# uVOMzPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqR
|
||||
# UgCvOA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9
|
||||
# Va8v/rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8
|
||||
# +n99lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+
|
||||
# Y1klD3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh
|
||||
# 2rBQHm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRy
|
||||
# zR30uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoo
|
||||
# uLGp25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx
|
||||
# 16HSxVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341
|
||||
# Hgi62jbb01+P3nSISRKhggLSMIICOwIBATCB/KGB1KSB0TCBzjELMAkGA1UEBhMC
|
||||
# BgkqhkiG9w0BAQEFAASCAQCHd7sSQVq0YDg8QDx6/kLWn3s6jtvvIDCCgsO9spHM
|
||||
# quPd4FPbG67DCsKDClekQs52qrtRO3Zo+JMnCw4j3bS+gZHzeJr2shbftOrpsFoD
|
||||
# l7OPcUmtrqul9dkQCOp8t0MP3ls0n96/YyNy6lz4BAlTdkdDx957uAxalKaCIBzb
|
||||
# R9QyppOKIfNFvwD4EI5KI6tpmSy/uH8SrRg7ZExAYZl6J6R18WkL7KHn649lPoAQ
|
||||
# ujwrIXH10xOJops45ILGzKWQcHmCzLJGYapL4VHUuK+73nT+9ZROGHdk/PyvIcdw
|
||||
# iERa+C06v305t3DA+CuHFy1tvyw7IFF6RVbLZPwxrJjToYIS7jCCEuoGCisGAQQB
|
||||
# gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME
|
||||
# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
|
||||
# MDEwDQYJYIZIAWUDBAIBBQAEIOCaTmvM1AP0WaEVqzKaaCu/R+bTlR4kCrM/ZXsb
|
||||
# /eNOAgZgGeLsMwsYEzIwMjEwMjAzMjExNzQ5LjU5MVowBIACAfSggdSkgdEwgc4x
|
||||
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
||||
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1p
|
||||
# Y3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMg
|
||||
# VFNTIEVTTjo4OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
|
||||
# U3RhbXAgU2VydmljZaCCDkEwggT1MIID3aADAgECAhMzAAABLCKvRZd1+RvuAAAA
|
||||
# AAEsMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
|
||||
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
|
||||
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
|
||||
# MB4XDTE5MTIxOTAxMTUwM1oXDTIxMDMxNzAxMTUwM1owgc4xCzAJBgNVBAYTAlVT
|
||||
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
|
||||
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVy
|
||||
# YXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4OTdB
|
||||
# LUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj
|
||||
# ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPK1zgSSq+MxAYo3qpCt
|
||||
# QDxSMPPJy6mm/wfEJNjNUnYtLFBwl1BUS5trEk/t41ldxITKehs+ABxYqo4Qxsg3
|
||||
# Gy1ugKiwHAnYiiekfC+ZhptNFgtnDZIn45zC0AlVr/6UfLtsLcHCh1XElLUHfEC0
|
||||
# nBuQcM/SpYo9e3l1qY5NdMgDGxCsmCKdiZfYXIu+U0UYIBhdzmSHnB3fxZOBVcr5
|
||||
# htFHEBBNt/rFJlm/A4yb8oBsp+Uf0p5QwmO/bCcdqB15JpylOhZmWs0sUfJKlK9E
|
||||
# rAhBwGki2eIRFKsQBdkXS9PWpF1w2gIJRvSkDEaCf+lbGTPdSzHSbfREWOF9wY3i
|
||||
# Yj8CAwEAAaOCARswggEXMB0GA1UdDgQWBBRRahZSGfrCQhCyIyGH9DkiaW7L0zAf
|
||||
# BgNVHSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBH
|
||||
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNU
|
||||
# aW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
|
||||
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0
|
||||
# YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsG
|
||||
# AQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBPFxHIwi4vAH49w9Svmz6K3tM55RlW
|
||||
# 5pPeULXdut2Rqy6Ys0+VpZsbuaEoxs6Z1C3hMbkiqZFxxyltxJpuHTyGTg61zfNI
|
||||
# F5n6RsYF3s7IElDXNfZznF1/2iWc6uRPZK8rxxUJ/7emYXZCYwuUY0XjsCpP9pbR
|
||||
# RKeJi6r5arSyI+NfKxvgoM21JNt1BcdlXuAecdd/k8UjxCscffanoK2n6LFw1PcZ
|
||||
# lEO7NId7o+soM2C0QY5BYdghpn7uqopB6ixyFIIkDXFub+1E7GmAEwfU6VwEHL7y
|
||||
# 9rNE8bd+JrQs+yAtkkHy9FmXg/PsGq1daVzX1So7CJ6nyphpuHSN3VfTMIIGcTCC
|
||||
# BFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC
|
||||
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
|
||||
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEpMCcGA1UECxMgTWljcm9zb2Z0IE9w
|
||||
# ZXJhdGlvbnMgUHVlcnRvIFJpY28xJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjYw
|
||||
# QkMtRTM4My0yNjM1MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2
|
||||
# aWNloiMKAQEwBwYFKw4DAhoDFQAKZzI5aZnESumrToHx3Lqgxnr//KCBgzCBgKR+
|
||||
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
||||
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
||||
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA
|
||||
# 4nuQTDAiGA8yMDIwMDUyOTE3NDQ0NFoYDzIwMjAwNTMwMTc0NDQ0WjB3MD0GCisG
|
||||
# AQQBhFkKBAExLzAtMAoCBQDie5BMAgEAMAoCAQACAiZJAgH/MAcCAQACAhEjMAoC
|
||||
# BQDifOHMAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEA
|
||||
# AgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAprmyJTXdH9FmQZ0I
|
||||
# mRSJdjc/RrSqDm8DUEq/h3FL73G/xvg9MbQj1J/h3hdlSIPcQXjrhL8hud/vyF0j
|
||||
# IFaTK5YOcixkX++9t7Vz3Mn0KkQo8F4DNSyZEPpz682AyKKwLMJDy52pFFFKNP5l
|
||||
# NpOz6YY1Od1xvk4nyN1WwfLnGswxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJV
|
||||
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
|
||||
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt
|
||||
# ZS1TdGFtcCBQQ0EgMjAxMAITMwAAASbfuksiuYKCBwAAAAABJjANBglghkgBZQME
|
||||
# AgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJ
|
||||
# BDEiBCB0IE0Q6P23RQlh8TFyp57UQQUF/sbui7mOMStRgTFZxTCB+gYLKoZIhvcN
|
||||
# AQkQAi8xgeowgecwgeQwgb0EIDb9z++evV5wDO9qk5ZnbEZ8CTOuR+kZyu8xbTsJ
|
||||
# CXUPMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
|
||||
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
||||
# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAEm
|
||||
# 37pLIrmCggcAAAAAASYwIgQgtwi02bvsGAOdpAxEF607G6g9PlyS8vc2bAUSHovH
|
||||
# /IIwDQYJKoZIhvcNAQELBQAEggEAEMCfsXNudrjztjI6JNyNDVpdF1axRVcGiNy6
|
||||
# 67pgb1EePsjA2EaBB+5ZjgO/73JxuiVgsoXgH7em8tKG5RQJtcm5obVDb+jKksK4
|
||||
# qcFLA1f7seQRGfE06UAPnSFh2GqMtTNJGCXWwqWLH2LduTjOqPt8Nupo16ABFIT2
|
||||
# akTzBSJ81EHBkEU0Et6CgeaZiBYrCCXUtD+ASvLDkPSrjweQGu3Zk1SSROEzxMY9
|
||||
# jdlGfMkK2krMd9ub9UZ13RcQDijJqo+h6mz76pAuiFFvuQl6wMoSGFaaUQwfd+WQ
|
||||
# gXlVVX/A9JFBihrxnDVglEPlsIOxCHkTeIxLfnAkCbax+9pevA==
|
||||
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv
|
||||
# b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcN
|
||||
# MjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
|
||||
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
|
||||
# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIw
|
||||
# DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0
|
||||
# VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEw
|
||||
# RA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQe
|
||||
# dGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKx
|
||||
# Xf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4G
|
||||
# kbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEA
|
||||
# AaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7
|
||||
# fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
|
||||
# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
|
||||
# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
|
||||
# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
|
||||
# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
|
||||
# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0g
|
||||
# AQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93
|
||||
# d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYB
|
||||
# BQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUA
|
||||
# bQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOh
|
||||
# IW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS
|
||||
# +7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlK
|
||||
# kVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon
|
||||
# /VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOi
|
||||
# PPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/
|
||||
# fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCII
|
||||
# YdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0
|
||||
# cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7a
|
||||
# KLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQ
|
||||
# cdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+
|
||||
# NR4Iuto229Nfj950iEkSoYICzzCCAjgCAQEwgfyhgdSkgdEwgc4xCzAJBgNVBAYT
|
||||
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
|
||||
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29mdCBP
|
||||
# cGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4
|
||||
# OTdBLUUzNTYtMTcwMTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
|
||||
# dmljZaIjCgEBMAcGBSsOAwIaAxUADE5OKSMoNx/mYxYWap1RTOohbJ2ggYMwgYCk
|
||||
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
|
||||
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
|
||||
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
|
||||
# AOPFChkwIhgPMjAyMTAyMDMxNTQwMDlaGA8yMDIxMDIwNDE1NDAwOVowdDA6Bgor
|
||||
# BgEEAYRZCgQBMSwwKjAKAgUA48UKGQIBADAHAgEAAgIXmDAHAgEAAgIRyTAKAgUA
|
||||
# 48ZbmQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID
|
||||
# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAHeeznL2n6HWCjHH94Fl
|
||||
# hcdW6TEXzq4XNgp1Gx1W9F8gJ4x+SwoV7elJZkwgGffcpHomLvIY/VSuzsl1NgtJ
|
||||
# TWM2UxoqSv58BBOrl4eGhH6kkg8Ucy2tdeK5T8cHa8pMkq2j9pFd2mRG/6VMk0dl
|
||||
# Xz7Uy3Z6bZqkcABMyAfuAaGbMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMx
|
||||
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
|
||||
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
|
||||
# U3RhbXAgUENBIDIwMTACEzMAAAEsIq9Fl3X5G+4AAAAAASwwDQYJYIZIAWUDBAIB
|
||||
# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx
|
||||
# IgQg/QYv7yp+354WTjWUIsXWndTEzXjaYjqwYjcBxCJKjdUwgfoGCyqGSIb3DQEJ
|
||||
# EAIvMYHqMIHnMIHkMIG9BCBbn/0uFFh42hTM5XOoKdXevBaiSxmYK9Ilcn9nu5ZH
|
||||
# 4TCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
|
||||
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
||||
# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABLCKv
|
||||
# RZd1+RvuAAAAAAEsMCIEIIfIM3YbzHswb/Kj/qq1l1cHA6QBl+gEXYanUNJomrpT
|
||||
# MA0GCSqGSIb3DQEBCwUABIIBAAwdcXssUZGO7ho5+NHLjIxLtQk543aKGo+lrRMY
|
||||
# Q9abE1h/AaaNJl0iGxX4IihNWyfovSfYL3L4eODUBAu68tWSxeceRfWNsb/ZZfUi
|
||||
# v89hpLssI/Gf1BEgNMA4zCuIGQiC8okusVumEpAhhvCEbSiTTTtBdolTnU/CAKui
|
||||
# oxaU3R9XkKh1F4oAM26+dJ1J2BLQXPs5afNvvedDsZWNQUPK1sFF3JRfzxiTrwBW
|
||||
# EJRyflev9gyDoqCHzippgb+6+eti1WTkcA9Q49GIT11S6LOAVqkSC9N7Nqf8ksh8
|
||||
# ARdwT8jigpsm+mj7lrVU9upDkhVYhKeO8oiZq95Q53Zkteo=
|
||||
# SIG # End signature block
|
||||
|
||||
349
externals/install-dotnet.sh
vendored
349
externals/install-dotnet.sh
vendored
@@ -40,7 +40,7 @@ if [ -t 1 ] && command -v tput > /dev/null; then
|
||||
fi
|
||||
|
||||
say_warning() {
|
||||
printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}"
|
||||
printf "%b\n" "${yellow:-}dotnet_install: Warning: $1${normal:-}" >&3
|
||||
}
|
||||
|
||||
say_err() {
|
||||
@@ -183,6 +183,9 @@ get_current_os_name() {
|
||||
elif is_musl_based_distro; then
|
||||
echo "linux-musl"
|
||||
return 0
|
||||
elif [ "$linux_platform_name" = "linux-musl" ]; then
|
||||
echo "linux-musl"
|
||||
return 0
|
||||
else
|
||||
echo "linux"
|
||||
return 0
|
||||
@@ -241,42 +244,6 @@ check_min_reqs() {
|
||||
return 0
|
||||
}
|
||||
|
||||
check_pre_reqs() {
|
||||
eval $invocation
|
||||
|
||||
if [ "${DOTNET_INSTALL_SKIP_PREREQS:-}" = "1" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ "$(uname)" = "Linux" ]; then
|
||||
if is_musl_based_distro; then
|
||||
if ! command -v scanelf > /dev/null; then
|
||||
say_warning "scanelf not found, please install pax-utils package."
|
||||
return 0
|
||||
fi
|
||||
LDCONFIG_COMMAND="scanelf --ldpath -BF '%f'"
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libintl)" ] && say_warning "Unable to locate libintl. Probable prerequisite missing; install libintl (or gettext)."
|
||||
else
|
||||
if [ ! -x "$(command -v ldconfig)" ]; then
|
||||
say_verbose "ldconfig is not in PATH, trying /sbin/ldconfig."
|
||||
LDCONFIG_COMMAND="/sbin/ldconfig"
|
||||
else
|
||||
LDCONFIG_COMMAND="ldconfig"
|
||||
fi
|
||||
local librarypath=${LD_LIBRARY_PATH:-}
|
||||
LDCONFIG_COMMAND="$LDCONFIG_COMMAND -NXv ${librarypath//:/ }"
|
||||
fi
|
||||
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep zlib)" ] && say_warning "Unable to locate zlib. Probable prerequisite missing; install zlib."
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep ssl)" ] && say_warning "Unable to locate libssl. Probable prerequisite missing; install libssl."
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libicu)" ] && say_warning "Unable to locate libicu. Probable prerequisite missing; install libicu."
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep lttng)" ] && say_warning "Unable to locate liblttng. Probable prerequisite missing; install libcurl."
|
||||
[ -z "$($LDCONFIG_COMMAND 2>/dev/null | grep libcurl)" ] && say_warning "Unable to locate libcurl. Probable prerequisite missing; install libcurl."
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# input - $1
|
||||
to_lowercase() {
|
||||
@@ -332,11 +299,11 @@ get_machine_architecture() {
|
||||
if command -v uname > /dev/null; then
|
||||
CPUName=$(uname -m)
|
||||
case $CPUName in
|
||||
armv7l)
|
||||
armv*l)
|
||||
echo "arm"
|
||||
return 0
|
||||
;;
|
||||
aarch64)
|
||||
aarch64|arm64)
|
||||
echo "arm64"
|
||||
return 0
|
||||
;;
|
||||
@@ -373,10 +340,34 @@ get_normalized_architecture_from_architecture() {
|
||||
;;
|
||||
esac
|
||||
|
||||
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/sdk/issues"
|
||||
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
|
||||
return 1
|
||||
}
|
||||
|
||||
# args:
|
||||
# user_defined_os - $1
|
||||
get_normalized_os() {
|
||||
eval $invocation
|
||||
|
||||
local osname="$(to_lowercase "$1")"
|
||||
if [ ! -z "$osname" ]; then
|
||||
case "$osname" in
|
||||
osx | freebsd | rhel.6 | linux-musl | linux)
|
||||
echo "$osname"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
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
|
||||
else
|
||||
osname="$(get_current_os_name)" || return 1
|
||||
fi
|
||||
echo "$osname"
|
||||
return 0
|
||||
}
|
||||
|
||||
# The version text returned from the feeds is a 1-line or 2-line string:
|
||||
# For the SDK and the dotnet runtime (2 lines):
|
||||
# Line 1: # commit_hash
|
||||
@@ -418,14 +409,12 @@ is_dotnet_package_installed() {
|
||||
# azure_feed - $1
|
||||
# channel - $2
|
||||
# normalized_architecture - $3
|
||||
# coherent - $4
|
||||
get_latest_version_info() {
|
||||
eval $invocation
|
||||
|
||||
local azure_feed="$1"
|
||||
local channel="$2"
|
||||
local normalized_architecture="$3"
|
||||
local coherent="$4"
|
||||
|
||||
local version_file_url=null
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
@@ -433,11 +422,7 @@ get_latest_version_info() {
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
version_file_url="$uncached_feed/aspnetcore/Runtime/$channel/latest.version"
|
||||
elif [ -z "$runtime" ]; then
|
||||
if [ "$coherent" = true ]; then
|
||||
version_file_url="$uncached_feed/Sdk/$channel/latest.coherent.version"
|
||||
else
|
||||
version_file_url="$uncached_feed/Sdk/$channel/latest.version"
|
||||
fi
|
||||
version_file_url="$uncached_feed/Sdk/$channel/latest.version"
|
||||
else
|
||||
say_err "Invalid value for \$runtime"
|
||||
return 1
|
||||
@@ -468,7 +453,6 @@ parse_jsonfile_for_version() {
|
||||
sdk_list=$(echo $sdk_section | awk -F"[{}]" '{print $2}')
|
||||
sdk_list=${sdk_list//[\" ]/}
|
||||
sdk_list=${sdk_list//,/$'\n'}
|
||||
sdk_list="$(echo -e "${sdk_list}" | tr -d '[[:space:]]')"
|
||||
|
||||
local version_info=""
|
||||
while read -r line; do
|
||||
@@ -505,26 +489,16 @@ get_specific_version_from_version() {
|
||||
local json_file="$5"
|
||||
|
||||
if [ -z "$json_file" ]; then
|
||||
case "$version" in
|
||||
latest)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
coherent)
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" true)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "$version"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
if [[ "$version" == "latest" ]]; then
|
||||
local version_info
|
||||
version_info="$(get_latest_version_info "$azure_feed" "$channel" "$normalized_architecture" false)" || return 1
|
||||
say_verbose "get_specific_version_from_version: version_info=$version_info"
|
||||
echo "$version_info" | get_version_from_version_info
|
||||
return 0
|
||||
else
|
||||
echo "$version"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
local version_info
|
||||
version_info="$(parse_jsonfile_for_version "$json_file")" || return 1
|
||||
@@ -538,6 +512,7 @@ get_specific_version_from_version() {
|
||||
# channel - $2
|
||||
# normalized_architecture - $3
|
||||
# specific_version - $4
|
||||
# normalized_os - $5
|
||||
construct_download_link() {
|
||||
eval $invocation
|
||||
|
||||
@@ -545,17 +520,16 @@ construct_download_link() {
|
||||
local channel="$2"
|
||||
local normalized_architecture="$3"
|
||||
local specific_version="${4//[$'\t\r\n']}"
|
||||
|
||||
local osname
|
||||
osname="$(get_current_os_name)" || return 1
|
||||
local specific_product_version="$(get_specific_product_version "$1" "$4")"
|
||||
local osname="$5"
|
||||
|
||||
local download_link=null
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_version-$osname-$normalized_architecture.tar.gz"
|
||||
download_link="$azure_feed/Runtime/$specific_version/dotnet-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz"
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
download_link="$azure_feed/aspnetcore/Runtime/$specific_version/aspnetcore-runtime-$specific_version-$osname-$normalized_architecture.tar.gz"
|
||||
download_link="$azure_feed/aspnetcore/Runtime/$specific_version/aspnetcore-runtime-$specific_product_version-$osname-$normalized_architecture.tar.gz"
|
||||
elif [ -z "$runtime" ]; then
|
||||
download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_version-$osname-$normalized_architecture.tar.gz"
|
||||
download_link="$azure_feed/Sdk/$specific_version/dotnet-sdk-$specific_product_version-$osname-$normalized_architecture.tar.gz"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
@@ -564,6 +538,50 @@ construct_download_link() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# specific_version - $2
|
||||
get_specific_product_version() {
|
||||
# If we find a 'productVersion.txt' at the root of any folder, we'll use its contents
|
||||
# to resolve the version of what's in the folder, superseding the specified version.
|
||||
eval $invocation
|
||||
|
||||
local azure_feed="$1"
|
||||
local specific_version="${2//[$'\t\r\n']}"
|
||||
local specific_product_version=$specific_version
|
||||
|
||||
local download_link=null
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
download_link="$azure_feed/Runtime/$specific_version/productVersion.txt${feed_credential}"
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
download_link="$azure_feed/aspnetcore/Runtime/$specific_version/productVersion.txt${feed_credential}"
|
||||
elif [ -z "$runtime" ]; then
|
||||
download_link="$azure_feed/Sdk/$specific_version/productVersion.txt${feed_credential}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
if machine_has "curl"
|
||||
then
|
||||
specific_product_version=$(curl -s --fail "$download_link")
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
specific_product_version=$specific_version
|
||||
fi
|
||||
elif machine_has "wget"
|
||||
then
|
||||
specific_product_version=$(wget -qO- "$download_link")
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
specific_product_version=$specific_version
|
||||
fi
|
||||
fi
|
||||
specific_product_version="${specific_product_version//[$'\t\r\n']}"
|
||||
|
||||
echo "$specific_product_version"
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# channel - $2
|
||||
@@ -684,11 +702,31 @@ extract_dotnet_package() {
|
||||
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"
|
||||
|
||||
rm -rf "$temp_out_path"
|
||||
rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
say_err "Extraction failed"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
get_http_header_curl() {
|
||||
eval $invocation
|
||||
local remote_path="$1"
|
||||
remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 "
|
||||
curl $curl_options "$remote_path_with_credential" || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
get_http_header_wget() {
|
||||
eval $invocation
|
||||
local remote_path="$1"
|
||||
remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
wget_options="-q -S --spider --tries 5 --waitretry 2 --connect-timeout 15 "
|
||||
wget $wget_options "$remote_path_with_credential" 2>&1 || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
@@ -706,13 +744,30 @@ download() {
|
||||
fi
|
||||
|
||||
local failed=false
|
||||
if machine_has "curl"; then
|
||||
downloadcurl "$remote_path" "$out_path" || failed=true
|
||||
elif machine_has "wget"; then
|
||||
downloadwget "$remote_path" "$out_path" || failed=true
|
||||
else
|
||||
failed=true
|
||||
fi
|
||||
local attempts=0
|
||||
while [ $attempts -lt 3 ]; do
|
||||
attempts=$((attempts+1))
|
||||
failed=false
|
||||
if machine_has "curl"; then
|
||||
downloadcurl "$remote_path" "$out_path" || failed=true
|
||||
elif machine_has "wget"; then
|
||||
downloadwget "$remote_path" "$out_path" || failed=true
|
||||
else
|
||||
say_err "Missing dependency: neither curl nor wget was found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$failed" = false ] || [ $attempts -ge 3 ] || { [ ! -z $http_code ] && [ $http_code = "404" ]; }; then
|
||||
break
|
||||
fi
|
||||
|
||||
say "Download attempt #$attempts has failed: $http_code $download_error_msg"
|
||||
say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
|
||||
sleep $((attempts*20))
|
||||
done
|
||||
|
||||
|
||||
|
||||
if [ "$failed" = true ]; then
|
||||
say_verbose "Download failed: $remote_path"
|
||||
return 1
|
||||
@@ -720,44 +775,60 @@ download() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Updates global variables $http_code and $download_error_msg
|
||||
downloadcurl() {
|
||||
eval $invocation
|
||||
unset http_code
|
||||
unset download_error_msg
|
||||
local remote_path="$1"
|
||||
local out_path="${2:-}"
|
||||
|
||||
# Append feed_credential as late as possible before calling curl to avoid logging feed_credential
|
||||
remote_path="${remote_path}${feed_credential}"
|
||||
|
||||
local remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
|
||||
local failed=false
|
||||
if [ -z "$out_path" ]; then
|
||||
curl $curl_options "$remote_path" || failed=true
|
||||
curl $curl_options "$remote_path_with_credential" || failed=true
|
||||
else
|
||||
curl $curl_options -o "$out_path" "$remote_path" || failed=true
|
||||
curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true
|
||||
fi
|
||||
if [ "$failed" = true ]; then
|
||||
say_verbose "Curl download failed"
|
||||
local response=$(get_http_header_curl $remote_path_with_credential)
|
||||
http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
|
||||
download_error_msg="Unable to download $remote_path."
|
||||
if [[ $http_code != 2* ]]; then
|
||||
download_error_msg+=" Returned HTTP status code: $http_code."
|
||||
fi
|
||||
say_verbose "$download_error_msg"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# Updates global variables $http_code and $download_error_msg
|
||||
downloadwget() {
|
||||
eval $invocation
|
||||
unset http_code
|
||||
unset download_error_msg
|
||||
local remote_path="$1"
|
||||
local out_path="${2:-}"
|
||||
|
||||
# Append feed_credential as late as possible before calling wget to avoid logging feed_credential
|
||||
remote_path="${remote_path}${feed_credential}"
|
||||
local remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
local wget_options="--tries 20 --waitretry 2 --connect-timeout 15 "
|
||||
local failed=false
|
||||
if [ -z "$out_path" ]; then
|
||||
wget -q $wget_options -O - "$remote_path" || failed=true
|
||||
wget -q $wget_options -O - "$remote_path_with_credential" || failed=true
|
||||
else
|
||||
wget $wget_options -O "$out_path" "$remote_path" || failed=true
|
||||
wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true
|
||||
fi
|
||||
if [ "$failed" = true ]; then
|
||||
say_verbose "Wget download failed"
|
||||
local response=$(get_http_header_wget $remote_path_with_credential)
|
||||
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
|
||||
download_error_msg="Unable to download $remote_path."
|
||||
if [[ $http_code != 2* ]]; then
|
||||
download_error_msg+=" Returned HTTP status code: $http_code."
|
||||
fi
|
||||
say_verbose "$download_error_msg"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
@@ -770,14 +841,18 @@ calculate_vars() {
|
||||
normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")"
|
||||
say_verbose "normalized_architecture=$normalized_architecture"
|
||||
|
||||
normalized_os="$(get_normalized_os "$user_defined_os")"
|
||||
say_verbose "normalized_os=$normalized_os"
|
||||
|
||||
specific_version="$(get_specific_version_from_version "$azure_feed" "$channel" "$normalized_architecture" "$version" "$json_file")"
|
||||
specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version")"
|
||||
say_verbose "specific_version=$specific_version"
|
||||
if [ -z "$specific_version" ]; then
|
||||
say_err "Could not resolve version information."
|
||||
return 1
|
||||
fi
|
||||
|
||||
download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")"
|
||||
download_link="$(construct_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version" "$normalized_os")"
|
||||
say_verbose "Constructed primary named payload URL: $download_link"
|
||||
|
||||
legacy_download_link="$(construct_legacy_download_link "$azure_feed" "$channel" "$normalized_architecture" "$specific_version")" || valid_legacy_download_link=false
|
||||
@@ -822,38 +897,74 @@ install_dotnet() {
|
||||
zip_path="$(mktemp "$temporary_file_template")"
|
||||
say_verbose "Zip path: $zip_path"
|
||||
|
||||
say "Downloading link: $download_link"
|
||||
|
||||
# Failures are normal in the non-legacy case for ultimately legacy downloads.
|
||||
# Do not output to stderr, since output to stderr is considered an error.
|
||||
say "Downloading primary link $download_link"
|
||||
|
||||
# The download function will set variables $http_code and $download_error_msg in case of failure.
|
||||
download "$download_link" "$zip_path" 2>&1 || download_failed=true
|
||||
|
||||
# if the download fails, download the legacy_download_link
|
||||
if [ "$download_failed" = true ]; then
|
||||
say "Cannot download: $download_link"
|
||||
|
||||
primary_path_http_code="$http_code"; primary_path_download_error_msg="$download_error_msg"
|
||||
case $primary_path_http_code in
|
||||
404)
|
||||
say "The resource at $download_link is not available."
|
||||
;;
|
||||
*)
|
||||
say "$primary_path_download_error_msg"
|
||||
;;
|
||||
esac
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
|
||||
if [ "$valid_legacy_download_link" = true ]; then
|
||||
download_failed=false
|
||||
download_link="$legacy_download_link"
|
||||
zip_path="$(mktemp "$temporary_file_template")"
|
||||
say_verbose "Legacy zip path: $zip_path"
|
||||
say "Downloading legacy link: $download_link"
|
||||
|
||||
say "Downloading legacy link $download_link"
|
||||
|
||||
# The download function will set variables $http_code and $download_error_msg in case of failure.
|
||||
download "$download_link" "$zip_path" 2>&1 || download_failed=true
|
||||
|
||||
if [ "$download_failed" = true ]; then
|
||||
say "Cannot download: $download_link"
|
||||
legacy_path_http_code="$http_code"; legacy_path_download_error_msg="$download_error_msg"
|
||||
case $legacy_path_http_code in
|
||||
404)
|
||||
say "The resource at $download_link is not available."
|
||||
;;
|
||||
*)
|
||||
say "$legacy_path_download_error_msg"
|
||||
;;
|
||||
esac
|
||||
rm -f "$zip_path" 2>&1 && say_verbose "Temporary zip file $zip_path was removed"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$download_failed" = true ]; then
|
||||
say_err "Could not find/download: \`$asset_name\` with version = $specific_version"
|
||||
say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
|
||||
if [[ "$primary_path_http_code" = "404" && ( "$valid_legacy_download_link" = false || "$legacy_path_http_code" = "404") ]]; then
|
||||
say_err "Could not find \`$asset_name\` with version = $specific_version"
|
||||
say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support"
|
||||
else
|
||||
say_err "Could not download: \`$asset_name\` with version = $specific_version"
|
||||
# 404-NotFound is an expected response if it goes from only one of the links, do not show that error.
|
||||
# If primary path is available (not 404-NotFound) then show the primary error else show the legacy error.
|
||||
if [ "$primary_path_http_code" != "404" ]; then
|
||||
say_err "$primary_path_download_error_msg"
|
||||
return 1
|
||||
fi
|
||||
if [[ "$valid_legacy_download_link" = true && "$legacy_path_http_code" != "404" ]]; then
|
||||
say_err "$legacy_path_download_error_msg"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
say "Extracting zip from $download_link"
|
||||
extract_dotnet_package "$zip_path" "$install_root"
|
||||
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.
|
||||
@@ -869,12 +980,14 @@ install_dotnet() {
|
||||
fi
|
||||
|
||||
# Check if the standard SDK version is installed.
|
||||
say_verbose "Checking installation: version = $specific_version"
|
||||
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_version"; then
|
||||
say_verbose "Checking installation: version = $specific_product_version"
|
||||
if is_dotnet_package_installed "$install_root" "$asset_relative_path" "$specific_product_version"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
say_err "\`$asset_name\` with version = $specific_version failed to install with an unknown error."
|
||||
# Version verification failed. More likely something is wrong either with the downloaded content or with the verification algorithm.
|
||||
say_err "Failed to verify the version of installed \`$asset_name\`.\nInstallation source: $download_link.\nInstallation location: $install_root.\nReport the bug at https://github.com/dotnet/install-scripts/issues."
|
||||
say_err "\`$asset_name\` with version = $specific_product_version failed to install with an unknown error."
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -900,6 +1013,7 @@ runtime=""
|
||||
runtime_id=""
|
||||
override_non_versioned_files=true
|
||||
non_dynamic_parameters=""
|
||||
user_defined_os=""
|
||||
|
||||
while [ $# -ne 0 ]
|
||||
do
|
||||
@@ -921,6 +1035,10 @@ do
|
||||
shift
|
||||
architecture="$1"
|
||||
;;
|
||||
--os|-[Oo][SS])
|
||||
shift
|
||||
user_defined_os="$1"
|
||||
;;
|
||||
--shared-runtime|-[Ss]hared[Rr]untime)
|
||||
say_warning "The --shared-runtime flag is obsolete and may be removed in a future version of this script. The recommended usage is to specify '--runtime dotnet'."
|
||||
if [ -z "$runtime" ]; then
|
||||
@@ -972,6 +1090,7 @@ do
|
||||
shift
|
||||
runtime_id="$1"
|
||||
non_dynamic_parameters+=" $name "\""$1"\"""
|
||||
say_warning "Use of --runtime-id is obsolete and should be limited to the versions below 2.1. To override architecture, use --architecture option instead. To override OS, use --os option instead."
|
||||
;;
|
||||
--jsonfile|-[Jj][Ss]on[Ff]ile)
|
||||
shift
|
||||
@@ -1004,8 +1123,6 @@ do
|
||||
echo " -Version"
|
||||
echo " Possible values:"
|
||||
echo " - latest - most latest build on specific channel"
|
||||
echo " - coherent - most latest coherent build on specific channel"
|
||||
echo " coherent applies only to SDK downloads"
|
||||
echo " - 3-part version in a format A.B.C - represents specific version of build"
|
||||
echo " examples: 2.0.0-preview2-006120; 1.1.0"
|
||||
echo " -i,--install-dir <DIR> Install under specified location (see Install Location below)"
|
||||
@@ -1013,6 +1130,11 @@ do
|
||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||
echo " --arch,-Architecture,-Arch"
|
||||
echo " Possible values: x64, arm, and arm64"
|
||||
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."
|
||||
echo " Not supported for legacy links. Use --runtime-id to specify platform for legacy links."
|
||||
echo " Refer to: https://aka.ms/dotnet-os-lifecycle for more information."
|
||||
echo " --runtime <RUNTIME> Installs a shared runtime only, without the SDK."
|
||||
echo " -Runtime"
|
||||
echo " Possible values:"
|
||||
@@ -1029,14 +1151,15 @@ do
|
||||
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 " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
|
||||
echo " -RuntimeId"
|
||||
echo " -?,--?,-h,--help,-Help Shows this help message"
|
||||
echo ""
|
||||
echo "Obsolete parameters:"
|
||||
echo " --shared-runtime The recommended alternative is '--runtime dotnet'."
|
||||
echo " This parameter is obsolete and may be removed in a future version of this script."
|
||||
echo " Installs just the shared runtime bits, not the entire SDK."
|
||||
echo " --runtime-id Installs the .NET Tools for the given platform (use linux-x64 for portable linux)."
|
||||
echo " -RuntimeId" The parameter is obsolete and may be removed in a future version of this script. Should be used only for versions below 2.1.
|
||||
echo " For primary links to override OS or/and architecture, use --os and --architecture option instead."
|
||||
echo ""
|
||||
echo "Install Location:"
|
||||
echo " Location is chosen in following order:"
|
||||
@@ -1058,6 +1181,11 @@ if [ "$no_cdn" = true ]; then
|
||||
azure_feed="$uncached_feed"
|
||||
fi
|
||||
|
||||
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"
|
||||
|
||||
check_min_reqs
|
||||
calculate_vars
|
||||
script_name=$(basename "$0")
|
||||
@@ -1068,7 +1196,7 @@ if [ "$dry_run" = true ]; then
|
||||
if [ "$valid_legacy_download_link" = true ]; then
|
||||
say "Legacy named payload URL: $legacy_download_link"
|
||||
fi
|
||||
repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"""
|
||||
repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
repeatable_command+=" --runtime "\""dotnet"\"""
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
@@ -1079,7 +1207,6 @@ if [ "$dry_run" = true ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
check_pre_reqs
|
||||
install_dotnet
|
||||
|
||||
bin_path="$(get_absolute_path "$(combine_paths "$install_root" "$bin_folder_relative_path")")"
|
||||
@@ -1090,4 +1217,6 @@ else
|
||||
say "Binaries of dotnet can be found in $bin_path"
|
||||
fi
|
||||
|
||||
say "Note that the script does not resolve dependencies during installation."
|
||||
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."
|
||||
|
||||
1676
package-lock.json
generated
1676
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
36
package.json
36
package.json
@@ -11,6 +11,13 @@
|
||||
"test": "jest",
|
||||
"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"
|
||||
@@ -23,26 +30,29 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.2.2",
|
||||
"@actions/exec": "^1.0.3",
|
||||
"@actions/core": "^1.2.6",
|
||||
"@actions/exec": "^1.0.4",
|
||||
"@actions/github": "^1.1.0",
|
||||
"@actions/http-client": "^1.0.8",
|
||||
"@actions/io": "^1.0.2",
|
||||
"@actions/tool-cache": "^1.3.1",
|
||||
"fast-xml-parser": "^3.15.1",
|
||||
"semver": "^6.3.0",
|
||||
"xmlbuilder": "^13.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^24.0.13",
|
||||
"@types/node": "^12.0.4",
|
||||
"@types/semver": "^6.0.0",
|
||||
"@zeit/ncc": "^0.21.0",
|
||||
"jest": "^26.0.1",
|
||||
"jest-circus": "^26.0.1",
|
||||
"prettier": "^1.17.1",
|
||||
"ts-jest": "^26.0.0",
|
||||
"typescript": "^3.9.2",
|
||||
"wget-improved": "^3.0.2"
|
||||
"@types/jest": "^25.2.3",
|
||||
"@types/node": "^12.12.62",
|
||||
"@types/semver": "^6.2.2",
|
||||
"@zeit/ncc": "^0.21.1",
|
||||
"husky": "^4.3.0",
|
||||
"jest": "^26.4.2",
|
||||
"jest-circus": "^26.4.2",
|
||||
"prettier": "^1.19.1",
|
||||
"ts-jest": "^26.4.0",
|
||||
"typescript": "^3.9.7",
|
||||
"wget-improved": "^3.2.1"
|
||||
},
|
||||
"jest": {
|
||||
"testEnvironment": "node"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,18 +4,22 @@ 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,
|
||||
existingFileLocation: string = ''
|
||||
existingFileLocation: string = '',
|
||||
processRoot: string = process.cwd()
|
||||
) {
|
||||
const existingNuGetConfig: string = path.resolve(
|
||||
process.env['RUNNER_TEMP'] || process.cwd(),
|
||||
existingFileLocation == '' ? 'nuget.config' : existingFileLocation
|
||||
processRoot,
|
||||
existingFileLocation === ''
|
||||
? getExistingNugetConfig(processRoot)
|
||||
: existingFileLocation
|
||||
);
|
||||
|
||||
const tempNuGetConfig: string = path.resolve(
|
||||
process.env['RUNNER_TEMP'] || process.cwd(),
|
||||
processRoot,
|
||||
'../',
|
||||
'nuget.config'
|
||||
);
|
||||
@@ -23,6 +27,21 @@ export function configAuthentication(
|
||||
writeFeedToFile(feedUrl, existingNuGetConfig, tempNuGetConfig);
|
||||
}
|
||||
|
||||
function isValidKey(key: string): boolean {
|
||||
return /^[\w\-\.]+$/i.test(key);
|
||||
}
|
||||
|
||||
function getExistingNugetConfig(processRoot: string) {
|
||||
const defaultConfigName = 'nuget.config';
|
||||
const configFileNames = fs
|
||||
.readdirSync(processRoot)
|
||||
.filter(filename => filename.toLowerCase() === defaultConfigName);
|
||||
if (configFileNames.length) {
|
||||
return configFileNames[0];
|
||||
}
|
||||
return defaultConfigName;
|
||||
}
|
||||
|
||||
function writeFeedToFile(
|
||||
feedUrl: string,
|
||||
existingFileLocation: string,
|
||||
@@ -107,9 +126,9 @@ function writeFeedToFile(
|
||||
xml = xml.ele('packageSourceCredentials');
|
||||
|
||||
sourceKeys.forEach(key => {
|
||||
if (key.indexOf(' ') > -1) {
|
||||
if (!isValidKey(key)) {
|
||||
throw new Error(
|
||||
"This action currently can't handle source names with spaces. Remove the space from your repo's NuGet.config and try again."
|
||||
"Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again."
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
463
src/installer.ts
463
src/installer.ts
@@ -1,40 +1,26 @@
|
||||
// Load tempDirectory before it gets wiped by tool-cache
|
||||
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import * as io from '@actions/io';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import hc = require('@actions/http-client');
|
||||
import {chmodSync} from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
||||
import * as semver from 'semver';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
if (!tempDirectory) {
|
||||
let baseLocation;
|
||||
if (IS_WINDOWS) {
|
||||
// On windows use the USERPROFILE env variable
|
||||
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
||||
} else {
|
||||
if (process.platform === 'darwin') {
|
||||
baseLocation = '/Users';
|
||||
} else {
|
||||
baseLocation = '/home';
|
||||
}
|
||||
}
|
||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the inputted version information
|
||||
*/
|
||||
export class DotNetVersionInfo {
|
||||
public inputVersion: string;
|
||||
private fullversion: string;
|
||||
private isExactVersionSet: boolean = false;
|
||||
|
||||
constructor(version: string) {
|
||||
this.inputVersion = version;
|
||||
|
||||
// Check for exact match
|
||||
if (semver.valid(semver.clean(version) || '') != null) {
|
||||
this.fullversion = semver.clean(version) as string;
|
||||
@@ -43,8 +29,7 @@ export class DotNetVersionInfo {
|
||||
return;
|
||||
}
|
||||
|
||||
//Note: No support for previews when using generic
|
||||
let parts: string[] = version.split('.');
|
||||
const parts: string[] = version.split('.');
|
||||
|
||||
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
|
||||
|
||||
@@ -52,8 +37,10 @@ export class DotNetVersionInfo {
|
||||
this.throwInvalidVersionFormat();
|
||||
}
|
||||
|
||||
let major = this.getVersionNumberOrThrow(parts[0]);
|
||||
let minor = this.getVersionNumberOrThrow(parts[1]);
|
||||
const major = this.getVersionNumberOrThrow(parts[0]);
|
||||
const minor = ['x', '*'].includes(parts[1])
|
||||
? parts[1]
|
||||
: this.getVersionNumberOrThrow(parts[1]);
|
||||
|
||||
this.fullversion = major + '.' + minor;
|
||||
}
|
||||
@@ -74,7 +61,9 @@ export class DotNetVersionInfo {
|
||||
}
|
||||
|
||||
private throwInvalidVersionFormat() {
|
||||
throw 'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*';
|
||||
throw new Error(
|
||||
'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,91 +78,55 @@ export class DotNetVersionInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a resolved version from the Web-Api
|
||||
*/
|
||||
class ResolvedVersionInfo {
|
||||
downloadUrls: string[];
|
||||
resolvedVersion: string;
|
||||
|
||||
constructor(downloadUrls: string[], resolvedVersion: string) {
|
||||
if (downloadUrls.length === 0) {
|
||||
throw 'DownloadUrls can not be empty';
|
||||
}
|
||||
|
||||
if (!resolvedVersion) {
|
||||
throw 'Resolved version is invalid';
|
||||
}
|
||||
|
||||
this.downloadUrls = downloadUrls;
|
||||
this.resolvedVersion = resolvedVersion;
|
||||
}
|
||||
}
|
||||
|
||||
export class DotnetCoreInstaller {
|
||||
constructor(version: string) {
|
||||
this.versionInfo = new DotNetVersionInfo(version);
|
||||
this.cachedToolName = 'dncs';
|
||||
this.arch = 'x64';
|
||||
constructor(version: string, includePrerelease: boolean = false) {
|
||||
this.version = version;
|
||||
this.includePrerelease = includePrerelease;
|
||||
}
|
||||
|
||||
public async installDotnet() {
|
||||
// Check cache
|
||||
let toolPath: string = '';
|
||||
let osSuffixes = await this.detectMachineOS();
|
||||
let parts = osSuffixes[0].split('-');
|
||||
if (parts.length > 1) {
|
||||
this.arch = parts[1];
|
||||
}
|
||||
|
||||
// If version is not generic -> look up cache
|
||||
if (this.versionInfo.isExactVersion())
|
||||
toolPath = this.getLocalTool(this.versionInfo.version());
|
||||
|
||||
if (!toolPath) {
|
||||
// download, extract, cache
|
||||
console.log('Getting a download url', this.versionInfo.version());
|
||||
let resolvedVersionInfo = await this.resolveInfos(
|
||||
osSuffixes,
|
||||
this.versionInfo
|
||||
);
|
||||
|
||||
//Check if cache exists for resolved version
|
||||
toolPath = this.getLocalTool(resolvedVersionInfo.resolvedVersion);
|
||||
if (!toolPath) {
|
||||
//If not exists install it
|
||||
toolPath = await this.downloadAndInstall(resolvedVersionInfo);
|
||||
} else {
|
||||
console.log('Using cached tool');
|
||||
}
|
||||
} else {
|
||||
console.log('Using cached tool');
|
||||
}
|
||||
|
||||
// Need to set this so that .NET Core global tools find the right locations.
|
||||
core.exportVariable('DOTNET_ROOT', toolPath);
|
||||
|
||||
// Prepend the tools path. instructs the agent to prepend for future tasks
|
||||
core.addPath(toolPath);
|
||||
}
|
||||
|
||||
private getLocalTool(version: string): string {
|
||||
console.log('Checking tool cache', version);
|
||||
return tc.find(this.cachedToolName, version, this.arch);
|
||||
}
|
||||
|
||||
private async detectMachineOS(): Promise<string[]> {
|
||||
let osSuffix: string[] = [];
|
||||
let output = '';
|
||||
|
||||
let resultCode = 0;
|
||||
|
||||
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', 'get-os-platform.ps1')
|
||||
.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}"`,
|
||||
[
|
||||
@@ -186,98 +139,68 @@ export class DotnetCoreInstaller {
|
||||
'-Command',
|
||||
command
|
||||
],
|
||||
{
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
output += data.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
options
|
||||
);
|
||||
} else {
|
||||
let scriptPath = path.join(
|
||||
__dirname,
|
||||
'..',
|
||||
'externals',
|
||||
'get-os-distro.sh'
|
||||
);
|
||||
chmodSync(scriptPath, '777');
|
||||
let escapedScript = path
|
||||
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||
.replace(/'/g, "''");
|
||||
chmodSync(escapedScript, '777');
|
||||
|
||||
const toolPath = await io.which(scriptPath, true);
|
||||
resultCode = await exec.exec(`"${toolPath}"`, [], {
|
||||
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 `Failed to detect os with result code ${resultCode}. Output: ${output}`;
|
||||
}
|
||||
|
||||
let index;
|
||||
if ((index = output.indexOf('Primary:')) >= 0) {
|
||||
let primary = output.substr(index + 'Primary:'.length).split(os.EOL)[0];
|
||||
osSuffix.push(primary);
|
||||
}
|
||||
|
||||
if ((index = output.indexOf('Legacy:')) >= 0) {
|
||||
let legacy = output.substr(index + 'Legacy:'.length).split(os.EOL)[0];
|
||||
osSuffix.push(legacy);
|
||||
}
|
||||
|
||||
if (osSuffix.length == 0) {
|
||||
throw 'Could not detect platform';
|
||||
}
|
||||
|
||||
return osSuffix;
|
||||
}
|
||||
|
||||
private async downloadAndInstall(resolvedVersionInfo: ResolvedVersionInfo) {
|
||||
let downloaded = false;
|
||||
let downloadPath = '';
|
||||
for (const url of resolvedVersionInfo.downloadUrls) {
|
||||
try {
|
||||
downloadPath = await tc.downloadTool(url);
|
||||
downloaded = true;
|
||||
break;
|
||||
} catch (error) {
|
||||
console.log('Could not Download', url, JSON.stringify(error));
|
||||
if (process.env['DOTNET_INSTALL_DIR']) {
|
||||
core.addPath(process.env['DOTNET_INSTALL_DIR']);
|
||||
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.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
|
||||
);
|
||||
} else {
|
||||
// This is the default set in install-dotnet.sh
|
||||
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
|
||||
core.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
path.join(process.env['HOME'] + '', '.dotnet')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!downloaded) {
|
||||
throw 'Failed to download package';
|
||||
console.log(process.env['PATH']);
|
||||
|
||||
if (resultCode != 0) {
|
||||
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
||||
}
|
||||
|
||||
// extract
|
||||
console.log('Extracting Package', downloadPath);
|
||||
let extPath: string = IS_WINDOWS
|
||||
? await tc.extractZip(downloadPath)
|
||||
: await tc.extractTar(downloadPath);
|
||||
|
||||
// cache tool
|
||||
console.log('Caching tool');
|
||||
let cachedDir = await tc.cacheDir(
|
||||
extPath,
|
||||
this.cachedToolName,
|
||||
resolvedVersionInfo.resolvedVersion,
|
||||
this.arch
|
||||
);
|
||||
|
||||
console.log('Successfully installed', resolvedVersionInfo.resolvedVersion);
|
||||
return cachedDir;
|
||||
}
|
||||
|
||||
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
|
||||
// Type - SDK / Runtime
|
||||
// versionInfo - versionInfo of the SDK/Runtime
|
||||
async resolveInfos(
|
||||
osSuffixes: string[],
|
||||
versionInfo: DotNetVersionInfo
|
||||
): Promise<ResolvedVersionInfo> {
|
||||
async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
|
||||
if (versionInfo.isExactVersion()) {
|
||||
return versionInfo.version();
|
||||
}
|
||||
|
||||
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
||||
allowRetries: true,
|
||||
maxRetries: 3
|
||||
@@ -293,79 +216,43 @@ export class DotnetCoreInstaller {
|
||||
let releasesInfo: any[] = releasesResult['releases'];
|
||||
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
|
||||
return (
|
||||
semver.satisfies(
|
||||
releaseInfo['sdk']['version'],
|
||||
versionInfo.version()
|
||||
) ||
|
||||
semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version(), {
|
||||
includePrerelease: this.includePrerelease
|
||||
}) ||
|
||||
semver.satisfies(
|
||||
releaseInfo['sdk']['version-display'],
|
||||
versionInfo.version()
|
||||
versionInfo.version(),
|
||||
{
|
||||
includePrerelease: this.includePrerelease
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// Exclude versions that are newer than the latest if using not exact
|
||||
if (!versionInfo.isExactVersion()) {
|
||||
let latestSdk: string = releasesResult['latest-sdk'];
|
||||
let latestSdk: string = releasesResult['latest-sdk'];
|
||||
|
||||
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
|
||||
semver.lte(releaseInfo['sdk']['version'], latestSdk)
|
||||
);
|
||||
}
|
||||
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'])
|
||||
semver.rcompare(a['sdk']['version'], b['sdk']['version'], {
|
||||
includePrerelease: this.includePrerelease
|
||||
})
|
||||
);
|
||||
|
||||
let downloadedVersion: string = '';
|
||||
let downloadUrls: string[] = [];
|
||||
|
||||
if (releasesInfo.length != 0) {
|
||||
let release = releasesInfo[0];
|
||||
|
||||
downloadedVersion = release['sdk']['version'];
|
||||
|
||||
let files: any[] = release['sdk']['files'];
|
||||
files = files.filter((file: any) => {
|
||||
if (file['rid'] == osSuffixes[0] || file['rid'] == osSuffixes[1]) {
|
||||
return (
|
||||
file['url'].endsWith('.zip') || file['url'].endsWith('.tar.gz')
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
if (files.length > 0) {
|
||||
files.forEach((file: any) => {
|
||||
downloadUrls.push(file['url']);
|
||||
});
|
||||
} else {
|
||||
throw `The specified version's download links are not correctly formed in the supported versions document => ${releasesJsonUrl}`;
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
`Could not fetch download information for version ${versionInfo.version()}`
|
||||
if (releasesInfo.length == 0) {
|
||||
throw new Error(
|
||||
`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`
|
||||
);
|
||||
|
||||
if (versionInfo.isExactVersion()) {
|
||||
console.log('Using fallback');
|
||||
|
||||
downloadUrls = await this.getFallbackDownloadUrls(
|
||||
versionInfo.version()
|
||||
);
|
||||
downloadedVersion = versionInfo.version();
|
||||
} else {
|
||||
console.log('Unable to use fallback, version is generic!');
|
||||
}
|
||||
}
|
||||
|
||||
if (downloadUrls.length == 0) {
|
||||
throw `Could not construct download URL. Please ensure that specified version ${versionInfo.version()}/${downloadedVersion} is valid.`;
|
||||
}
|
||||
|
||||
core.debug(`Got download urls ${downloadUrls}`);
|
||||
|
||||
return new ResolvedVersionInfo(downloadUrls, downloadedVersion);
|
||||
let release = releasesInfo[0];
|
||||
return release['sdk']['version'];
|
||||
}
|
||||
|
||||
private async getReleasesJsonUrl(
|
||||
@@ -375,124 +262,32 @@ export class DotnetCoreInstaller {
|
||||
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') {
|
||||
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 `Could not find info for version ${versionParts.join(
|
||||
'.'
|
||||
)} at ${DotNetCoreIndexUrl}`;
|
||||
throw new Error(
|
||||
`Could not find info for version ${versionParts.join(
|
||||
'.'
|
||||
)} at ${DotNetCoreIndexUrl}`
|
||||
);
|
||||
}
|
||||
|
||||
return releasesInfo[0]['releases.json'];
|
||||
}
|
||||
|
||||
private async getFallbackDownloadUrls(version: string): Promise<string[]> {
|
||||
let primaryUrlSearchString: string;
|
||||
let legacyUrlSearchString: string;
|
||||
let output = '';
|
||||
let resultCode = 0;
|
||||
|
||||
if (IS_WINDOWS) {
|
||||
let escapedScript = path
|
||||
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||
.replace(/'/g, "''");
|
||||
let command = `& '${escapedScript}' -Version ${version} -DryRun`;
|
||||
|
||||
const powershellPath = await io.which('powershell', true);
|
||||
resultCode = await exec.exec(
|
||||
`"${powershellPath}"`,
|
||||
[
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
'-NoProfile',
|
||||
'-NonInteractive',
|
||||
'-ExecutionPolicy',
|
||||
'Unrestricted',
|
||||
'-Command',
|
||||
command
|
||||
],
|
||||
{
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
output += data.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
||||
} else {
|
||||
let escapedScript = path
|
||||
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||
.replace(/'/g, "''");
|
||||
chmodSync(escapedScript, '777');
|
||||
|
||||
const scriptPath = await io.which(escapedScript, true);
|
||||
resultCode = await exec.exec(
|
||||
`"${scriptPath}"`,
|
||||
['--version', version, '--dry-run'],
|
||||
{
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => {
|
||||
output += data.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
||||
}
|
||||
|
||||
if (resultCode != 0) {
|
||||
throw `Failed to get download urls with result code ${resultCode}. ${output}`;
|
||||
}
|
||||
|
||||
let primaryUrl: string = '';
|
||||
let legacyUrl: string = '';
|
||||
if (!!output && output.length > 0) {
|
||||
let lines: string[] = output.split(os.EOL);
|
||||
|
||||
// Fallback to \n if initial split doesn't work (not consistent across versions)
|
||||
if (lines.length === 1) {
|
||||
lines = output.split('\n');
|
||||
}
|
||||
if (!!lines && lines.length > 0) {
|
||||
lines.forEach((line: string) => {
|
||||
if (!line) {
|
||||
return;
|
||||
}
|
||||
var primarySearchStringIndex = line.indexOf(primaryUrlSearchString);
|
||||
if (primarySearchStringIndex > -1) {
|
||||
primaryUrl = line.substring(
|
||||
primarySearchStringIndex + primaryUrlSearchString.length
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var legacySearchStringIndex = line.indexOf(legacyUrlSearchString);
|
||||
if (legacySearchStringIndex > -1) {
|
||||
legacyUrl = line.substring(
|
||||
legacySearchStringIndex + legacyUrlSearchString.length
|
||||
);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return [primaryUrl, legacyUrl];
|
||||
}
|
||||
|
||||
private versionInfo: DotNetVersionInfo;
|
||||
private cachedToolName: string;
|
||||
private arch: string;
|
||||
private version: string;
|
||||
private includePrerelease: boolean;
|
||||
}
|
||||
|
||||
const DotNetCoreIndexUrl: string =
|
||||
|
||||
@@ -7,20 +7,21 @@ import * as auth from './authutil';
|
||||
export async function run() {
|
||||
try {
|
||||
//
|
||||
// Version is optional. If supplied, install / use from the tool cache
|
||||
// If not supplied then task is still used to setup proxy, auth, etc...
|
||||
// dotnet-version is optional, but needs to be provided for most use cases.
|
||||
// If supplied, install / use from the tool cache.
|
||||
// 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 version: string = core.getInput('version');
|
||||
if (!version) {
|
||||
version = core.getInput('dotnet-version');
|
||||
}
|
||||
let version = core.getInput('dotnet-version');
|
||||
if (!version) {
|
||||
// Try to fall back to global.json
|
||||
core.debug('No version found, trying to find version from global.json');
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
if (fs.existsSync(globalJsonPath)) {
|
||||
const globalJson = JSON.parse(
|
||||
fs.readFileSync(globalJsonPath, {encoding: 'utf8'})
|
||||
// .trim() is necessary to strip BOM https://github.com/nodejs/node/issues/20649
|
||||
fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim()
|
||||
);
|
||||
if (globalJson.sdk && globalJson.sdk.version) {
|
||||
version = globalJson.sdk.version;
|
||||
@@ -29,7 +30,14 @@ export async function run() {
|
||||
}
|
||||
|
||||
if (version) {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
||||
const includePrerelease: boolean =
|
||||
(core.getInput('include-prerelease') || 'false').toLowerCase() ===
|
||||
'true';
|
||||
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||
version,
|
||||
includePrerelease
|
||||
);
|
||||
await dotnetInstaller.installDotnet();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user