You've already forked setup-dotnet
mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-07-14 02:50:31 +07:00
Compare commits
90 Commits
v-malob/up
...
v1.8.2
Author | SHA1 | Date | |
---|---|---|---|
5a3fa01c67 | |||
f2da928c08 | |||
fb9fd97b03 | |||
f0b9e4cf3f | |||
b66058b059 | |||
7323c4e7cb | |||
6eab455d72 | |||
b2cf6c7cd4 | |||
ff5b78971e | |||
e26fc623bc | |||
e974974b42 | |||
9969bca445 | |||
deee0f6246 | |||
33fad1d142 | |||
2c3efd1f04 | |||
f3822c3b02 | |||
5e45b4b591 | |||
b7b99f337e | |||
f92687c910 | |||
0067f023d2 | |||
9480036ff9 | |||
6b8ad2e725 | |||
078f7c4a73 | |||
13fd5bf191 | |||
26be14c4e1 | |||
8309d4ee7e | |||
bab14f40fd | |||
4b337272b7 | |||
d62c876481 | |||
5306333434 | |||
5070486392 | |||
9647326bcf | |||
f720d14d91 | |||
7f3ad75595 | |||
634914df32 | |||
4fc55d8fdb | |||
c98cd238db | |||
b25fa305a3 | |||
181f10df92 | |||
c65a26fe6d | |||
dd9ada314c | |||
12194cb2cd | |||
b8ab602c41 | |||
95f03216f8 | |||
5529ce4143 | |||
5b0ff19756 | |||
bf3c3eb1fd | |||
450b569534 | |||
e1cf912aaf | |||
03d6eb5402 | |||
effa3e26d2 | |||
a71d1eb2c8 | |||
b50d70502b | |||
d8cff32ae5 | |||
7b2009794e | |||
53d6483af8 | |||
34c59b7d0b | |||
bd485b6bd1 | |||
0cfae9b3a5 | |||
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 | |||
768b4eb7db | |||
ba7e1e2155 | |||
9fdd50a4bb |
51
.github/workflows/check-dist.yml
vendored
Normal file
51
.github/workflows/check-dist.yml
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
# `dist/index.js` is a special file in Actions.
|
||||
# When you reference an action with `uses:` in a workflow,
|
||||
# `index.js` is the code that will run.
|
||||
# For our project, we generate this file through a build process from other source files.
|
||||
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||
name: Check dist/
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
check-dist:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js 12.x
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 12.x
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Rebuild the dist/ directory
|
||||
run: npm run build
|
||||
|
||||
- name: Compare the expected and actual dist/ directories
|
||||
run: |
|
||||
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||
echo "Detected uncommitted changes after build. See status below:"
|
||||
git diff
|
||||
exit 1
|
||||
fi
|
||||
id: diff
|
||||
|
||||
# If index.js was different than expected, upload the expected version as an artifact
|
||||
- uses: actions/upload-artifact@v2
|
||||
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
10
.github/workflows/licensed.yml
vendored
10
.github/workflows/licensed.yml
vendored
@ -1,8 +1,12 @@
|
||||
name: Licensed
|
||||
|
||||
on:
|
||||
push: {branches: main}
|
||||
pull_request: {branches: main}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
test:
|
||||
@ -17,4 +21,4 @@ jobs:
|
||||
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
|
||||
- run: licensed status
|
||||
|
28
.github/workflows/release-new-action-version.yml
vendored
Normal file
28
.github/workflows/release-new-action-version.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
name: Release new action version
|
||||
on:
|
||||
release:
|
||||
types: [released]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
TAG_NAME:
|
||||
description: 'Tag name that the major tag will point to'
|
||||
required: true
|
||||
|
||||
env:
|
||||
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
update_tag:
|
||||
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||
environment:
|
||||
name: releaseNewActionVersion
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Update the ${{ env.TAG_NAME }} tag
|
||||
id: update-major-tag
|
||||
uses: actions/publish-action@v0.1.0
|
||||
with:
|
||||
source-tag: ${{ env.TAG_NAME }}
|
||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
37
README.md
37
README.md
@ -13,7 +13,7 @@ This action sets up a [dotnet core cli](https://github.com/dotnet/cli) environme
|
||||
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://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners)
|
||||
[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
|
||||
@ -23,13 +23,24 @@ See [action.yml](action.yml)
|
||||
Basic:
|
||||
```yaml
|
||||
steps:
|
||||
- uses: actions/checkout@main
|
||||
- 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:
|
||||
@ -37,7 +48,7 @@ jobs:
|
||||
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@v2
|
||||
@ -59,7 +70,7 @@ jobs:
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '2.2.103'
|
||||
dotnet-version: '2.1.x'
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
@ -82,10 +93,10 @@ steps:
|
||||
- run: dotnet build <my project>
|
||||
- name: Create the package
|
||||
run: dotnet pack --configuration Release <my project>
|
||||
- name: Publish the package to GPR
|
||||
- name: Publish the package to GPR
|
||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||
|
||||
# Authticates packages to push to Azure Artifacts
|
||||
# Authenticates packages to push to Azure Artifacts
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
||||
@ -93,11 +104,21 @@ steps:
|
||||
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
||||
- name: Publish the package to Azure Artifacts
|
||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||
|
||||
# Authenticates packages to push to nuget.org.
|
||||
# It's only the way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
|
||||
- uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.x
|
||||
- name: Publish the package to nuget.org
|
||||
run: dotnet nuget push */bin/Release/*.nupkg -k $NUGET_AUTH_TOKEN -s https://api.nuget.org/v3/index.json
|
||||
env:
|
||||
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
||||
```
|
||||
|
||||
## Environment Variables to use with dotnet
|
||||
|
||||
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet#environment-variables
|
||||
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
|
||||
|
||||
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false)
|
||||
- DOTNET_CLI_TELEMETRY_OPTOUT - opt-out of telemetry being sent to Microsoft (default: false)
|
||||
@ -113,7 +134,7 @@ build:
|
||||
- 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
|
||||
|
@ -1,13 +1,13 @@
|
||||
$dotnetPaths = @{
|
||||
Linux = @("/usr/share/dotnet")
|
||||
macOS = @("$env:HOME/.dotnet")
|
||||
Windows = @("$env:ProgramFiles\dotnet/*",
|
||||
"$env:LocalAppData\Microsoft\dotnet/*")
|
||||
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
|
||||
foreach ($srcPath in $dotnetPaths[$args[0]]) {
|
||||
if (Test-Path $srcPath) {
|
||||
Write-Host "Move $srcPath path"
|
||||
$dstPath = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
|
||||
Move-Item -Path $srcPath -Destination $dstPath
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ const toolDir = path.join(__dirname, 'runner', 'tools2');
|
||||
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||
|
||||
import * as setup from '../src/setup-dotnet';
|
||||
import * as dotnetInstaller from '../src/installer';
|
||||
|
||||
const IS_WINDOWS = process.platform === 'win32';
|
||||
|
||||
@ -19,7 +20,7 @@ describe('setup-dotnet tests', () => {
|
||||
await io.rmRF(tempDir);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
afterEach(async () => {
|
||||
try {
|
||||
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
||||
await io.rmRF(toolDir);
|
||||
@ -44,4 +45,26 @@ describe('setup-dotnet tests', () => {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
}, 400000);
|
||||
|
||||
it('Acquires version of dotnet from global.json with rollForward option, install the latest patch', async () => {
|
||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version":"3.1.201",${os.EOL}"rollForward":"latestFeature"${os.EOL}}${os.EOL}}`;
|
||||
if (!fs.existsSync(globalJsonPath)) {
|
||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||
}
|
||||
|
||||
const version = '3.1';
|
||||
const installer = new dotnetInstaller.DotnetCoreInstaller(version);
|
||||
const patchVersion = await installer.resolveVersion(
|
||||
new dotnetInstaller.DotNetVersionInfo(version)
|
||||
);
|
||||
await setup.run();
|
||||
|
||||
expect(fs.existsSync(path.join(toolDir, 'sdk', patchVersion))).toBe(true);
|
||||
if (IS_WINDOWS) {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||
} else {
|
||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||
}
|
||||
}, 400000);
|
||||
});
|
||||
|
@ -13,6 +13,8 @@ describe('version tests', () => {
|
||||
);
|
||||
|
||||
each([
|
||||
['3.x', '3.x'],
|
||||
['3.*', '3.*'],
|
||||
['3.1.x', '3.1'],
|
||||
['1.1.*', '1.1'],
|
||||
['2.0', '2.0']
|
||||
@ -42,7 +44,6 @@ describe('version tests', () => {
|
||||
'.2.3',
|
||||
'.2.x',
|
||||
'1',
|
||||
'2.x',
|
||||
'*.*.1',
|
||||
'*.1',
|
||||
'*.',
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: 'Setup .NET Core SDK'
|
||||
description: 'Set up a specific version of the .NET Core CLI in the PATH and set up authentication to a private NuGet repository'
|
||||
description: 'Used to build and publish .NET source. Set up a specific version of the .NET and authentication to private NuGet repository'
|
||||
author: 'GitHub'
|
||||
branding:
|
||||
icon: play
|
||||
@ -13,6 +13,9 @@ inputs:
|
||||
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
|
||||
config-file:
|
||||
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
|
||||
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'
|
||||
|
81
dist/index.js
vendored
81
dist/index.js
vendored
@ -4840,11 +4840,26 @@ const github = __importStar(__webpack_require__(469));
|
||||
const xmlbuilder = __importStar(__webpack_require__(312));
|
||||
const xmlParser = __importStar(__webpack_require__(989));
|
||||
function configAuthentication(feedUrl, existingFileLocation = '', processRoot = process.cwd()) {
|
||||
const existingNuGetConfig = path.resolve(processRoot, existingFileLocation == '' ? 'nuget.config' : existingFileLocation);
|
||||
const existingNuGetConfig = path.resolve(processRoot, existingFileLocation === ''
|
||||
? getExistingNugetConfig(processRoot)
|
||||
: existingFileLocation);
|
||||
const tempNuGetConfig = path.resolve(processRoot, '../', 'nuget.config');
|
||||
writeFeedToFile(feedUrl, existingNuGetConfig, tempNuGetConfig);
|
||||
}
|
||||
exports.configAuthentication = configAuthentication;
|
||||
function isValidKey(key) {
|
||||
return /^[\w\-\.]+$/i.test(key);
|
||||
}
|
||||
function getExistingNugetConfig(processRoot) {
|
||||
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, existingFileLocation, tempFileLocation) {
|
||||
console.log(`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`);
|
||||
let xml;
|
||||
@ -4910,8 +4925,8 @@ function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) {
|
||||
}
|
||||
xml = xml.ele('packageSourceCredentials');
|
||||
sourceKeys.forEach(key => {
|
||||
if (key.indexOf(' ') > -1) {
|
||||
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.");
|
||||
if (!isValidKey(key)) {
|
||||
throw new Error("Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again.");
|
||||
}
|
||||
xml = xml
|
||||
.ele(key)
|
||||
@ -7814,14 +7829,13 @@ function run() {
|
||||
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' }));
|
||||
if (globalJson.sdk && globalJson.sdk.version) {
|
||||
version = globalJson.sdk.version;
|
||||
}
|
||||
version = getVersionFromGlobalJson(globalJsonPath);
|
||||
}
|
||||
}
|
||||
if (version) {
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
||||
const includePrerelease = (core.getInput('include-prerelease') || 'false').toLowerCase() ===
|
||||
'true';
|
||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version, includePrerelease);
|
||||
yield dotnetInstaller.installDotnet();
|
||||
}
|
||||
const sourceUrl = core.getInput('source-url');
|
||||
@ -7838,6 +7852,21 @@ function run() {
|
||||
});
|
||||
}
|
||||
exports.run = run;
|
||||
function getVersionFromGlobalJson(globalJsonPath) {
|
||||
let version = '';
|
||||
const globalJson = JSON.parse(
|
||||
// .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;
|
||||
const rollForward = globalJson.sdk.rollForward;
|
||||
if (rollForward && rollForward === 'latestFeature') {
|
||||
const [major, minor] = version.split('.');
|
||||
version = `${major}.${minor}`;
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
run();
|
||||
|
||||
|
||||
@ -16868,15 +16897,16 @@ class DotNetVersionInfo {
|
||||
this.isExactVersionSet = true;
|
||||
return;
|
||||
}
|
||||
//Note: No support for previews when using generic
|
||||
let parts = version.split('.');
|
||||
const parts = version.split('.');
|
||||
if (parts.length < 2 || parts.length > 3)
|
||||
this.throwInvalidVersionFormat();
|
||||
if (parts.length == 3 && parts[2] !== 'x' && parts[2] !== '*') {
|
||||
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;
|
||||
}
|
||||
getVersionNumberOrThrow(input) {
|
||||
@ -16894,7 +16924,7 @@ class DotNetVersionInfo {
|
||||
}
|
||||
}
|
||||
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.*');
|
||||
}
|
||||
/**
|
||||
* If true exacatly one version should be resolved
|
||||
@ -16908,8 +16938,9 @@ class DotNetVersionInfo {
|
||||
}
|
||||
exports.DotNetVersionInfo = DotNetVersionInfo;
|
||||
class DotnetCoreInstaller {
|
||||
constructor(version) {
|
||||
constructor(version, includePrerelease = false) {
|
||||
this.version = version;
|
||||
this.includePrerelease = includePrerelease;
|
||||
}
|
||||
installDotnet() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
@ -16997,7 +17028,7 @@ class DotnetCoreInstaller {
|
||||
}
|
||||
console.log(process.env['PATH']);
|
||||
if (resultCode != 0) {
|
||||
throw `Failed to install dotnet ${resultCode}. ${output}`;
|
||||
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -17016,16 +17047,24 @@ class DotnetCoreInstaller {
|
||||
const releasesResult = releasesResponse.result || {};
|
||||
let releasesInfo = releasesResult['releases'];
|
||||
releasesInfo = releasesInfo.filter((releaseInfo) => {
|
||||
return (semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version()) ||
|
||||
semver.satisfies(releaseInfo['sdk']['version-display'], versionInfo.version()));
|
||||
return (semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version(), {
|
||||
includePrerelease: this.includePrerelease
|
||||
}) ||
|
||||
semver.satisfies(releaseInfo['sdk']['version-display'], versionInfo.version(), {
|
||||
includePrerelease: this.includePrerelease
|
||||
}));
|
||||
});
|
||||
// Exclude versions that are newer than the latest if using not exact
|
||||
let latestSdk = releasesResult['latest-sdk'];
|
||||
releasesInfo = releasesInfo.filter((releaseInfo) => semver.lte(releaseInfo['sdk']['version'], latestSdk));
|
||||
releasesInfo = releasesInfo.filter((releaseInfo) => 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']));
|
||||
releasesInfo = releasesInfo.sort((a, b) => semver.rcompare(a['sdk']['version'], b['sdk']['version'], {
|
||||
includePrerelease: this.includePrerelease
|
||||
}));
|
||||
if (releasesInfo.length == 0) {
|
||||
throw `Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`;
|
||||
throw new Error(`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`);
|
||||
}
|
||||
let release = releasesInfo[0];
|
||||
return release['sdk']['version'];
|
||||
@ -17046,7 +17085,7 @@ class DotnetCoreInstaller {
|
||||
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'];
|
||||
});
|
||||
|
723
externals/install-dotnet.ps1
vendored
723
externals/install-dotnet.ps1
vendored
@ -16,15 +16,27 @@
|
||||
- LTS - most current supported release
|
||||
- 2-part version in a format A.B - represents a specific release
|
||||
examples: 2.0, 1.0
|
||||
- Branch name
|
||||
examples: release/2.0.0, Master
|
||||
Note: The version parameter overrides the channel parameter.
|
||||
- 3-part version in a format A.B.Cxx - represents a specific SDK release
|
||||
examples: 5.0.1xx, 5.0.2xx
|
||||
Supported since 5.0 release
|
||||
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used.
|
||||
.PARAMETER Quality
|
||||
Download the latest build of specified quality in the channel. The possible values are: daily, signed, validated, preview, GA.
|
||||
Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used.
|
||||
For SDK use channel in A.B.Cxx format: using quality together with channel in A.B format is not supported.
|
||||
Supported since 5.0 release.
|
||||
Note: The version parameter overrides the channel parameter when any version other than 'latest' is used, and therefore overrides the quality.
|
||||
.PARAMETER Version
|
||||
Default: latest
|
||||
Represents a build version on specific channel. Possible values:
|
||||
- latest - most latest build on specific channel
|
||||
- 3-part version in a format A.B.C - represents specific version of build
|
||||
examples: 2.0.0-preview2-006120, 1.1.0
|
||||
.PARAMETER Internal
|
||||
Download internal builds. Requires providing credentials via -FeedCredential parameter.
|
||||
.PARAMETER FeedCredential
|
||||
Token to access Azure feed. Used as a query string to append to the Azure feed.
|
||||
This parameter typically is not specified.
|
||||
.PARAMETER InstallDir
|
||||
Default: %LocalAppData%\Microsoft\dotnet
|
||||
Path to where to install dotnet. Note that binaries will be placed directly in a given directory.
|
||||
@ -59,9 +71,6 @@
|
||||
.PARAMETER UncachedFeed
|
||||
This parameter typically is not changed by the user.
|
||||
It allows changing the URL for the Uncached feed used by this installer.
|
||||
.PARAMETER FeedCredential
|
||||
Used as a query string to append to the Azure feed.
|
||||
It allows changing the URL to use non-public blob storage accounts.
|
||||
.PARAMETER ProxyAddress
|
||||
If set, the installer will use the proxy when making web requests
|
||||
.PARAMETER ProxyUseDefaultCredentials
|
||||
@ -77,15 +86,19 @@
|
||||
.PARAMETER JSonFile
|
||||
Determines the SDK version from a user specified global.json file
|
||||
Note: global.json must have a value for 'SDK:Version'
|
||||
.PARAMETER DownloadTimeout
|
||||
Determines timeout duration in seconds for dowloading of the SDK file
|
||||
Default: 1200 seconds (20 minutes)
|
||||
#>
|
||||
[cmdletbinding()]
|
||||
param(
|
||||
[string]$Channel="LTS",
|
||||
[string]$Quality,
|
||||
[string]$Version="Latest",
|
||||
[switch]$Internal,
|
||||
[string]$JSonFile,
|
||||
[string]$InstallDir="<auto>",
|
||||
[Alias('i')][string]$InstallDir="<auto>",
|
||||
[string]$Architecture="<auto>",
|
||||
[ValidateSet("dotnet", "aspnetcore", "windowsdesktop", IgnoreCase = $false)]
|
||||
[string]$Runtime,
|
||||
[Obsolete("This parameter may be removed in a future version of this script. The recommended alternative is '-Runtime dotnet'.")]
|
||||
[switch]$SharedRuntime,
|
||||
@ -98,7 +111,8 @@ param(
|
||||
[switch]$ProxyUseDefaultCredentials,
|
||||
[string[]]$ProxyBypassList=@(),
|
||||
[switch]$SkipNonVersionedFiles,
|
||||
[switch]$NoCdn
|
||||
[switch]$NoCdn,
|
||||
[int]$DownloadTimeout=1200
|
||||
)
|
||||
|
||||
Set-StrictMode -Version Latest
|
||||
@ -167,7 +181,7 @@ function Say-Invocation($Invocation) {
|
||||
Say-Verbose "$command $args"
|
||||
}
|
||||
|
||||
function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) {
|
||||
function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [System.Threading.CancellationToken]$cancellationToken = [System.Threading.CancellationToken]::None, [int]$MaxAttempts = 3, [int]$SecondsBetweenAttempts = 1) {
|
||||
$Attempts = 0
|
||||
|
||||
while ($true) {
|
||||
@ -176,7 +190,7 @@ function Invoke-With-Retry([ScriptBlock]$ScriptBlock, [int]$MaxAttempts = 3, [in
|
||||
}
|
||||
catch {
|
||||
$Attempts++
|
||||
if ($Attempts -lt $MaxAttempts) {
|
||||
if (($Attempts -lt $MaxAttempts) -and -not $cancellationToken.IsCancellationRequested) {
|
||||
Start-Sleep $SecondsBetweenAttempts
|
||||
}
|
||||
else {
|
||||
@ -205,7 +219,7 @@ function Get-Machine-Architecture() {
|
||||
function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
switch ($Architecture.ToLower()) {
|
||||
switch ($Architecture.ToLowerInvariant()) {
|
||||
{ $_ -eq "<auto>" } { return Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture) }
|
||||
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
|
||||
{ $_ -eq "x86" } { return "x86" }
|
||||
@ -215,6 +229,53 @@ function Get-CLIArchitecture-From-Architecture([string]$Architecture) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function Get-NormalizedQuality([string]$Quality) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if ([string]::IsNullOrEmpty($Quality)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
switch ($Quality) {
|
||||
{ @("daily", "signed", "validated", "preview") -contains $_ } { return $Quality.ToLowerInvariant() }
|
||||
#ga quality is available without specifying quality, so normalizing it to empty
|
||||
{ $_ -eq "ga" } { return "" }
|
||||
default { throw "'$Quality' is not a supported value for -Quality option. Supported values are: daily, signed, validated, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." }
|
||||
}
|
||||
}
|
||||
|
||||
function Get-NormalizedChannel([string]$Channel) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if ([string]::IsNullOrEmpty($Channel)) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if ($Channel.StartsWith('release/')) {
|
||||
Say-Warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead, such as "-Channel 5.0 -Quality Daily."'
|
||||
}
|
||||
|
||||
switch ($Channel) {
|
||||
{ $_ -eq "lts" } { return "LTS" }
|
||||
{ $_ -eq "current" } { return "current" }
|
||||
default { return $Channel.ToLowerInvariant() }
|
||||
}
|
||||
}
|
||||
|
||||
function Get-NormalizedProduct([string]$Runtime) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
switch ($Runtime) {
|
||||
{ $_ -eq "dotnet" } { return "dotnet-runtime" }
|
||||
{ $_ -eq "aspnetcore" } { return "aspnetcore-runtime" }
|
||||
{ $_ -eq "windowsdesktop" } { return "windowsdesktop-runtime" }
|
||||
{ [string]::IsNullOrEmpty($_) } { return "dotnet-sdk" }
|
||||
default { throw "'$Runtime' is not a supported value for -Runtime option, supported values are: dotnet, aspnetcore, windowsdesktop. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# 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
|
||||
@ -243,10 +304,11 @@ function Load-Assembly([string] $Assembly) {
|
||||
}
|
||||
}
|
||||
|
||||
function GetHTTPResponse([Uri] $Uri)
|
||||
function GetHTTPResponse([Uri] $Uri, [bool]$HeaderOnly, [bool]$DisableRedirect, [bool]$DisableFeedCredential)
|
||||
{
|
||||
Invoke-With-Retry(
|
||||
{
|
||||
$cts = New-Object System.Threading.CancellationTokenSource
|
||||
|
||||
$downloadScript = {
|
||||
|
||||
$HttpClient = $null
|
||||
|
||||
@ -270,32 +332,53 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
}
|
||||
}
|
||||
|
||||
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
|
||||
if($ProxyAddress) {
|
||||
$HttpClientHandler = New-Object System.Net.Http.HttpClientHandler
|
||||
$HttpClientHandler.Proxy = New-Object System.Net.WebProxy -Property @{
|
||||
Address=$ProxyAddress;
|
||||
UseDefaultCredentials=$ProxyUseDefaultCredentials;
|
||||
BypassList = $ProxyBypassList;
|
||||
}
|
||||
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
||||
}
|
||||
if ($DisableRedirect)
|
||||
{
|
||||
$HttpClientHandler.AllowAutoRedirect = $false
|
||||
}
|
||||
$HttpClient = New-Object System.Net.Http.HttpClient -ArgumentList $HttpClientHandler
|
||||
|
||||
# Default timeout for HttpClient is 100s. For a 50 MB download this assumes 500 KB/s average, any less will time out
|
||||
# Defaulting to 20 minutes allows it to work over much slower connections.
|
||||
$HttpClient.Timeout = New-TimeSpan -Seconds $DownloadTimeout
|
||||
|
||||
if ($HeaderOnly){
|
||||
$completionOption = [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead
|
||||
}
|
||||
else {
|
||||
|
||||
$HttpClient = New-Object System.Net.Http.HttpClient
|
||||
$completionOption = [System.Net.Http.HttpCompletionOption]::ResponseContentRead
|
||||
}
|
||||
# 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
|
||||
$Task = $HttpClient.GetAsync("${Uri}${FeedCredential}").ConfigureAwait("false");
|
||||
|
||||
if ($DisableFeedCredential) {
|
||||
$UriWithCredential = $Uri
|
||||
}
|
||||
else {
|
||||
$UriWithCredential = "${Uri}${FeedCredential}"
|
||||
}
|
||||
|
||||
$Task = $HttpClient.GetAsync("$UriWithCredential", $completionOption).ConfigureAwait("false");
|
||||
$Response = $Task.GetAwaiter().GetResult();
|
||||
|
||||
if (($null -eq $Response) -or (-not ($Response.IsSuccessStatusCode))) {
|
||||
if (($null -eq $Response) -or ((-not $HeaderOnly) -and (-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"]
|
||||
|
||||
if (404 -eq [int] $Response.StatusCode)
|
||||
{
|
||||
$cts.Cancel()
|
||||
}
|
||||
}
|
||||
|
||||
throw $DownloadException
|
||||
@ -323,11 +406,22 @@ function GetHTTPResponse([Uri] $Uri)
|
||||
throw $DownloadException
|
||||
}
|
||||
finally {
|
||||
if ($HttpClient -ne $null) {
|
||||
if ($null -ne $HttpClient) {
|
||||
$HttpClient.Dispose()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
return Invoke-With-Retry $downloadScript $cts.Token
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($null -ne $cts)
|
||||
{
|
||||
$cts.Dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) {
|
||||
@ -349,6 +443,9 @@ function Get-Latest-Version-Info([string]$AzureFeed, [string]$Channel) {
|
||||
else {
|
||||
throw "Invalid value for `$Runtime"
|
||||
}
|
||||
|
||||
Say-Verbose "Constructed latest.version URL: $VersionFileUrl"
|
||||
|
||||
try {
|
||||
$Response = GetHTTPResponse -Uri $VersionFileUrl
|
||||
}
|
||||
@ -411,7 +508,7 @@ function Get-Specific-Version-From-Version([string]$AzureFeed, [string]$Channel,
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if (-not $JSonFile) {
|
||||
if ($Version.ToLower() -eq "latest") {
|
||||
if ($Version.ToLowerInvariant() -eq "latest") {
|
||||
$LatestVersionInfo = Get-Latest-Version-Info -AzureFeed $AzureFeed -Channel $Channel
|
||||
return $LatestVersionInfo.Version
|
||||
}
|
||||
@ -478,58 +575,116 @@ function Get-LegacyDownload-Link([string]$AzureFeed, [string]$SpecificVersion, [
|
||||
return $PayloadURL
|
||||
}
|
||||
|
||||
function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion) {
|
||||
function Get-Product-Version([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink) {
|
||||
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"
|
||||
# Try to get the version number, using the productVersion.txt file located next to the installer file.
|
||||
$ProductVersionTxtURLs = (Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $true),
|
||||
(Get-Product-Version-Url $AzureFeed $SpecificVersion $PackageDownloadLink -Flattened $false)
|
||||
|
||||
Foreach ($ProductVersionTxtURL in $ProductVersionTxtURLs) {
|
||||
Say-Verbose "Checking for the 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) when trying to get productVersion.txt at $productVersionTxtUrl."
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl (Exception: '$($_.Exception.Message)'. )"
|
||||
}
|
||||
}
|
||||
elseif (-not $Runtime) {
|
||||
$ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/productVersion.txt"
|
||||
}
|
||||
else {
|
||||
throw "Invalid value '$Runtime' specified for `$Runtime"
|
||||
|
||||
# Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
|
||||
if ([string]::IsNullOrEmpty($PackageDownloadLink))
|
||||
{
|
||||
Say-Verbose "Using the default value '$SpecificVersion' as the product version."
|
||||
return $SpecificVersion
|
||||
}
|
||||
|
||||
Say-Verbose "Checking for existence of $ProductVersionTxtURL"
|
||||
$productVersion = Get-ProductVersionFromDownloadLink $PackageDownloadLink $SpecificVersion
|
||||
return $productVersion
|
||||
}
|
||||
|
||||
try {
|
||||
$productVersionResponse = GetHTTPResponse($productVersionTxtUrl)
|
||||
function Get-Product-Version-Url([string]$AzureFeed, [string]$SpecificVersion, [string]$PackageDownloadLink, [bool]$Flattened) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
if ($productVersionResponse.StatusCode -eq 200) {
|
||||
$productVersion = $productVersionResponse.Content.ReadAsStringAsync().Result.Trim()
|
||||
if ($productVersion -ne $SpecificVersion)
|
||||
{
|
||||
Say "Using alternate version $productVersion found in $ProductVersionTxtURL"
|
||||
}
|
||||
$majorVersion=$null
|
||||
if ($SpecificVersion -match '^(\d+)\.(.*)') {
|
||||
$majorVersion = $Matches[1] -as[int]
|
||||
}
|
||||
|
||||
return $productVersion
|
||||
$pvFileName='productVersion.txt'
|
||||
if($Flattened) {
|
||||
if(-not $Runtime) {
|
||||
$pvFileName='sdk-productVersion.txt'
|
||||
}
|
||||
elseif($Runtime -eq "dotnet") {
|
||||
$pvFileName='runtime-productVersion.txt'
|
||||
}
|
||||
else {
|
||||
Say-Verbose "Got StatusCode $($productVersionResponse.StatusCode) trying to get productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion"
|
||||
$productVersion = $SpecificVersion
|
||||
$pvFileName="$Runtime-productVersion.txt"
|
||||
}
|
||||
} catch {
|
||||
Say-Verbose "Could not read productVersion.txt at $productVersionTxtUrl, so using default value of $SpecificVersion (Exception: '$($_.Exception.Message)' )"
|
||||
$productVersion = $SpecificVersion
|
||||
}
|
||||
|
||||
return $productVersion
|
||||
if ([string]::IsNullOrEmpty($PackageDownloadLink)) {
|
||||
if ($Runtime -eq "dotnet") {
|
||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/$pvFileName"
|
||||
}
|
||||
elseif ($Runtime -eq "aspnetcore") {
|
||||
$ProductVersionTxtURL = "$AzureFeed/aspnetcore/Runtime/$SpecificVersion/$pvFileName"
|
||||
}
|
||||
elseif ($Runtime -eq "windowsdesktop") {
|
||||
# The windows desktop runtime is part of the core runtime layout prior to 5.0
|
||||
$ProductVersionTxtURL = "$AzureFeed/Runtime/$SpecificVersion/$pvFileName"
|
||||
if ($majorVersion -ne $null -and $majorVersion -ge 5) {
|
||||
$ProductVersionTxtURL = "$AzureFeed/WindowsDesktop/$SpecificVersion/$pvFileName"
|
||||
}
|
||||
}
|
||||
elseif (-not $Runtime) {
|
||||
$ProductVersionTxtURL = "$AzureFeed/Sdk/$SpecificVersion/$pvFileName"
|
||||
}
|
||||
else {
|
||||
throw "Invalid value '$Runtime' specified for `$Runtime"
|
||||
}
|
||||
}
|
||||
else {
|
||||
$ProductVersionTxtURL = $PackageDownloadLink.Substring(0, $PackageDownloadLink.LastIndexOf("/")) + "/$pvFileName"
|
||||
}
|
||||
|
||||
Say-Verbose "Constructed productVersion link: $ProductVersionTxtURL"
|
||||
|
||||
return $ProductVersionTxtURL
|
||||
}
|
||||
|
||||
function Get-ProductVersionFromDownloadLink([string]$PackageDownloadLink, [string]$SpecificVersion)
|
||||
{
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
#product specific version follows the product name
|
||||
#for filename 'dotnet-sdk-3.1.404-win-x64.zip': the product version is 3.1.400
|
||||
$filename = $PackageDownloadLink.Substring($PackageDownloadLink.LastIndexOf("/") + 1)
|
||||
$filenameParts = $filename.Split('-')
|
||||
if ($filenameParts.Length -gt 2)
|
||||
{
|
||||
$productVersion = $filenameParts[2]
|
||||
Say-Verbose "Extracted product version '$productVersion' from download link '$PackageDownloadLink'."
|
||||
}
|
||||
else {
|
||||
Say-Verbose "Using the default value '$SpecificVersion' as the product version."
|
||||
$productVersion = $SpecificVersion
|
||||
}
|
||||
return $productVersion
|
||||
}
|
||||
|
||||
function Get-User-Share-Path() {
|
||||
@ -702,15 +857,150 @@ function Prepend-Sdk-InstallRoot-To-Path([string]$InstallRoot, [string]$BinFolde
|
||||
}
|
||||
}
|
||||
|
||||
function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
|
||||
Say-Invocation $MyInvocation
|
||||
|
||||
#quality is not supported for LTS or current channel
|
||||
if (![string]::IsNullOrEmpty($Quality) -and (@("LTS", "current") -contains $Channel)) {
|
||||
$Quality = ""
|
||||
Say-Warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored."
|
||||
}
|
||||
Say-Verbose "Retrieving primary payload URL from aka.ms link for channel: '$Channel', quality: '$Quality' product: '$Product', os: 'win', architecture: '$Architecture'."
|
||||
|
||||
#construct aka.ms link
|
||||
$akaMsLink = "https://aka.ms/dotnet"
|
||||
if ($Internal) {
|
||||
$akaMsLink += "/internal"
|
||||
}
|
||||
$akaMsLink += "/$Channel"
|
||||
if (-not [string]::IsNullOrEmpty($Quality)) {
|
||||
$akaMsLink +="/$Quality"
|
||||
}
|
||||
$akaMsLink +="/$Product-win-$Architecture.zip"
|
||||
Say-Verbose "Constructed aka.ms link: '$akaMsLink'."
|
||||
$akaMsDownloadLink=$null
|
||||
|
||||
for ($maxRedirections = 9; $maxRedirections -ge 0; $maxRedirections--)
|
||||
{
|
||||
#get HTTP response
|
||||
#do not pass credentials as a part of the $akaMsLink and do not apply credentials in the GetHTTPResponse function
|
||||
#otherwise the redirect link would have credentials as well
|
||||
#it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link
|
||||
$Response= GetHTTPResponse -Uri $akaMsLink -HeaderOnly $true -DisableRedirect $true -DisableFeedCredential $true
|
||||
Say-Verbose "Received response:`n$Response"
|
||||
|
||||
if ([string]::IsNullOrEmpty($Response)) {
|
||||
Say-Verbose "The link '$akaMsLink' is not valid: failed to get redirect location. The resource is not available."
|
||||
return $null
|
||||
}
|
||||
|
||||
#if HTTP code is 301 (Moved Permanently), the redirect link exists
|
||||
if ($Response.StatusCode -eq 301)
|
||||
{
|
||||
try {
|
||||
$akaMsDownloadLink = $Response.Headers.GetValues("Location")[0]
|
||||
|
||||
if ([string]::IsNullOrEmpty($akaMsDownloadLink)) {
|
||||
Say-Verbose "The link '$akaMsLink' is not valid: server returned 301 (Moved Permanently), but the headers do not contain the redirect location."
|
||||
return $null
|
||||
}
|
||||
|
||||
Say-Verbose "The redirect location retrieved: '$akaMsDownloadLink'."
|
||||
# This may yet be a link to another redirection. Attempt to retrieve the page again.
|
||||
$akaMsLink = $akaMsDownloadLink
|
||||
continue
|
||||
}
|
||||
catch {
|
||||
Say-Verbose "The link '$akaMsLink' is not valid: failed to get redirect location."
|
||||
return $null
|
||||
}
|
||||
}
|
||||
elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink)))
|
||||
{
|
||||
# Redirections have ended.
|
||||
return $akaMsDownloadLink
|
||||
}
|
||||
|
||||
Say-Verbose "The link '$akaMsLink' is not valid: failed to retrieve the redirection location."
|
||||
return $null
|
||||
}
|
||||
|
||||
Say-Verbose "Aka.ms links have redirected more than the maximum allowed redirections. This may be caused by a cyclic redirection of aka.ms links."
|
||||
return $null
|
||||
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
if ($Internal -and [string]::IsNullOrWhitespace($FeedCredential)) {
|
||||
$message = "Provide credentials via -FeedCredential parameter."
|
||||
if ($DryRun) {
|
||||
Say-Warning "$message"
|
||||
} else {
|
||||
throw "$message"
|
||||
}
|
||||
}
|
||||
|
||||
#FeedCredential should start with "?", for it to be added to the end of the link.
|
||||
#adding "?" at the beginning of the FeedCredential if needed.
|
||||
if ((![string]::IsNullOrWhitespace($FeedCredential)) -and ($FeedCredential[0] -ne '?')) {
|
||||
$FeedCredential = "?" + $FeedCredential
|
||||
}
|
||||
|
||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $Architecture
|
||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
||||
$DownloadLink, $EffectiveVersion = Get-Download-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
$LegacyDownloadLink = Get-LegacyDownload-Link -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -CLIArchitecture $CLIArchitecture
|
||||
$NormalizedQuality = Get-NormalizedQuality $Quality
|
||||
Say-Verbose "Normalized quality: '$NormalizedQuality'"
|
||||
$NormalizedChannel = Get-NormalizedChannel $Channel
|
||||
Say-Verbose "Normalized channel: '$NormalizedChannel'"
|
||||
$NormalizedProduct = Get-NormalizedProduct $Runtime
|
||||
Say-Verbose "Normalized product: '$NormalizedProduct'"
|
||||
$DownloadLink = $null
|
||||
|
||||
#try to get download location from aka.ms link
|
||||
#not applicable when exact version is specified via command or json file
|
||||
if ([string]::IsNullOrEmpty($JSonFile) -and ($Version -eq "latest")) {
|
||||
$AkaMsDownloadLink = Get-AkaMSDownloadLink -Channel $NormalizedChannel -Quality $NormalizedQuality -Internal $Internal -Product $NormalizedProduct -Architecture $CLIArchitecture
|
||||
|
||||
if ([string]::IsNullOrEmpty($AkaMsDownloadLink)){
|
||||
if (-not [string]::IsNullOrEmpty($NormalizedQuality)) {
|
||||
# if quality is specified - exit with error - there is no fallback approach
|
||||
Say-Error "Failed to locate the latest version in the channel '$NormalizedChannel' with '$NormalizedQuality' quality for '$NormalizedProduct', os: 'win', architecture: '$CLIArchitecture'."
|
||||
Say-Error "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support."
|
||||
throw "aka.ms link resolution failure"
|
||||
}
|
||||
Say-Verbose "Falling back to latest.version file approach."
|
||||
}
|
||||
else {
|
||||
Say-Verbose "Retrieved primary named payload URL from aka.ms link: '$AkaMsDownloadLink'."
|
||||
$DownloadLink = $AkaMsDownloadLink
|
||||
Say-Verbose "Downloading using legacy url will not be attempted."
|
||||
$LegacyDownloadLink = $null
|
||||
|
||||
#get version from the path
|
||||
$pathParts = $DownloadLink.Split('/')
|
||||
if ($pathParts.Length -ge 2) {
|
||||
$SpecificVersion = $pathParts[$pathParts.Length - 2]
|
||||
Say-Verbose "Version: '$SpecificVersion'."
|
||||
}
|
||||
else {
|
||||
Say-Error "Failed to extract the version from download link '$DownloadLink'."
|
||||
}
|
||||
|
||||
#retrieve effective (product) version
|
||||
$EffectiveVersion = Get-Product-Version -AzureFeed $AzureFeed -SpecificVersion $SpecificVersion -PackageDownloadLink $DownloadLink
|
||||
Say-Verbose "Product version: '$EffectiveVersion'."
|
||||
}
|
||||
}
|
||||
|
||||
if ([string]::IsNullOrEmpty($DownloadLink)) {
|
||||
$SpecificVersion = Get-Specific-Version-From-Version -AzureFeed $AzureFeed -Channel $Channel -Version $Version -JSonFile $JSonFile
|
||||
$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
|
||||
Say-Verbose "InstallRoot: $InstallRoot"
|
||||
@ -718,9 +1008,9 @@ $ScriptName = $MyInvocation.MyCommand.Name
|
||||
|
||||
if ($DryRun) {
|
||||
Say "Payload URLs:"
|
||||
Say "Primary named payload URL: $DownloadLink"
|
||||
Say "Primary named payload URL: ${DownloadLink}"
|
||||
if ($LegacyDownloadLink) {
|
||||
Say "Legacy named payload URL: $LegacyDownloadLink"
|
||||
Say "Legacy named payload URL: ${LegacyDownloadLink}"
|
||||
}
|
||||
$RepeatableCommand = ".\$ScriptName -Version `"$SpecificVersion`" -InstallDir `"$InstallRoot`" -Architecture `"$CLIArchitecture`""
|
||||
if ($Runtime -eq "dotnet") {
|
||||
@ -729,11 +1019,20 @@ if ($DryRun) {
|
||||
elseif ($Runtime -eq "aspnetcore") {
|
||||
$RepeatableCommand+=" -Runtime `"aspnetcore`""
|
||||
}
|
||||
|
||||
if (-not [string]::IsNullOrEmpty($NormalizedQuality))
|
||||
{
|
||||
$RepeatableCommand+=" -Quality `"$NormalizedQuality`""
|
||||
}
|
||||
|
||||
foreach ($key in $MyInvocation.BoundParameters.Keys) {
|
||||
if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version") -contains $key)) {
|
||||
if (-not (@("Architecture","Channel","DryRun","InstallDir","Runtime","SharedRuntime","Version","Quality","FeedCredential") -contains $key)) {
|
||||
$RepeatableCommand+=" -$key `"$($MyInvocation.BoundParameters[$key])`""
|
||||
}
|
||||
}
|
||||
if ($MyInvocation.BoundParameters.Keys -contains "FeedCredential") {
|
||||
$RepeatableCommand+=" -FeedCredential `"<feedCredential>`""
|
||||
}
|
||||
Say "Repeatable invocation: $RepeatableCommand"
|
||||
if ($SpecificVersion -ne $EffectiveVersion)
|
||||
{
|
||||
@ -779,9 +1078,16 @@ if ($isAssetInstalled) {
|
||||
|
||||
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) {
|
||||
$installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
|
||||
$diskInfo = $null
|
||||
try{
|
||||
$diskInfo = Get-PSDrive -Name $installDrive
|
||||
}
|
||||
catch{
|
||||
Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space."
|
||||
}
|
||||
|
||||
if ( ($diskInfo -ne $null) -and ($diskInfo.Free / 1MB -le 100)) {
|
||||
throw "There is not enough disk space on drive ${installDrive}:"
|
||||
}
|
||||
|
||||
@ -901,43 +1207,44 @@ Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot -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"
|
||||
|
||||
# SIG # Begin signature block
|
||||
# MIIjjwYJKoZIhvcNAQcCoIIjgDCCI3wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||
# MIIjhgYJKoZIhvcNAQcCoIIjdzCCI3MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
||||
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCNsnhcJvx/hXmM
|
||||
# w8KjuvvIMDBFonhg9XJFc1QwfTyH4aCCDYEwggX/MIID56ADAgECAhMzAAABh3IX
|
||||
# chVZQMcJAAAAAAGHMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDO8obeUp97UA1H
|
||||
# qy3NSLDwxxLLlEbGxeCzMOcKVT/3eKCCDYEwggX/MIID56ADAgECAhMzAAAB32vw
|
||||
# LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
||||
# bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ3WhcNMjEwMzAzMTgzOTQ3WjB0MQsw
|
||||
# bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw
|
||||
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
||||
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
||||
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
||||
# AQDOt8kLc7P3T7MKIhouYHewMFmnq8Ayu7FOhZCQabVwBp2VS4WyB2Qe4TQBT8aB
|
||||
# znANDEPjHKNdPT8Xz5cNali6XHefS8i/WXtF0vSsP8NEv6mBHuA2p1fw2wB/F0dH
|
||||
# sJ3GfZ5c0sPJjklsiYqPw59xJ54kM91IOgiO2OUzjNAljPibjCWfH7UzQ1TPHc4d
|
||||
# weils8GEIrbBRb7IWwiObL12jWT4Yh71NQgvJ9Fn6+UhD9x2uk3dLj84vwt1NuFQ
|
||||
# itKJxIV0fVsRNR3abQVOLqpDugbr0SzNL6o8xzOHL5OXiGGwg6ekiXA1/2XXY7yV
|
||||
# Fc39tledDtZjSjNbex1zzwSXAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
||||
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhov4ZyO96axkJdMjpzu2zVXOJcsw
|
||||
# AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn
|
||||
# s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw
|
||||
# PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS
|
||||
# yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG
|
||||
# 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh
|
||||
# EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
||||
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw
|
||||
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
||||
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU4Mzg1MB8GA1UdIwQYMBaAFEhu
|
||||
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu
|
||||
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
|
||||
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
|
||||
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
|
||||
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
|
||||
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAixmy
|
||||
# S6E6vprWD9KFNIB9G5zyMuIjZAOuUJ1EK/Vlg6Fb3ZHXjjUwATKIcXbFuFC6Wr4K
|
||||
# NrU4DY/sBVqmab5AC/je3bpUpjtxpEyqUqtPc30wEg/rO9vmKmqKoLPT37svc2NV
|
||||
# BmGNl+85qO4fV/w7Cx7J0Bbqk19KcRNdjt6eKoTnTPHBHlVHQIHZpMxacbFOAkJr
|
||||
# qAVkYZdz7ikNXTxV+GRb36tC4ByMNxE2DF7vFdvaiZP0CVZ5ByJ2gAhXMdK9+usx
|
||||
# zVk913qKde1OAuWdv+rndqkAIm8fUlRnr4saSCg7cIbUwCCf116wUJ7EuJDg0vHe
|
||||
# yhnCeHnBbyH3RZkHEi2ofmfgnFISJZDdMAeVZGVOh20Jp50XBzqokpPzeZ6zc1/g
|
||||
# yILNyiVgE+RPkjnUQshd1f1PMgn3tns2Cz7bJiVUaqEO3n9qRFgy5JuLae6UweGf
|
||||
# AeOo3dgLZxikKzYs3hDMaEtJq8IP71cX7QXe6lnMmXU/Hdfz2p897Zd+kU+vZvKI
|
||||
# 3cwLfuVQgK2RZ2z+Kc3K3dRPz2rXycK5XCuRZmvGab/WbrZiC7wJQapgBodltMI5
|
||||
# GMdFrBg9IeF7/rP4EqVQXeKtevTlZXjpuNhhjuR+2DMt/dWufjXpiW91bo3aH6Ea
|
||||
# jOALXmoxgltCp1K7hrS6gmsvj94cLRf50QQ4U8Qwggd6MIIFYqADAgECAgphDpDS
|
||||
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH
|
||||
# tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS
|
||||
# 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp
|
||||
# TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok
|
||||
# t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4
|
||||
# b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao
|
||||
# mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD
|
||||
# Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt
|
||||
# VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G
|
||||
# CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+
|
||||
# Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82
|
||||
# oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS
|
||||
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
|
||||
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
|
||||
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
|
||||
@ -977,119 +1284,119 @@ Say "Installation finished"
|
||||
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
||||
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
||||
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVZDCCFWACAQEwgZUwfjELMAkG
|
||||
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWzCCFVcCAQEwgZUwfjELMAkG
|
||||
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
||||
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
||||
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAYdyF3IVWUDHCQAAAAABhzAN
|
||||
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN
|
||||
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgpT/bxWwe
|
||||
# aW0EinKMWCAzDXUjwXkIHldYzR6lw4/1Pc0wQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
||||
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg7EExOCvj
|
||||
# ZDkub0Fc7HAVivJIlz+Omt11fROkTFKR+KQwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
||||
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
||||
# BgkqhkiG9w0BAQEFAASCAQCHd7sSQVq0YDg8QDx6/kLWn3s6jtvvIDCCgsO9spHM
|
||||
# quPd4FPbG67DCsKDClekQs52qrtRO3Zo+JMnCw4j3bS+gZHzeJr2shbftOrpsFoD
|
||||
# l7OPcUmtrqul9dkQCOp8t0MP3ls0n96/YyNy6lz4BAlTdkdDx957uAxalKaCIBzb
|
||||
# R9QyppOKIfNFvwD4EI5KI6tpmSy/uH8SrRg7ZExAYZl6J6R18WkL7KHn649lPoAQ
|
||||
# ujwrIXH10xOJops45ILGzKWQcHmCzLJGYapL4VHUuK+73nT+9ZROGHdk/PyvIcdw
|
||||
# iERa+C06v305t3DA+CuHFy1tvyw7IFF6RVbLZPwxrJjToYIS7jCCEuoGCisGAQQB
|
||||
# gjcDAwExghLaMIIS1gYJKoZIhvcNAQcCoIISxzCCEsMCAQMxDzANBglghkgBZQME
|
||||
# AgEFADCCAVUGCyqGSIb3DQEJEAEEoIIBRASCAUAwggE8AgEBBgorBgEEAYRZCgMB
|
||||
# MDEwDQYJYIZIAWUDBAIBBQAEIOCaTmvM1AP0WaEVqzKaaCu/R+bTlR4kCrM/ZXsb
|
||||
# /eNOAgZgGeLsMwsYEzIwMjEwMjAzMjExNzQ5LjU5MVowBIACAfSggdSkgdEwgc4x
|
||||
# BgkqhkiG9w0BAQEFAASCAQBPvflyU+HQEIM4XvImAK2eQp74ABDaxeWVbl21ZF0L
|
||||
# cKf5GkIzdvlCoKxforXBkRIBtLxU9Sb4ff+AO3jiw2M36ZLwZQRYcn003FTR3BAY
|
||||
# 3XVGdxb64vCEMUb6Dzh9Hb1lmJjyn2NHsB514ZuUez4v/UIsV9e3TV731kY6gcQV
|
||||
# 3ridn3IKj3RMJGtPD5qxVMZohvVIy1Xiz4n/9BpBkk4HHsSuGPmBj08jWnIcI5TF
|
||||
# eXYC4LonTOFZLcsKiW4eMRaDt0fXxJjhQF8DSJX3PAxCC73YkPrJJyXAkGNHcXCg
|
||||
# 2Lyi9Yd6oV0nbJlCSLWK7jcn5lxUIgsrb+U6F8yXoNsXoYIS5TCCEuEGCisGAQQB
|
||||
# gjcDAwExghLRMIISzQYJKoZIhvcNAQcCoIISvjCCEroCAQMxDzANBglghkgBZQME
|
||||
# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB
|
||||
# MDEwDQYJYIZIAWUDBAIBBQAEIEwFz8qgqbYKKOXyaZMOTE0/ve/rpdJjnq1eyDVG
|
||||
# mWB6AgZhHpsDT9wYEzIwMjEwODIzMTUxNzA2LjAyMVowBIACAfSggdCkgc0wgcox
|
||||
# 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
|
||||
# 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=
|
||||
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p
|
||||
# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg
|
||||
# RVNOOjhBODItRTM0Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
|
||||
# cCBTZXJ2aWNloIIOPDCCBPEwggPZoAMCAQICEzMAAAFLT7KmSNXkwlEAAAAAAUsw
|
||||
# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
|
||||
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
|
||||
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
|
||||
# MjAxMTEyMTgyNTU5WhcNMjIwMjExMTgyNTU5WjCByjELMAkGA1UEBhMCVVMxEzAR
|
||||
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
|
||||
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg
|
||||
# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlE
|
||||
# REExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0G
|
||||
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChNnpQx3YuJr/ivobPoLtpQ9egUFl8
|
||||
# THdWZ6SAKIJdtP3L24D3/d63ommmjZjCyrQm+j/1tHDAwjQGuOwYvn79ecPCQfAB
|
||||
# 91JnEp/wP4BMF2SXyMf8k9R84RthIdfGHPXTWqzpCCfNWolVEcUVm8Ad/r1LrikR
|
||||
# O+4KKo6slDQJKsgKApfBU/9J7Rudvhw1rEQw0Nk1BRGWjrIp7/uWoUIfR4rcl6U1
|
||||
# utOiYIonC87PPpAJQXGRsDdKnVFF4NpWvMiyeuksn5t/Otwz82sGlne/HNQpmMzi
|
||||
# gR8cZ8eXEDJJNIZxov9WAHHj28gUE29D8ivAT706ihxvTv50ZY8W51uxAgMBAAGj
|
||||
# ggEbMIIBFzAdBgNVHQ4EFgQUUqpqftASlue6K3LePlTTn01K68YwHwYDVR0jBBgw
|
||||
# FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov
|
||||
# L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB
|
||||
# XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0
|
||||
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx
|
||||
# MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN
|
||||
# BgkqhkiG9w0BAQsFAAOCAQEAFtq51Zc/O1AfJK4tEB2Nr8bGEVD5qQ8l8gXIQMrM
|
||||
# ZYtddHH+cGiqgF/4GmvmPfl5FAYh+gf/8Yd3q4/iD2+K4LtJbs/3v6mpyBl1mQ4v
|
||||
# usK65dAypWmiT1W3FiXjsmCIkjSDDsKLFBYH5yGFnNFOEMgL+O7u4osH42f80nc2
|
||||
# WdnZV6+OvW035XPV6ZttUBfFWHdIbUkdOG1O2n4yJm10OfacItZ08fzgMMqE+f/S
|
||||
# TgVWNCHbR2EYqTWayrGP69jMwtVD9BGGTWti1XjpvE6yKdO8H9nuRi3L+C6jYntf
|
||||
# aEmBTbnTFEV+kRx1CNcpSb9os86CAUehZU1aRzQ6CQ/pjzCCBnEwggRZoAMCAQIC
|
||||
# CmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD
|
||||
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
||||
# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRp
|
||||
# ZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIx
|
||||
# NDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
|
||||
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG
|
||||
# A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3
|
||||
# DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF
|
||||
# ++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRD
|
||||
# DNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSx
|
||||
# z5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1
|
||||
# rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16Hgc
|
||||
# sOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB
|
||||
# 4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqF
|
||||
# bVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
|
||||
# EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYD
|
||||
# VR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv
|
||||
# cHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEB
|
||||
# BE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j
|
||||
# ZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCB
|
||||
# kjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jv
|
||||
# c29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQe
|
||||
# MiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQA
|
||||
# LiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUx
|
||||
# vs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GAS
|
||||
# inbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1
|
||||
# L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWO
|
||||
# M7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4
|
||||
# pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45
|
||||
# V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x
|
||||
# 4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEe
|
||||
# gPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKn
|
||||
# QqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp
|
||||
# 3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvT
|
||||
# X4/edIhJEqGCAs4wggI3AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEG
|
||||
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
|
||||
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
|
||||
# cGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo4QTgyLUUzNEYtOURE
|
||||
# QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcG
|
||||
# BSsOAwIaAxUAkToz97fseHxNOUSQ5O/bBVSF+e6ggYMwgYCkfjB8MQswCQYDVQQG
|
||||
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
||||
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
|
||||
# VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOTNtrcwIhgPMjAy
|
||||
# MTA4MjMxMzU1MDNaGA8yMDIxMDgyNDEzNTUwM1owdzA9BgorBgEEAYRZCgQBMS8w
|
||||
# LTAKAgUA5M22twIBADAKAgEAAgIcfAIB/zAHAgEAAgIQOTAKAgUA5M8INwIBADA2
|
||||
# BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB
|
||||
# AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBADrUnASEIEovjIFdqxhyYsyiBSfNeD7e
|
||||
# W4qeRl1B4DTAY8Z/U1SpnK8yy7r6oZn0D8og+QJmnWEnCPqNXAreyg8tlFyTF1TV
|
||||
# K6uUlslIY4WCmrAECIFua/DuksTerny66SBw4aSEeQHtGiynnR87WcdqItBJxxRA
|
||||
# pElXzs8QzC0EMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
||||
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
||||
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
||||
# IDIwMTACEzMAAAFLT7KmSNXkwlEAAAAAAUswDQYJYIZIAWUDBAIBBQCgggFKMBoG
|
||||
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg87M/Jiqh
|
||||
# MlaXNWAIAn7CM9CZw6QCPgBx3voUSIH6+qUwgfoGCyqGSIb3DQEJEAIvMYHqMIHn
|
||||
# MIHkMIG9BCBr9u6EInnsZYEts/Fj/rIFv0YZW1ynhXKOP2hVPUU5IzCBmDCBgKR+
|
||||
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
||||
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
||||
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABS0+ypkjV5MJRAAAA
|
||||
# AAFLMCIEIGs9Mn51TUGRleeUO5lQCRHZSu0G/8Ir92l3NgMGq1/GMA0GCSqGSIb3
|
||||
# DQEBCwUABIIBAA1oBIiM3guh89/Pvwwcn4hdZGGBsMk56MRMvOir8XQM0Je/rSwP
|
||||
# P11S2VwYUMmBjfFX1QK7r280k3k9xcDWW79ZC4Kn2UsV7jxuUwFHgdVlgDNjg6QL
|
||||
# unGuwFX5lStgNevwUH9DotoASXxgtwNNmtZNDB4NYVCxQLS7RtVSbxP+xFYXbokG
|
||||
# G4DFVHBr3CGPga3OduE/YUBpxIRxtiDF/9WHo0tJEdS95tfdnsyaGo8eHNzyfTdS
|
||||
# kjrNsAlqpJRT0Va/ooBXCV7Uny7PlCkRIQRTSJDy/kSXpsL22CTEHw6mU0jEU99k
|
||||
# OL4uwu+aVnolWFlpbiJjQxBqfT3plBLIg88=
|
||||
# SIG # End signature block
|
||||
|
428
externals/install-dotnet.sh
vendored
428
externals/install-dotnet.sh
vendored
@ -24,7 +24,7 @@ exec 3>&1
|
||||
# See if stdout is a terminal
|
||||
if [ -t 1 ] && command -v tput > /dev/null; then
|
||||
# see if it supports colors
|
||||
ncolors=$(tput colors)
|
||||
ncolors=$(tput colors || echo 0)
|
||||
if [ -n "$ncolors" ] && [ $ncolors -ge 8 ]; then
|
||||
bold="$(tput bold || echo)"
|
||||
normal="$(tput sgr0 || echo)"
|
||||
@ -368,6 +368,75 @@ get_normalized_os() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# quality - $1
|
||||
get_normalized_quality() {
|
||||
eval $invocation
|
||||
|
||||
local quality="$(to_lowercase "$1")"
|
||||
if [ ! -z "$quality" ]; then
|
||||
case "$quality" in
|
||||
daily | signed | validated | preview)
|
||||
echo "$quality"
|
||||
return 0
|
||||
;;
|
||||
ga)
|
||||
#ga quality is available without specifying quality, so normalizing it to empty
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
say_err "'$quality' is not a supported value for --quality option. Supported values are: daily, signed, validated, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# channel - $1
|
||||
get_normalized_channel() {
|
||||
eval $invocation
|
||||
|
||||
local channel="$(to_lowercase "$1")"
|
||||
|
||||
if [[ $channel == release/* ]]; then
|
||||
say_warning 'Using branch name with -Channel option is no longer supported with newer releases. Use -Quality option with a channel in X.Y format instead.';
|
||||
fi
|
||||
|
||||
if [ ! -z "$channel" ]; then
|
||||
case "$channel" in
|
||||
lts)
|
||||
echo "LTS"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
echo "$channel"
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# runtime - $1
|
||||
get_normalized_product() {
|
||||
eval $invocation
|
||||
|
||||
local runtime="$(to_lowercase "$1")"
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
product="dotnet-runtime"
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
product="aspnetcore-runtime"
|
||||
elif [ -z "$runtime" ]; then
|
||||
product="dotnet-sdk"
|
||||
fi
|
||||
echo "$product"
|
||||
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
|
||||
@ -541,43 +610,131 @@ construct_download_link() {
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# specific_version - $2
|
||||
# download link - $3 (optional)
|
||||
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.
|
||||
# if 'productVersion.txt' is missing but download link is already available, product version will be taken from download link
|
||||
eval $invocation
|
||||
|
||||
local azure_feed="$1"
|
||||
local specific_version="${2//[$'\t\r\n']}"
|
||||
local specific_product_version=$specific_version
|
||||
local package_download_link=""
|
||||
if [ $# -gt 2 ]; then
|
||||
local package_download_link="$3"
|
||||
fi
|
||||
local specific_product_version=null
|
||||
|
||||
# Try to get the version number, using the productVersion.txt file located next to the installer file.
|
||||
local download_links=($(get_specific_product_version_url "$azure_feed" "$specific_version" true "$package_download_link")
|
||||
$(get_specific_product_version_url "$azure_feed" "$specific_version" false "$package_download_link"))
|
||||
|
||||
for download_link in "${download_links[@]}"
|
||||
do
|
||||
say_verbose "Checking for the existence of $download_link"
|
||||
|
||||
if machine_has "curl"
|
||||
then
|
||||
specific_product_version=$(curl -s --fail "${download_link}${feed_credential}")
|
||||
if [ $? = 0 ]; then
|
||||
echo "${specific_product_version//[$'\t\r\n']}"
|
||||
return 0
|
||||
fi
|
||||
elif machine_has "wget"
|
||||
then
|
||||
specific_product_version=$(wget -qO- "${download_link}${feed_credential}")
|
||||
if [ $? = 0 ]; then
|
||||
echo "${specific_product_version//[$'\t\r\n']}"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Getting the version number with productVersion.txt has failed. Try parsing the download link for a version number.
|
||||
say_verbose "Failed to get the version using productVersion.txt file. Download link will be parsed instead."
|
||||
specific_product_version="$(get_product_specific_version_from_download_link "$package_download_link" "$specific_version")"
|
||||
echo "${specific_product_version//[$'\t\r\n']}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# azure_feed - $1
|
||||
# specific_version - $2
|
||||
# is_flattened - $3
|
||||
# download link - $4 (optional)
|
||||
get_specific_product_version_url() {
|
||||
eval $invocation
|
||||
|
||||
local azure_feed="$1"
|
||||
local specific_version="$2"
|
||||
local is_flattened="$3"
|
||||
local package_download_link=""
|
||||
if [ $# -gt 3 ]; then
|
||||
local package_download_link="$4"
|
||||
fi
|
||||
|
||||
local pvFileName="productVersion.txt"
|
||||
if [ "$is_flattened" = true ]; then
|
||||
if [ -z "$runtime" ]; then
|
||||
pvFileName="sdk-productVersion.txt"
|
||||
elif [[ "$runtime" == "dotnet" ]]; then
|
||||
pvFileName="runtime-productVersion.txt"
|
||||
else
|
||||
pvFileName="$runtime-productVersion.txt"
|
||||
fi
|
||||
fi
|
||||
|
||||
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}"
|
||||
|
||||
if [ -z "$package_download_link" ]; then
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
download_link="$azure_feed/Runtime/$specific_version/${pvFileName}"
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
download_link="$azure_feed/aspnetcore/Runtime/$specific_version/${pvFileName}"
|
||||
elif [ -z "$runtime" ]; then
|
||||
download_link="$azure_feed/Sdk/$specific_version/${pvFileName}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
download_link="${package_download_link%/*}/${pvFileName}"
|
||||
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']}"
|
||||
say_verbose "Constructed productVersion link: $download_link"
|
||||
echo "$download_link"
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# download link - $1
|
||||
# specific version - $2
|
||||
get_product_specific_version_from_download_link()
|
||||
{
|
||||
eval $invocation
|
||||
|
||||
local download_link="$1"
|
||||
local specific_version="$2"
|
||||
local specific_product_version=""
|
||||
|
||||
if [ -z "$download_link" ]; then
|
||||
echo "$specific_version"
|
||||
return 0
|
||||
fi
|
||||
|
||||
#get filename
|
||||
filename="${download_link##*/}"
|
||||
|
||||
#product specific version follows the product name
|
||||
#for filename 'dotnet-sdk-3.1.404-linux-x64.tar.gz': the product version is 3.1.404
|
||||
IFS='-'
|
||||
read -ra filename_elems <<< "$filename"
|
||||
count=${#filename_elems[@]}
|
||||
if [[ "$count" -gt 2 ]]; then
|
||||
specific_product_version="${filename_elems[2]}"
|
||||
else
|
||||
specific_product_version=$specific_version
|
||||
fi
|
||||
unset IFS;
|
||||
echo "$specific_product_version"
|
||||
return 0
|
||||
}
|
||||
@ -711,19 +868,62 @@ extract_dotnet_package() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# remote_path - $1
|
||||
# disable_feed_credential - $2
|
||||
get_http_header()
|
||||
{
|
||||
eval $invocation
|
||||
local remote_path="$1"
|
||||
local disable_feed_credential="$2"
|
||||
|
||||
local failed=false
|
||||
local response
|
||||
if machine_has "curl"; then
|
||||
get_http_header_curl $remote_path $disable_feed_credential || failed=true
|
||||
elif machine_has "wget"; then
|
||||
get_http_header_wget $remote_path $disable_feed_credential || failed=true
|
||||
else
|
||||
failed=true
|
||||
fi
|
||||
if [ "$failed" = true ]; then
|
||||
say_verbose "Failed to get HTTP header: '$remote_path'."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# remote_path - $1
|
||||
# disable_feed_credential - $2
|
||||
get_http_header_curl() {
|
||||
eval $invocation
|
||||
local remote_path="$1"
|
||||
remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
local disable_feed_credential="$2"
|
||||
|
||||
remote_path_with_credential="$remote_path"
|
||||
if [ "$disable_feed_credential" = false ]; then
|
||||
remote_path_with_credential+="$feed_credential"
|
||||
fi
|
||||
|
||||
curl_options="-I -sSL --retry 5 --retry-delay 2 --connect-timeout 15 "
|
||||
curl $curl_options "$remote_path_with_credential" || return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# args:
|
||||
# remote_path - $1
|
||||
# disable_feed_credential - $2
|
||||
get_http_header_wget() {
|
||||
eval $invocation
|
||||
local remote_path="$1"
|
||||
remote_path_with_credential="${remote_path}${feed_credential}"
|
||||
local disable_feed_credential="$2"
|
||||
|
||||
remote_path_with_credential="$remote_path"
|
||||
if [ "$disable_feed_credential" = false ]; then
|
||||
remote_path_with_credential+="$feed_credential"
|
||||
fi
|
||||
|
||||
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
|
||||
@ -763,7 +963,7 @@ download() {
|
||||
|
||||
say "Download attempt #$attempts has failed: $http_code $download_error_msg"
|
||||
say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
|
||||
sleep $((attempts*20))
|
||||
sleep $((attempts*10))
|
||||
done
|
||||
|
||||
|
||||
@ -783,6 +983,7 @@ downloadcurl() {
|
||||
local remote_path="$1"
|
||||
local out_path="${2:-}"
|
||||
# Append feed_credential as late as possible before calling curl to avoid logging feed_credential
|
||||
# Avoid passing URI with credentials to functions: note, most of them echoing parameters of invocation in verbose output.
|
||||
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
|
||||
@ -792,7 +993,8 @@ downloadcurl() {
|
||||
curl $curl_options -o "$out_path" "$remote_path_with_credential" || failed=true
|
||||
fi
|
||||
if [ "$failed" = true ]; then
|
||||
local response=$(get_http_header_curl $remote_path_with_credential)
|
||||
local disable_feed_credential=false
|
||||
local response=$(get_http_header_curl $remote_path $disable_feed_credential)
|
||||
http_code=$( echo "$response" | awk '/^HTTP/{print $2}' | tail -1 )
|
||||
download_error_msg="Unable to download $remote_path."
|
||||
if [[ $http_code != 2* ]]; then
|
||||
@ -822,7 +1024,8 @@ downloadwget() {
|
||||
wget $wget_options -O "$out_path" "$remote_path_with_credential" || failed=true
|
||||
fi
|
||||
if [ "$failed" = true ]; then
|
||||
local response=$(get_http_header_wget $remote_path_with_credential)
|
||||
local disable_feed_credential=false
|
||||
local response=$(get_http_header_wget $remote_path $disable_feed_credential)
|
||||
http_code=$( echo "$response" | awk '/^ HTTP/{print $2}' | tail -1 )
|
||||
download_error_msg="Unable to download $remote_path."
|
||||
if [[ $http_code != 2* ]]; then
|
||||
@ -834,15 +1037,115 @@ downloadwget() {
|
||||
return 0
|
||||
}
|
||||
|
||||
get_download_link_from_aka_ms() {
|
||||
eval $invocation
|
||||
|
||||
#quality is not supported for LTS or current channel
|
||||
if [[ ! -z "$normalized_quality" && ("$normalized_channel" == "LTS" || "$normalized_channel" == "current") ]]; then
|
||||
normalized_quality=""
|
||||
say_warning "Specifying quality for current or LTS channel is not supported, the quality will be ignored."
|
||||
fi
|
||||
|
||||
say_verbose "Retrieving primary payload URL from aka.ms for channel: '$normalized_channel', quality: '$normalized_quality', product: '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
|
||||
|
||||
#construct aka.ms link
|
||||
aka_ms_link="https://aka.ms/dotnet"
|
||||
if [ "$internal" = true ]; then
|
||||
aka_ms_link="$aka_ms_link/internal"
|
||||
fi
|
||||
aka_ms_link="$aka_ms_link/$normalized_channel"
|
||||
if [[ ! -z "$normalized_quality" ]]; then
|
||||
aka_ms_link="$aka_ms_link/$normalized_quality"
|
||||
fi
|
||||
aka_ms_link="$aka_ms_link/$normalized_product-$normalized_os-$normalized_architecture.tar.gz"
|
||||
say_verbose "Constructed aka.ms link: '$aka_ms_link'."
|
||||
|
||||
#get HTTP response
|
||||
#do not pass credentials as a part of the $aka_ms_link and do not apply credentials in the get_http_header function
|
||||
#otherwise the redirect link would have credentials as well
|
||||
#it would result in applying credentials twice to the resulting link and thus breaking it, and in echoing credentials to the output as a part of redirect link
|
||||
disable_feed_credential=true
|
||||
response="$(get_http_header $aka_ms_link $disable_feed_credential)"
|
||||
|
||||
say_verbose "Received response: $response"
|
||||
# Get results of all the redirects.
|
||||
http_codes=$( echo "$response" | awk '$1 ~ /^HTTP/ {print $2}' )
|
||||
# They all need to be 301, otherwise some links are broken (except for the last, which is not a redirect but 200 or 404).
|
||||
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -v '301' )
|
||||
|
||||
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
|
||||
if [[ -z "$broken_redirects" ]]; then
|
||||
aka_ms_download_link=$( echo "$response" | awk '$1 ~ /^Location/{print $2}' | tail -1 | tr -d '\r')
|
||||
|
||||
if [[ -z "$aka_ms_download_link" ]]; then
|
||||
say_verbose "The aka.ms link '$aka_ms_link' is not valid: failed to get redirect location."
|
||||
return 1
|
||||
fi
|
||||
|
||||
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
|
||||
return 0
|
||||
else
|
||||
say_verbose "The aka.ms link '$aka_ms_link' is not valid: received HTTP code: $(echo "$broken_redirects" | paste -sd "," -)."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
calculate_vars() {
|
||||
eval $invocation
|
||||
valid_legacy_download_link=true
|
||||
|
||||
#normalize input variables
|
||||
normalized_architecture="$(get_normalized_architecture_from_architecture "$architecture")"
|
||||
say_verbose "normalized_architecture=$normalized_architecture"
|
||||
|
||||
say_verbose "Normalized architecture: '$normalized_architecture'."
|
||||
normalized_os="$(get_normalized_os "$user_defined_os")"
|
||||
say_verbose "normalized_os=$normalized_os"
|
||||
say_verbose "Normalized OS: '$normalized_os'."
|
||||
normalized_quality="$(get_normalized_quality "$quality")"
|
||||
say_verbose "Normalized quality: '$normalized_quality'."
|
||||
normalized_channel="$(get_normalized_channel "$channel")"
|
||||
say_verbose "Normalized channel: '$normalized_channel'."
|
||||
normalized_product="$(get_normalized_product "$runtime")"
|
||||
say_verbose "Normalized product: '$normalized_product'."
|
||||
|
||||
#try to get download location from aka.ms link
|
||||
#not applicable when exact version is specified via command or json file
|
||||
normalized_version="$(to_lowercase "$version")"
|
||||
if [[ -z "$json_file" && "$normalized_version" == "latest" ]]; then
|
||||
|
||||
valid_aka_ms_link=true;
|
||||
get_download_link_from_aka_ms || valid_aka_ms_link=false
|
||||
|
||||
if [ "$valid_aka_ms_link" == false ]; then
|
||||
# if quality is specified - exit with error - there is no fallback approach
|
||||
if [ ! -z "$normalized_quality" ]; then
|
||||
say_err "Failed to locate the latest version in the channel '$normalized_channel' with '$normalized_quality' quality for '$normalized_product', os: '$normalized_os', architecture: '$normalized_architecture'."
|
||||
say_err "Refer to: https://aka.ms/dotnet-os-lifecycle for information on .NET Core support."
|
||||
return 1
|
||||
fi
|
||||
say_verbose "Falling back to latest.version file approach."
|
||||
else
|
||||
say_verbose "Retrieved primary payload URL from aka.ms link: '$aka_ms_download_link'."
|
||||
download_link=$aka_ms_download_link
|
||||
|
||||
say_verbose "Downloading using legacy url will not be attempted."
|
||||
valid_legacy_download_link=false
|
||||
|
||||
#get version from the path
|
||||
IFS='/'
|
||||
read -ra pathElems <<< "$download_link"
|
||||
count=${#pathElems[@]}
|
||||
specific_version="${pathElems[count-2]}"
|
||||
unset IFS;
|
||||
say_verbose "Version: '$specific_version'."
|
||||
|
||||
#Retrieve product specific version
|
||||
specific_product_version="$(get_specific_product_version "$azure_feed" "$specific_version" "$download_link")"
|
||||
say_verbose "Product specific version: '$specific_product_version'."
|
||||
|
||||
install_root="$(resolve_installation_path "$install_dir")"
|
||||
say_verbose "InstallRoot: '$install_root'."
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
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")"
|
||||
@ -1011,6 +1314,8 @@ feed_credential=""
|
||||
verbose=false
|
||||
runtime=""
|
||||
runtime_id=""
|
||||
quality=""
|
||||
internal=false
|
||||
override_non_versioned_files=true
|
||||
non_dynamic_parameters=""
|
||||
user_defined_os=""
|
||||
@ -1027,6 +1332,14 @@ do
|
||||
shift
|
||||
version="$1"
|
||||
;;
|
||||
-q|--quality|-[Qq]uality)
|
||||
shift
|
||||
quality="$1"
|
||||
;;
|
||||
--internal|-[Ii]nternal)
|
||||
internal=true
|
||||
non_dynamic_parameters+=" $name"
|
||||
;;
|
||||
-i|--install-dir|-[Ii]nstall[Dd]ir)
|
||||
shift
|
||||
install_dir="$1"
|
||||
@ -1084,7 +1397,9 @@ do
|
||||
--feed-credential|-[Ff]eed[Cc]redential)
|
||||
shift
|
||||
feed_credential="$1"
|
||||
non_dynamic_parameters+=" $name "\""$1"\"""
|
||||
#feed_credential should start with "?", for it to be added to the end of the link.
|
||||
#adding "?" at the beginning of the feed_credential if needed.
|
||||
[[ -z "$(echo $feed_credential)" ]] || [[ $feed_credential == \?* ]] || feed_credential="?$feed_credential"
|
||||
;;
|
||||
--runtime-id|-[Rr]untime[Ii]d)
|
||||
shift
|
||||
@ -1116,15 +1431,26 @@ do
|
||||
echo " - LTS - most current supported release"
|
||||
echo " - 2-part version in a format A.B - represents a specific release"
|
||||
echo " examples: 2.0; 1.0"
|
||||
echo " - Branch name"
|
||||
echo " examples: release/2.0.0; Master"
|
||||
echo " Note: The version parameter overrides the channel parameter."
|
||||
echo " - 3-part version in a format A.B.Cxx - represents a specific SDK release"
|
||||
echo " examples: 5.0.1xx, 5.0.2xx."
|
||||
echo " Supported since 5.0 release"
|
||||
echo " Note: The version parameter overrides the channel parameter when any version other than `latest` is used."
|
||||
echo " -v,--version <VERSION> Use specific VERSION, Defaults to \`$version\`."
|
||||
echo " -Version"
|
||||
echo " Possible values:"
|
||||
echo " - latest - most latest build on specific channel"
|
||||
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 " -q,--quality <quality> Download the latest build of specified quality in the channel."
|
||||
echo " -Quality"
|
||||
echo " The possible values are: daily, signed, validated, preview, GA."
|
||||
echo " Works only in combination with channel. Not applicable for current and LTS channels and will be ignored if those channels are used."
|
||||
echo " For SDK use channel in A.B.Cxx format. Using quality for SDK together with channel in A.B format is not supported."
|
||||
echo " Supported since 5.0 release."
|
||||
echo " Note: The version parameter overrides the channel parameter when any version other than `latest` is used, and therefore overrides the quality."
|
||||
echo " --internal,-Internal Download internal builds. Requires providing credentials via --feed-credential parameter."
|
||||
echo " --feed-credential <FEEDCREDENTIAL> Token to access Azure feed. Used as a query string to append to the Azure feed."
|
||||
echo " -FeedCredential This parameter typically is not specified."
|
||||
echo " -i,--install-dir <DIR> Install under specified location (see Install Location below)"
|
||||
echo " -InstallDir"
|
||||
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
|
||||
@ -1145,7 +1471,6 @@ do
|
||||
echo " --verbose,-Verbose Display diagnostics information."
|
||||
echo " --azure-feed,-AzureFeed Azure feed location. Defaults to $azure_feed, This parameter typically is not changed by the user."
|
||||
echo " --uncached-feed,-UncachedFeed Uncached feed location. This parameter typically is not changed by the user."
|
||||
echo " --feed-credential,-FeedCredential Azure feed shared access token. This parameter typically is not specified."
|
||||
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
|
||||
echo " -SkipNonVersionedFiles"
|
||||
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
|
||||
@ -1186,23 +1511,44 @@ say "- The SDK needs to be installed without user interaction and without admin
|
||||
say "- The SDK installation doesn't need to persist across multiple CI runs."
|
||||
say "To set up a development environment or to run apps, use installers rather than this script. Visit https://dotnet.microsoft.com/download to get the installer.\n"
|
||||
|
||||
if [ "$internal" = true ] && [ -z "$(echo $feed_credential)" ]; then
|
||||
message="Provide credentials via --feed-credential parameter."
|
||||
if [ "$dry_run" = true ]; then
|
||||
say_warning "$message"
|
||||
else
|
||||
say_err "$message"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
check_min_reqs
|
||||
calculate_vars
|
||||
script_name=$(basename "$0")
|
||||
|
||||
if [ "$dry_run" = true ]; then
|
||||
say "Payload URLs:"
|
||||
say "Primary named payload URL: $download_link"
|
||||
say "Primary named payload URL: ${download_link}"
|
||||
if [ "$valid_legacy_download_link" = true ]; then
|
||||
say "Legacy named payload URL: $legacy_download_link"
|
||||
say "Legacy named payload URL: ${legacy_download_link}"
|
||||
fi
|
||||
repeatable_command="./$script_name --version "\""$specific_version"\"" --install-dir "\""$install_root"\"" --architecture "\""$normalized_architecture"\"" --os "\""$normalized_os"\"""
|
||||
|
||||
if [ ! -z "$normalized_quality" ]; then
|
||||
repeatable_command+=" --quality "\""$normalized_quality"\"""
|
||||
fi
|
||||
|
||||
if [[ "$runtime" == "dotnet" ]]; then
|
||||
repeatable_command+=" --runtime "\""dotnet"\"""
|
||||
elif [[ "$runtime" == "aspnetcore" ]]; then
|
||||
repeatable_command+=" --runtime "\""aspnetcore"\"""
|
||||
fi
|
||||
|
||||
repeatable_command+="$non_dynamic_parameters"
|
||||
|
||||
if [ -n "$feed_credential" ]; then
|
||||
repeatable_command+=" --feed-credential "\""<feed_credential>"\"""
|
||||
fi
|
||||
|
||||
say "Repeatable invocation: $repeatable_command"
|
||||
exit 0
|
||||
fi
|
||||
@ -1219,4 +1565,4 @@ 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."
|
||||
say "Installation finished successfully."
|
77
package-lock.json
generated
77
package-lock.json
generated
@ -2254,8 +2254,7 @@
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
|
||||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
@ -2332,9 +2331,9 @@
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"html-encoding-sniffer": {
|
||||
@ -2600,7 +2599,6 @@
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"is-docker": "^2.0.0"
|
||||
}
|
||||
@ -3405,9 +3403,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.get": {
|
||||
@ -3437,6 +3435,15 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
"integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"macos-release": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz",
|
||||
@ -3614,11 +3621,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-notifier": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz",
|
||||
"integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==",
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz",
|
||||
"integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"growly": "^1.3.0",
|
||||
"is-wsl": "^2.2.0",
|
||||
@ -3629,25 +3635,25 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"semver": {
|
||||
"version": "7.3.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
|
||||
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
|
||||
"version": "7.3.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz",
|
||||
"integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"version": "8.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||
"dev": true
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
@ -3886,9 +3892,9 @@
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-type": {
|
||||
@ -4445,8 +4451,7 @@
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
|
||||
"integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
@ -5319,9 +5324,9 @@
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.3.1",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz",
|
||||
"integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==",
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz",
|
||||
"integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==",
|
||||
"dev": true
|
||||
},
|
||||
"xml-name-validator": {
|
||||
@ -5342,9 +5347,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
|
||||
"integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true
|
||||
},
|
||||
"yaml": {
|
||||
|
@ -13,7 +13,9 @@ export function configAuthentication(
|
||||
) {
|
||||
const existingNuGetConfig: string = path.resolve(
|
||||
processRoot,
|
||||
existingFileLocation == '' ? 'nuget.config' : existingFileLocation
|
||||
existingFileLocation === ''
|
||||
? getExistingNugetConfig(processRoot)
|
||||
: existingFileLocation
|
||||
);
|
||||
|
||||
const tempNuGetConfig: string = path.resolve(
|
||||
@ -25,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,
|
||||
@ -109,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."
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -29,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();
|
||||
|
||||
@ -38,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;
|
||||
}
|
||||
@ -60,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.*'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,8 +79,9 @@ export class DotNetVersionInfo {
|
||||
}
|
||||
|
||||
export class DotnetCoreInstaller {
|
||||
constructor(version: string) {
|
||||
constructor(version: string, includePrerelease: boolean = false) {
|
||||
this.version = version;
|
||||
this.includePrerelease = includePrerelease;
|
||||
}
|
||||
|
||||
public async installDotnet() {
|
||||
@ -187,7 +191,7 @@ export class DotnetCoreInstaller {
|
||||
console.log(process.env['PATH']);
|
||||
|
||||
if (resultCode != 0) {
|
||||
throw `Failed to install dotnet ${resultCode}. ${output}`;
|
||||
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -212,13 +216,15 @@ 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
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
@ -227,16 +233,22 @@ export class DotnetCoreInstaller {
|
||||
let latestSdk: string = releasesResult['latest-sdk'];
|
||||
|
||||
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
|
||||
semver.lte(releaseInfo['sdk']['version'], latestSdk)
|
||||
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
|
||||
})
|
||||
);
|
||||
|
||||
if (releasesInfo.length == 0) {
|
||||
throw `Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`;
|
||||
throw new Error(
|
||||
`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`
|
||||
);
|
||||
}
|
||||
|
||||
let release = releasesInfo[0];
|
||||
@ -264,15 +276,18 @@ export class DotnetCoreInstaller {
|
||||
});
|
||||
|
||||
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 version: string;
|
||||
private includePrerelease: boolean;
|
||||
}
|
||||
|
||||
const DotNetCoreIndexUrl: string =
|
||||
|
@ -19,17 +19,19 @@ export async function run() {
|
||||
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'})
|
||||
);
|
||||
if (globalJson.sdk && globalJson.sdk.version) {
|
||||
version = globalJson.sdk.version;
|
||||
}
|
||||
version = getVersionFromGlobalJson(globalJsonPath);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@ -46,4 +48,21 @@ export async function run() {
|
||||
}
|
||||
}
|
||||
|
||||
function getVersionFromGlobalJson(globalJsonPath: string): string {
|
||||
let version: string = '';
|
||||
const globalJson = JSON.parse(
|
||||
// .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;
|
||||
const rollForward = globalJson.sdk.rollForward;
|
||||
if (rollForward && rollForward === 'latestFeature') {
|
||||
const [major, minor] = version.split('.');
|
||||
version = `${major}.${minor}`;
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
run();
|
||||
|
Reference in New Issue
Block a user