Compare commits

...

29 Commits

Author SHA1 Message Date
dependabot[bot]
c2fa09f4bd Bump minimatch from 3.1.2 to 3.1.5 (#705)
* Bump minimatch from 3.1.2 to 3.1.5

Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.1.2 to 3.1.5.
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* check failure fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: gowridurgad <gowridurgad@gmail.com>
2026-02-26 13:31:30 -06:00
priya-kinthali
02574b18e2 Add support for optional architecture input for cross-architecture .NET installs (#700)
* fix basic validation with npm command

* Revert "fix basic validation with npm command"

This reverts commit 27a0803a2a.

* add architecture support

* updated installdir logic

* update architecture resolution

* update normalizeArch
2026-02-26 13:17:54 -06:00
dependabot[bot]
16c7b3c2fa Bump fast-xml-parser from 4.4.1 to 5.3.6 (#671)
* Bump fast-xml-parser from 4.4.1 to 5.3.0

Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 4.4.1 to 5.3.0.
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.4.1...v5.3.0)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 5.3.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* check failure fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: gowridurgad <gowridurgad@gmail.com>
2026-02-19 10:47:32 -06:00
gowridurgad
131b410979 Add support for workloads input (#693)
* Add workloads input

* fix typo

* resloves conflicts

* Doc update

---------

Co-authored-by: gowridurgad <gowridurgad@gmail.com>
2026-01-28 18:12:03 -06:00
priya-kinthali
baa11fbfe1 Bump test dependencies to resolve System.Net.Http vulnerability, update workflows and README (#692)
* update test deps, workflows, and docs for latest versions

* fix wording

* update versions
2026-01-13 17:07:38 -06:00
Salman Chishti
24ec4f204b Upgrade to latest actions packages (#687)
* Add license metadata for various npm dependencies

* fix: correct license type for @actions/http-client to mit

* chore: update dependencies and version in package.json

- Bump version from 5.0.0 to 5.0.1
- Upgrade @actions/cache from ^4.0.3 to ^5.0.0
- Upgrade @actions/core from ^1.10.0 to ^2.0.0
- Upgrade @actions/exec from ^1.1.1 to ^2.0.0
- Upgrade @actions/http-client from ^2.2.3 to ^3.0.0

Add license files for @actions/http-client versions 2.2.3 and 3.0.0

* dist updates

* upgrade cache to 5.0.1

* check failure fix

---------

Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2026-01-13 14:14:30 -06:00
Benjamin Krämer
4c100cb5e4 Fix icons (#604) 2026-01-13 14:09:59 -06:00
dependabot[bot]
25328d894d Bump actions/checkout from 5 to 6 (#684)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-29 15:18:38 -06:00
priya-kinthali
937b8dd381 Update README with note on setting DOTNET_INSTALL_DIR for Linux permission issues (#689)
* update README: setting DOTNET_INSTALL_DIR

* fix indentation
2025-12-22 12:03:09 -06:00
dependabot[bot]
2016bd2012 Bump actions/publish-action from 0.3.0 to 0.4.0 and update macos-13 to macos-15-intel (#665)
* Bump actions/publish-action from 0.3.0 to 0.4.0

Bumps [actions/publish-action](https://github.com/actions/publish-action) from 0.3.0 to 0.4.0.
- [Commits](https://github.com/actions/publish-action/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: actions/publish-action
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Bump actions/publish-action from 0.3.0 to 0.4.0

Bumps [actions/publish-action](https://github.com/actions/publish-action) from 0.3.0 to 0.4.0.
- [Commits](https://github.com/actions/publish-action/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: actions/publish-action
  dependency-version: 0.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Installer script updates

* Update macos-13 to macos-15-intel

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-11-24 11:04:21 -06:00
dependabot[bot]
21e81f65dd Bump eslint-plugin-jest from 27.9.0 to 29.0.1 (#648)
* Bump eslint-plugin-jest from 27.9.0 to 29.0.1

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-version: 29.0.1
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* check failure fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-10-14 14:30:19 -05:00
dependabot[bot]
740310365d Bump typescript from 5.4.2 to 5.9.2 (#624)
* Bump typescript from 5.4.2 to 5.8.3

Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.4.2 to 5.8.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* doc update

* doc update

* doc format update

* update

* update

* doc update

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-09-08 22:03:08 -05:00
Salman Chishti
d4c94342e5 Update to Node.js 24 and modernize async usage (#654)
* Update to Node.js 24 and modernize async usage

Bump Node.js version to 24 in workflows, action metadata, and engines. Update TypeScript target to ES2022 and use native async/await instead of __awaiter in compiled JS. Upgrade @types/node to 24.1.0 and update undici-types. Remove legacy async helpers and refactor code for improved readability and compatibility with modern Node.js.

* update licences

* update indentation

* update package.json version

* documentation update

---------

Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-09-02 21:50:49 -05:00
dependabot[bot]
5c125af7da Bump actions/checkout from 4 to 5 (#662)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-21 11:16:35 -05:00
gowridurgad
87c6e11776 Bumps form-data (#652)
Co-authored-by: “gowridurgad” <“hgowridurgad@github.com>
2025-07-30 14:53:25 -05:00
dependabot[bot]
06a5327ecf Bump undici from 5.28.5 to 5.29.0 (#641)
* Bump undici from 5.28.5 to 5.29.0

Bumps [undici](https://github.com/nodejs/undici) from 5.28.5 to 5.29.0.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.5...v5.29.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 5.29.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Check failure fix

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: lmvysakh <lmvysakh@github.com>
2025-07-29 12:06:55 -05:00
dependabot[bot]
e8e5b8203e Bump eslint-config-prettier from 9.1.0 to 10.1.5 (#639)
Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 9.1.0 to 10.1.5.
- [Release notes](https://github.com/prettier/eslint-config-prettier/releases)
- [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/eslint-config-prettier/compare/v9.1.0...v10.1.5)

---
updated-dependencies:
- dependency-name: eslint-config-prettier
  dependency-version: 10.1.5
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-15 12:29:20 -05:00
dependabot[bot]
bf4cd79173 Bump @actions/glob from 0.4.0 to 0.5.0 (#594)
* Bump @actions/glob from 0.4.0 to 0.5.0

Bumps [@actions/glob](https://github.com/actions/toolkit/tree/HEAD/packages/glob) from 0.4.0 to 0.5.0.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/glob/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/glob)

---
updated-dependencies:
- dependency-name: "@actions/glob"
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix CI failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
2025-07-08 12:07:13 -05:00
dependabot[bot]
4ddad1c881 Bump husky from 8.0.3 to 9.1.7 (#591)
Bumps [husky](https://github.com/typicode/husky) from 8.0.3 to 9.1.7.
- [Release notes](https://github.com/typicode/husky/releases)
- [Commits](https://github.com/typicode/husky/compare/v8.0.3...v9.1.7)

---
updated-dependencies:
- dependency-name: husky
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-07-07 13:59:28 -05:00
gowridurgad
0f55b457d2 removes end-of-line dotnet versions (#647)
Co-authored-by: “gowridurgad” <“hgowridurgad@github.com>
2025-06-24 11:36:43 -05:00
aparnajyothi-y
267870a9c4 upgrade actions/cache to 4.0.3 (#622) 2025-04-08 12:45:24 -05:00
HarithaVattikuti
67a3573c9a cache upgrade from 4.0.0 to 4.0.2 (#615) 2025-03-16 21:47:43 -05:00
Zachary Taylor
83c0c1a6c8 v4 - Remove azureedge.net fallback logic and update install scripts (#572)
* Remove logic for azureedge.net fallback in preparation for install script changes

* remove extra spacing

* Update README.md (#587)

* upgrade cache from 3.2.4 to 4.0.0 (#586)

* upgrade cache to 4.0.0

* license update

* failure fix

* e2e failure fix

* Configure Dependabot settings (#585)

* Create dependabot.yml

* update latest install scripts

* Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 (#590)

Bumps [actions/publish-immutable-action](https://github.com/actions/publish-immutable-action) from 0.0.3 to 0.0.4.
- [Release notes](https://github.com/actions/publish-immutable-action/releases)
- [Commits](https://github.com/actions/publish-immutable-action/compare/0.0.3...v0.0.4)

---
updated-dependencies:
- dependency-name: actions/publish-immutable-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump @actions/http-client from 2.2.1 to 2.2.3 (#592)

* Bump @actions/http-client from 2.2.1 to 2.2.3

Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 2.2.1 to 2.2.3.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

---
updated-dependencies:
- dependency-name: "@actions/http-client"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for the check failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>

* Bump undici from 5.28.4 to 5.28.5 (#596)

* Bump undici from 5.28.4 to 5.28.5

Bumps [undici](https://github.com/nodejs/undici) from 5.28.4 to 5.28.5.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for the check failures

* fix for licensed check failure

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>

* Remove old URLs from E2E tests workflow

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Ben Wells <benwells@github.com>
Co-authored-by: aparnajyothi-y <147696841+aparnajyothi-y@users.noreply.github.com>
Co-authored-by: HarithaVattikuti <73516759+HarithaVattikuti@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-02-12 08:36:58 -06:00
dependabot[bot]
3951f0dfe7 Bump undici from 5.28.4 to 5.28.5 (#596)
* Bump undici from 5.28.4 to 5.28.5

Bumps [undici](https://github.com/nodejs/undici) from 5.28.4 to 5.28.5.
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v5.28.4...v5.28.5)

---
updated-dependencies:
- dependency-name: undici
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for the check failures

* fix for licensed check failure

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-01-29 11:57:00 -06:00
dependabot[bot]
4849e736f1 Bump @actions/http-client from 2.2.1 to 2.2.3 (#592)
* Bump @actions/http-client from 2.2.1 to 2.2.3

Bumps [@actions/http-client](https://github.com/actions/toolkit/tree/HEAD/packages/http-client) from 2.2.1 to 2.2.3.
- [Changelog](https://github.com/actions/toolkit/blob/main/packages/http-client/RELEASES.md)
- [Commits](https://github.com/actions/toolkit/commits/HEAD/packages/http-client)

---
updated-dependencies:
- dependency-name: "@actions/http-client"
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix for the check failures

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aparna Jyothi <aparnajyothi-y@github.com>
2025-01-29 11:40:46 -06:00
dependabot[bot]
3e76c4dc41 Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 (#590)
Bumps [actions/publish-immutable-action](https://github.com/actions/publish-immutable-action) from 0.0.3 to 0.0.4.
- [Release notes](https://github.com/actions/publish-immutable-action/releases)
- [Commits](https://github.com/actions/publish-immutable-action/compare/0.0.3...v0.0.4)

---
updated-dependencies:
- dependency-name: actions/publish-immutable-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-29 10:09:57 -06:00
HarithaVattikuti
91b379339b Configure Dependabot settings (#585)
* Create dependabot.yml

* update latest install scripts
2025-01-21 16:16:10 -06:00
aparnajyothi-y
4b37d22250 upgrade cache from 3.2.4 to 4.0.0 (#586)
* upgrade cache to 4.0.0

* license update

* failure fix

* e2e failure fix
2025-01-16 16:56:28 -06:00
Ben Wells
f9d0f6282c Update README.md (#587) 2025-01-16 08:48:22 -06:00
92 changed files with 115049 additions and 109186 deletions

22
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: 'npm'
# Look for `package.json` and `lock` files in the `root` directory
directory: '/'
# Check the npm registry for updates every day (weekdays)
schedule:
interval: 'weekly'
# Enable version updates for GitHub Actions
- package-ecosystem: 'github-actions'
# Workflow files stored in the default location of `.github/workflows`
# You don't need to specify `/.github/workflows` for `directory`. You can use `directory: "/"`.
directory: '/'
schedule:
interval: 'weekly'

View File

@@ -16,4 +16,4 @@ jobs:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
with:
node-version: '20'
node-version: '24'

View File

@@ -16,4 +16,4 @@ jobs:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
with:
node-version: '20'
node-version: '24'

File diff suppressed because it is too large Load Diff

View File

@@ -14,7 +14,7 @@ jobs:
steps:
- name: Checking out
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Publish
id: publish
uses: actions/publish-immutable-action@0.0.3
uses: actions/publish-immutable-action@v0.0.4

View File

@@ -23,7 +23,7 @@ jobs:
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.3.0
uses: actions/publish-action@v0.4.0
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

View File

@@ -18,32 +18,17 @@ jobs:
fail-fast: false
matrix:
operating-system:
[ubuntu-latest, ubuntu-22.04, windows-latest, macos-13, macos-latest]
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0']
exclude:
- dotnet-version: '2.1'
operating-system: ubuntu-latest
- dotnet-version: '2.2'
operating-system: ubuntu-latest
- dotnet-version: '3.0'
operating-system: ubuntu-latest
- dotnet-version: '3.1'
operating-system: ubuntu-latest
- dotnet-version: '5.0'
operating-system: ubuntu-latest
- dotnet-version: '2.1'
operating-system: macos-latest
- dotnet-version: '2.2'
operating-system: macos-latest
- dotnet-version: '3.0'
operating-system: macos-latest
- dotnet-version: '3.1'
operating-system: macos-latest
- dotnet-version: '5.0'
operating-system: macos-latest
[
ubuntu-latest,
ubuntu-22.04,
windows-latest,
macos-15-intel,
macos-latest
]
dotnet-version: ['8.0', '9.0', '10.0']
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v6
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}

Binary file not shown.

BIN
.licenses/npm/@actions/exec-2.0.0.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/@protobuf-ts/runtime.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/debug.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

161
README.md
View File

@@ -15,6 +15,13 @@ documentation:
[Software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-software)
for .NET SDK versions that are currently available.
## Breaking changes in V5
- Upgraded action from node20 to node24
> Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. see [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
For more details, see the full release notes on the [release page](https://github.com/actions/setup-dotnet/releases/tag/v5.0.0)
## Usage
See [action.yml](action.yml)
@@ -22,10 +29,10 @@ See [action.yml](action.yml)
**Basic**:
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '3.1.x'
dotnet-version: '8.0.x'
- run: dotnet build <my project>
```
> **Warning**: Unless a concrete version is specified in the [`global.json`](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) file, **_the latest .NET version installed on the runner (including preinstalled versions) will be used [by default](https://learn.microsoft.com/en-us/dotnet/core/versions/selection#the-sdk-uses-the-latest-installed-version)_**. Please refer to the [documentation](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-software) for the currently preinstalled .NET SDK versions.
@@ -33,25 +40,42 @@ steps:
**Multiple version installation**:
```yml
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup dotnet
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
3.1.x
5.0.x
8.0.x
9.0.x
- run: dotnet build <my project>
```
## Supported version syntax
The `dotnet-version` input supports following syntax:
- **A.B.C** (e.g 6.0.400, 7.0.100-preview.7.22377.5) - installs exact version of .NET SDK
- **A.B** or **A.B.x** (e.g. 3.1, 3.1.x) - installs the latest patch version of .NET SDK on the channel `3.1`, including prerelease versions (preview, rc)
- **A** or **A.x** (e.g. 3, 3.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
- **A.B.Cxx** (e.g. 6.0.4xx) - available since `.NET 5.0` release. Installs the latest version of the specific SDK release, including prerelease versions (preview, rc).
- **A.B.C** (e.g 9.0.308, 10.0.100-preview.1.25120.13) - installs exact version of .NET SDK
- **A.B** or **A.B.x** (e.g. 8.0, 8.0.x) - installs the latest patch version of .NET SDK on the channel `8.0`, including prerelease versions (preview, rc)
- **A** or **A.x** (e.g. 8, 8.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
- **A.B.Cxx** (e.g. 8.0.4xx) - available since `.NET 5.0` release. Installs the latest version of the specific SDK release, including prerelease versions (preview, rc).
## Using the `architecture` input
Using the architecture input, it is possible to specify the required .NET SDK architecture. Possible values: `x64`, `x86`, `arm64`, `amd64`, `arm`, `s390x`, `ppc64le`, `riscv64`. If the input is not specified, the architecture defaults to the host OS architecture (not all of the architectures are available on all platforms).
**Example: Install multiple SDK versions for a specific architecture**
```yml
steps:
- uses: actions/checkout@v6
- name: Setup dotnet (x86)
uses: actions/setup-dotnet@v5
with:
dotnet-version: |
8.0.x
9.0.x
architecture: x86
- run: dotnet build <my project>
```
## Using the `dotnet-quality` input
This input sets up the action to install the latest build of the specified quality in the channel. The possible values of `dotnet-quality` are: **daily**, **signed**, **validated**, **preview**, **ga**.
@@ -59,10 +83,10 @@ This input sets up the action to install the latest build of the specified quali
```yml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '6.0.x'
dotnet-version: '8.0.x'
dotnet-quality: 'preview'
- run: dotnet build <my project>
```
@@ -74,8 +98,8 @@ steps:
```yml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
global-json-file: csharp/global.json
- run: dotnet build <my project>
@@ -91,10 +115,10 @@ The action searches for [NuGet Lock files](https://learn.microsoft.com/nuget/con
```yaml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: 6.x
dotnet-version: 8.x
cache: true
- run: dotnet restore --locked-mode
```
@@ -116,10 +140,10 @@ steps:
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: 6.x
dotnet-version: 8.x
cache: true
- run: dotnet restore --locked-mode
```
@@ -130,10 +154,10 @@ steps:
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: 6.x
dotnet-version: 8.x
cache: true
cache-dependency-path: subdir/packages.lock.json
- run: dotnet restore --locked-mode
@@ -147,12 +171,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
dotnet: [ '8.0.x', '9.0.x', '10.0.x' ]
name: Dotnet ${{ matrix.dotnet }} sample
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup dotnet
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: ${{ matrix.dotnet }}
- name: Execute dotnet
@@ -167,12 +191,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
dotnet: [ '8.0.x', '9.0.x', '10.0.x' ]
name: Dotnet ${{ matrix.dotnet }} sample
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Setup dotnet
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
id: stepid
with:
dotnet-version: ${{ matrix.dotnet }}
@@ -181,15 +205,16 @@ jobs:
- name: Execute dotnet
run: dotnet build <my project>
```
>**Note**: When generating a temporary `global.json` within your workflow on Windows, ensure the command is executed using a shell such as PowerShell Core (`pwsh`) or `bash` (where supported) to avoid formatting inconsistencies that could cause .NET commands to fail.
## Setting up authentication for nuget feeds
### Github Package Registry (GPR)
```yml
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '3.1.x'
dotnet-version: '8.0.x'
source-url: https://nuget.pkg.github.com/<owner>/index.json
env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
@@ -202,7 +227,7 @@ steps:
### Azure Artifacts
```yml
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
with:
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
env:
@@ -213,9 +238,9 @@ steps:
### nuget.org
```yml
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
with:
dotnet-version: 3.1.x
dotnet-version: 8.0.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:
@@ -223,6 +248,22 @@ steps:
```
> **Note**: It's the only way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
## Using the `workloads` input
The `workloads` input allows you to install .NET workloads as part of the SDK setup. Workloads provide additional platform tools and dependencies for frameworks. This action automatically runs `dotnet workload update` before installing the specified workloads to ensure manifests are refreshed and existing workloads are updated to their latest compatible versions.
```yaml
steps:
- uses: actions/checkout@v5
- name: Setup .NET with workloads
uses: actions/setup-dotnet@v5
with:
dotnet-version: '9.0.x'
workloads: workload1, workload2 # Specify the workloads required for the project, such as wasm-tools, maui, etc.
- run: dotnet build <my project>
```
> **Note**: Ensure workloads are compatible with your runner's OS, architecture, and .NET SDK version before enabling workload installation. Some workloads may require additional installation time due to large toolchain downloads.
# Outputs and environment variables
## Outputs
@@ -236,11 +277,11 @@ Using the **dotnet-version** output it's possible to get the installed by the ac
In case of a single version installation, the `dotnet-version` output contains the version that is installed by the action.
```yaml
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
id: stepid
with:
dotnet-version: 3.1.422
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 3.1.422
dotnet-version: 8.0.416
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 8.0.416
```
**Multiple version installation**
@@ -248,27 +289,27 @@ In case of a single version installation, the `dotnet-version` output contains t
In case of a multiple version installation, the `dotnet-version` output contains the latest version that is installed by the action.
```yaml
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
id: stepid
with:
dotnet-version: |
3.1.422
5.0.408
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 5.0.408
8.0.416
9.0.308
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 9.0.308
```
**Installation from global.json**
When the `dotnet-version` input is used along with the `global-json-file` input, the `dotnet-version` output contains the version resolved from the `global.json`.
```yaml
- uses: actions/setup-dotnet@v4
- uses: actions/setup-dotnet@v5
id: stepid
with:
dotnet-version: |
3.1.422
5.0.408
global-json-file: "./global.json" # contains version 2.2.207
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 2.2.207
9.0.308
10.0.101
global-json-file: "./global.json" # contains version 8.0.416
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 8.0.416
```
### `cache-hit`
@@ -301,12 +342,28 @@ build:
DOTNET_INSTALL_DIR: "path/to/directory"
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@main
- uses: actions/setup-dotnet@v4
- uses: actions/checkout@v6
- uses: actions/setup-dotnet@v5
with:
dotnet-version: '3.1.x'
dotnet-version: '8.0.x'
cache: true
```
You can also set `DOTNET_INSTALL_DIR` to a value based on runtime variables, such as `$HOME/.dotnet` or `${{ runner.temp }}/.dotnet` before the `setup-dotnet` step:
```yml
- name: Set DOTNET_INSTALL_DIR
run: echo "DOTNET_INSTALL_DIR=$HOME/.dotnet" >> $GITHUB_ENV
```
> **Note**: On some self-hosted or large Linux runners, installing .NET under the default `/usr/share/dotnet` location may fail due to insufficient permissions. To ensure successful installation, set `DOTNET_INSTALL_DIR` to a user-writable path.
## Recommended permissions
When using the `setup-dotnet` action in your GitHub Actions workflow, it is recommended to set the following permissions to ensure proper functionality:
```yaml
permissions:
contents: read # access to check out code and install dependencies
```
## License

View File

@@ -0,0 +1,4 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
// Sequential test execution
[assembly: DoNotParallelize]

View File

@@ -12,7 +12,7 @@ namespace test_csproj
Console.WriteLine("TestMethod");
int calculatedResult = 1000 / 25;
int expectedResult = 40;
Assert.AreEqual(calculatedResult, expectedResult);
Assert.AreEqual(expectedResult, calculatedResult);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -8,9 +8,9 @@
<ItemGroup>
<!-- These packages will be downloaded over the network for testing proxy settings -->
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20170810-02" />
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="MSTest.TestAdapter" Version="4.0.2" />
<PackageReference Include="MSTest.TestFramework" Version="4.0.2" />
</ItemGroup>
</Project>

View File

@@ -2,6 +2,7 @@ import each from 'jest-each';
import semver from 'semver';
import fs from 'fs';
import fspromises from 'fs/promises';
import os from 'os';
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as io from '@actions/io';
@@ -38,7 +39,7 @@ describe('installer tests', () => {
});
it('should throw the error in case of non-zero exit code of the installation script. The error message should contain logs.', async () => {
const inputVersion = '3.1.100';
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const errorMessage = 'fictitious error message!';
@@ -60,7 +61,7 @@ describe('installer tests', () => {
});
it('should return version of .NET SDK after installation complete', async () => {
const inputVersion = '3.1.100';
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
@@ -82,7 +83,7 @@ describe('installer tests', () => {
});
it(`should supply 'version' argument to the installation script if supplied version is in A.B.C syntax`, async () => {
const inputVersion = '6.0.300';
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
@@ -120,7 +121,7 @@ describe('installer tests', () => {
});
it(`should warn if the 'quality' input is set and the supplied version is in A.B.C syntax`, async () => {
const inputVersion = '6.0.300';
const inputVersion = '10.0.101';
const inputQuality = 'ga' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
@@ -147,7 +148,7 @@ describe('installer tests', () => {
it(`should warn if the 'quality' input is set and version isn't in A.B.C syntax but major tag is lower then 6`, async () => {
const inputVersion = '3.1';
const inputQuality = 'ga' as QualityOptions;
const stdout = `Fictitious dotnet version 3.1.100 is installed`;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
@@ -170,12 +171,12 @@ describe('installer tests', () => {
);
});
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
each(['10', '10.0', '10.0.x', '10.0.*', '10.0.X']).test(
`should supply 'quality' argument to the installation script if quality input is set and version (%s) is not in A.B.C syntax`,
async inputVersion => {
const inputQuality = 'ga' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: exitCode,
@@ -210,12 +211,12 @@ describe('installer tests', () => {
}
);
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
each(['10', '10.0', '10.0.x', '10.0.*', '10.0.X']).test(
`should supply 'channel' argument to the installation script if version (%s) isn't in A.B.C syntax`,
async inputVersion => {
const inputQuality = '' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: exitCode,
@@ -243,8 +244,8 @@ describe('installer tests', () => {
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedArgument = IS_WINDOWS
? `-Channel 6.0`
: `--channel 6.0`;
? `-Channel 10.0`
: `--channel 10.0`;
expect(scriptArguments).toContain(expectedArgument);
}
@@ -253,7 +254,7 @@ describe('installer tests', () => {
if (IS_WINDOWS) {
it(`should supply '-ProxyAddress' argument to the installation script if env.variable 'https_proxy' is set`, async () => {
process.env['https_proxy'] = 'https://proxy.com';
const inputVersion = '6.0.100';
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
@@ -291,9 +292,9 @@ describe('installer tests', () => {
it(`should supply '-ProxyBypassList' argument to the installation script if env.variable 'no_proxy' is set`, async () => {
process.env['no_proxy'] = 'first.url,second.url';
const inputVersion = '6.0.100';
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
@@ -327,6 +328,143 @@ describe('installer tests', () => {
);
});
}
it(`should supply 'architecture' argument to the installation script when architecture is provided`, async () => {
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const inputArchitecture = 'x64';
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);
const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
inputQuality,
inputArchitecture
);
await dotnetInstaller.installDotnet();
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedArgument = IS_WINDOWS
? `-Architecture ${inputArchitecture}`
: `--architecture ${inputArchitecture}`;
expect(scriptArguments).toContain(expectedArgument);
});
it(`should NOT supply 'architecture' argument when architecture is not provided`, async () => {
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);
const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
inputQuality
);
await dotnetInstaller.installDotnet();
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
expect(scriptArguments).not.toContain('--architecture');
expect(scriptArguments).not.toContain('-Architecture');
});
it(`should supply 'install-dir' with arch subdirectory for cross-arch install`, async () => {
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const inputArchitecture = 'x64';
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);
// Mock os.arch() to return a different arch to simulate cross-arch
const archSpy = jest.spyOn(os, 'arch').mockReturnValue('arm64');
const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
inputQuality,
inputArchitecture
);
await dotnetInstaller.installDotnet();
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedInstallDirFlag = IS_WINDOWS
? '-InstallDir'
: '--install-dir';
expect(scriptArguments).toContain(expectedInstallDirFlag);
expect(scriptArguments).toContain(inputArchitecture);
archSpy.mockRestore();
});
it(`should NOT supply 'install-dir' when architecture matches runner's native arch`, async () => {
const inputVersion = '10.0.101';
const inputQuality = '' as QualityOptions;
const nativeArch = os.arch().toLowerCase();
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);
const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
inputQuality,
nativeArch
);
await dotnetInstaller.installDotnet();
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
expect(scriptArguments).not.toContain('--install-dir');
expect(scriptArguments).not.toContain('-InstallDir');
});
});
describe('addToPath() tests', () => {
@@ -346,17 +484,43 @@ describe('installer tests', () => {
});
});
describe('normalizeArch() tests', () => {
it(`should normalize 'amd64' to 'x64'`, () => {
expect(installer.normalizeArch('amd64')).toBe('x64');
});
it(`should normalize 'AMD64' to 'x64' (case-insensitive)`, () => {
expect(installer.normalizeArch('AMD64')).toBe('x64');
});
it(`should pass through 'x64' unchanged`, () => {
expect(installer.normalizeArch('x64')).toBe('x64');
});
it(`should pass through 'arm64' unchanged`, () => {
expect(installer.normalizeArch('arm64')).toBe('arm64');
});
it(`should lowercase 'ARM64'`, () => {
expect(installer.normalizeArch('ARM64')).toBe('arm64');
});
it(`should pass through 'x86' unchanged`, () => {
expect(installer.normalizeArch('x86')).toBe('x86');
});
});
describe('DotnetVersionResolver tests', () => {
describe('createDotnetVersion() tests', () => {
each([
'3.1',
'3.x',
'3.1.x',
'3.1.*',
'3.1.X',
'3.1.2',
'3.1.0-preview1',
'6.0.2xx'
'10.0',
'10.x',
'10.0.x',
'10.0.*',
'10.0.X',
'10.0.0',
'10.0.0-preview7',
'10.0.1xx'
]).test(
'if valid version is supplied (%s), it should return version object with some value',
async version => {
@@ -408,7 +572,7 @@ describe('installer tests', () => {
}
);
each(['3', '3.1', '3.1.x', '3.1.*', '3.1.X', '6.0.2xx']).test(
each(['10', '10.0', '10.0.x', '10.0.*', '10.0.X', '10.0.1xx']).test(
"if version that can be resolved to 'channel' option is supplied (%s), it should set type to 'channel' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
@@ -423,7 +587,7 @@ describe('installer tests', () => {
}
);
each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.2xx']).test(
each(['10.0', '10.0.x', '10.0.*', '10.0.X', '10.0.1xx']).test(
"if version that can be resolved to 'channel' option is supplied and its major tag is >= 6 (%s), it should set type to 'channel' and qualityFlag to 'true' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
@@ -439,7 +603,7 @@ describe('installer tests', () => {
}
);
each(['3.1.2', '3.1.0-preview1']).test(
each(['10.0.0', '10.0.0-preview7']).test(
"if version that can be resolved to 'version' option is supplied (%s), it should set quality flag to 'false' and type to 'version' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
@@ -455,7 +619,7 @@ describe('installer tests', () => {
}
);
each(['3.1.2', '3.1']).test(
each(['10.0.0', '10.0']).test(
'it should create proper line arguments for powershell/bash installation scripts',
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(

View File

@@ -2,7 +2,7 @@ import * as core from '@actions/core';
import fs from 'fs';
import semver from 'semver';
import * as auth from '../src/authutil';
import os from 'os';
import * as setup from '../src/setup-dotnet';
import {DotnetCoreInstaller, DotnetInstallDir} from '../src/installer';
import * as cacheUtils from '../src/cache-utils';
@@ -81,7 +81,7 @@ describe('setup-dotnet tests', () => {
it('should fail the action if quality is supplied but its value is not supported', async () => {
inputs['global-json-file'] = '';
inputs['dotnet-version'] = ['6.0'];
inputs['dotnet-version'] = ['10.0'];
inputs['dotnet-quality'] = 'fictitiousQuality';
const expectedErrorMessage = `Value '${inputs['dotnet-quality']}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`;
@@ -92,7 +92,7 @@ describe('setup-dotnet tests', () => {
it('should call installDotnet() multiple times if dotnet-version multiline input is provided', async () => {
inputs['global-json-file'] = '';
inputs['dotnet-version'] = ['6.0', '7.0'];
inputs['dotnet-version'] = ['9.0', '10.0'];
inputs['dotnet-quality'] = '';
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
@@ -103,7 +103,7 @@ describe('setup-dotnet tests', () => {
it('should call addToPath() after installation complete', async () => {
inputs['global-json-file'] = '';
inputs['dotnet-version'] = ['6.0', '7.0'];
inputs['dotnet-version'] = ['9.0', '10.0'];
inputs['dotnet-quality'] = '';
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
@@ -145,7 +145,7 @@ describe('setup-dotnet tests', () => {
});
it('should call setOutput() after installation complete successfully', async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-version'] = ['10.0.101'];
installDotnetSpy.mockImplementation(() =>
Promise.resolve(`${inputs['dotnet-version']}`)
@@ -156,7 +156,7 @@ describe('setup-dotnet tests', () => {
});
it(`shouldn't call setOutput() if parsing dotnet-installer logs failed`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-version'] = ['10.0.101'];
const warningMessage = `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`;
installDotnetSpy.mockImplementation(() => Promise.resolve(null));
@@ -177,7 +177,7 @@ describe('setup-dotnet tests', () => {
});
it(`should get 'cache-dependency-path' and call restoreCache() if input cache is set to true and cache feature is available`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['cache'] = true;
inputs['cache-dependency-path'] = 'fictitious.package.lock.json';
@@ -195,7 +195,7 @@ describe('setup-dotnet tests', () => {
});
it(`shouldn't call restoreCache() if input cache isn't set to true`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['cache'] = false;
@@ -209,7 +209,7 @@ describe('setup-dotnet tests', () => {
});
it(`shouldn't call restoreCache() if cache feature isn't available`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['cache'] = true;
@@ -221,5 +221,40 @@ describe('setup-dotnet tests', () => {
await setup.run();
expect(restoreCacheSpy).not.toHaveBeenCalled();
});
it('should pass valid architecture input to DotnetCoreInstaller', async () => {
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['architecture'] = os.arch().toLowerCase();
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
await setup.run();
expect(installDotnetSpy).toHaveBeenCalledTimes(1);
expect(DotnetInstallDir.addToPath).toHaveBeenCalledTimes(1);
});
it('should work with empty architecture input for auto-detection', async () => {
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['architecture'] = '';
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
await setup.run();
expect(installDotnetSpy).toHaveBeenCalledTimes(1);
expect(DotnetInstallDir.addToPath).toHaveBeenCalledTimes(1);
});
it('should fail the action if unsupported architecture is provided', async () => {
inputs['dotnet-version'] = ['10.0.101'];
inputs['dotnet-quality'] = '';
inputs['architecture'] = 'x688';
const expectedErrorMessage = `Value 'x688' is not supported for the 'architecture' option. Supported values are: x64, x86, arm64, amd64, arm, s390x, ppc64le, riscv64.`;
await setup.run();
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
});
});
});

View File

@@ -72,6 +72,8 @@ $targetFrameworkVersionMap = @{
"6.0" = "net6.0";
"7.0" = "net7.0";
"8.0" = "net8.0";
"9.0" = "net9.0";
"10.0" = "net10.0";
}
foreach ($version in $Versions)

View File

@@ -24,13 +24,19 @@ inputs:
cache-dependency-path:
description: 'Used to specify the path to a dependency file: packages.lock.json. Supports wildcards or a list of file names for caching multiple dependencies.'
required: false
workloads:
description: 'Optional SDK workloads to install for additional platform support. Examples: wasm-tools, maui, aspire.'
required: false
architecture:
description: 'Optional architecture for the .NET install. Supported values: x64, x86, arm64, amd64, arm, s390x, ppc64le, riscv64. If not set, the installer auto-detects the current system architecture.'
required: false
outputs:
cache-hit:
description: 'A boolean value to indicate if a cache was hit.'
dotnet-version:
description: 'Contains the installed by action .NET SDK version for reuse.'
runs:
using: 'node20'
using: 'node24'
main: 'dist/setup/index.js'
post: 'dist/cache-save/index.js'
post-if: success()

106410
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

112508
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -6,13 +6,13 @@ We have prepared a short guide so that the process of making your contribution i
## How can I contribute...
* [Contribute Documentation:green_book:](#contribute-documentation)
* [Contribute Documentation :green_book:](#contribute-documentation)
* [Contribute Code :computer:](#contribute-code)
* [Provide Support on Issues:pencil:](#provide-support-on-issues)
* [Provide Support on Issues :pencil:](#provide-support-on-issues)
* [Review Pull Requests:mag:](#review-pull-requests)
* [Review Pull Requests :mag:](#review-pull-requests)
## Contribute documentation

View File

@@ -28,9 +28,8 @@
Warning: Value "Current" is deprecated for the Channel parameter. Use "STS" instead.
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.
Download the latest build of specified quality in the channel. The possible values are: daily, preview, GA.
Works only in combination with channel. Not applicable for STS 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
@@ -64,7 +63,7 @@
.PARAMETER DryRun
If set it will not perform installation but instead display what command line to use to consistently install
currently requested version of dotnet cli. In example if you specify version 'latest' it will display a link
with specific version so that this command can be used deterministicly in a build script.
with specific version so that this command can be used deterministically in a build script.
It also displays binaries location if you prefer to install or download it yourself.
.PARAMETER NoPath
By default this script will set environment variable PATH for the current process to the binaries folder inside installation folder.
@@ -72,14 +71,12 @@
.PARAMETER Verbose
Displays diagnostics information.
.PARAMETER AzureFeed
Default: https://dotnetcli.azureedge.net/dotnet
Default: https://builds.dotnet.microsoft.com/dotnet
For internal use only.
Allows using a different storage to download SDK archives from.
This parameter is only used if $NoCdn is false.
.PARAMETER UncachedFeed
For internal use only.
Allows using a different storage to download SDK archives from.
This parameter is only used if $NoCdn is true.
.PARAMETER ProxyAddress
If set, the installer will use the proxy when making web requests
.PARAMETER ProxyUseDefaultCredentials
@@ -90,13 +87,11 @@
.PARAMETER SkipNonVersionedFiles
Default: false
Skips installing non-versioned files if they already exist, such as dotnet.exe.
.PARAMETER NoCdn
Disable downloading from the Azure CDN, and use the uncached feed directly.
.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
Determines timeout duration in seconds for downloading of the SDK file
Default: 1200 seconds (20 minutes)
.PARAMETER KeepZip
If set, downloaded file is kept
@@ -130,7 +125,6 @@ param(
[switch]$ProxyUseDefaultCredentials,
[string[]]$ProxyBypassList = @(),
[switch]$SkipNonVersionedFiles,
[switch]$NoCdn,
[int]$DownloadTimeout = 1200,
[switch]$KeepZip,
[string]$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName()),
@@ -165,7 +159,7 @@ function Say-Warning($str) {
# Use this function to show a human-readable comment along with an exception.
function Say-Error($str) {
try {
# Write-Error is quite oververbose for the purpose of the function, let's write one line with error style settings.
# Write-Error is quite verbose for the purpose of the function, let's write one line with error style settings.
$Host.UI.WriteErrorLine("dotnet-install: $str")
}
catch {
@@ -191,7 +185,7 @@ function Measure-Action($name, $block) {
function Get-Remote-File-Size($zipUri) {
try {
$response = Invoke-WebRequest -Uri $zipUri -Method Head
$response = Invoke-WebRequest -UseBasicParsing -Uri $zipUri -Method Head
$fileSize = $response.Headers["Content-Length"]
if ((![string]::IsNullOrEmpty($fileSize))) {
Say "Remote file $zipUri size is $fileSize bytes."
@@ -305,10 +299,10 @@ function Get-NormalizedQuality([string]$Quality) {
}
switch ($Quality) {
{ @("daily", "signed", "validated", "preview") -contains $_ } { return $Quality.ToLowerInvariant() }
{ @("daily", "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." }
default { throw "'$Quality' is not a supported value for -Quality option. Supported values are: daily, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues." }
}
}
@@ -997,32 +991,6 @@ function PrintDryRunOutput($Invocation, $DownloadLinks) {
}
}
# grab the 'stem' of the redirect and check it against all of our configured feeds,
# if it matches, we can be sure that the redirect is valid and we should use it for
# subsequent processing
function Sanitize-RedirectUrl([string]$url) {
$urlSegments = ([System.Uri]$url).Segments;
$urlStem = $urlSegments[2..($urlSegments.Length - 1)] -join "";
Write-Verbose "Checking configured feeds for the asset at $urlStem"
foreach ($prospectiveFeed in $feeds) {
$trialUrl = "$prospectiveFeed/$urlStem";
Write-Verbose "Checking $trialUrl"
try {
$trialResponse = Invoke-WebRequest -Uri $trialUrl -Method HEAD
if ($trialResponse.StatusCode -eq 200) {
Write-Verbose "Found a match at $trialUrl"
return $trialUrl;
}
else {
Write-Verbose "No match at $trialUrl"
}
}
catch {
Write-Verbose "Failed to check $trialUrl"
}
}
}
function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Internal, [string]$Product, [string]$Architecture) {
Say-Invocation $MyInvocation
@@ -1081,11 +1049,6 @@ function Get-AkaMSDownloadLink([string]$Channel, [string]$Quality, [bool]$Intern
}
elseif ((($Response.StatusCode -lt 300) -or ($Response.StatusCode -ge 400)) -and (-not [string]::IsNullOrEmpty($akaMsDownloadLink))) {
# Redirections have ended.
$actualRedirectUrl = Sanitize-RedirectUrl $akaMsDownloadLink
if ($null -ne $actualRedirectUrl) {
$akaMsDownloadLink = $actualRedirectUrl
}
return $akaMsDownloadLink
}
@@ -1137,24 +1100,15 @@ function Get-AkaMsLink-And-Version([string] $NormalizedChannel, [string] $Normal
function Get-Feeds-To-Use() {
$feeds = @(
"https://builds.dotnet.microsoft.com/dotnet"
"https://dotnetcli.azureedge.net/dotnet"
"https://ci.dot.net/public"
"https://dotnetbuilds.azureedge.net/public"
)
if (-not [string]::IsNullOrEmpty($AzureFeed)) {
$feeds = @($AzureFeed)
}
if ($NoCdn) {
$feeds = @(
"https://dotnetcli.blob.core.windows.net/dotnet",
"https://dotnetbuilds.blob.core.windows.net/public"
)
if (-not [string]::IsNullOrEmpty($UncachedFeed)) {
if (-not [string]::IsNullOrEmpty($UncachedFeed)) {
$feeds = @($UncachedFeed)
}
}
Write-Verbose "Initialized feeds: $feeds"
@@ -1399,221 +1353,221 @@ Say "Note that the script does not ensure your Windows version is supported duri
Say "To check the list of supported versions, go to https://learn.microsoft.com/dotnet/core/install/windows#supported-versions"
Say "Installed version is $($DownloadedLink.effectiveVersion)"
Say "Installation finished"
# SIG # Begin signature block
# MIIoVQYJKoZIhvcNAQcCoIIoRjCCKEICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# MIIoKgYJKoZIhvcNAQcCoIIoGzCCKBcCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAYvsOYTXPcgaBF
# C8M6oYBHzvQKaqKPOJVvd3P0sSBCw6CCDYUwggYDMIID66ADAgECAhMzAAAEA73V
# lV0POxitAAAAAAQDMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCyKn7B6ieM6Y2C
# rr9TCFvTSv2mMIh9mBGXh4z2gOksEqCCDXYwggX0MIID3KADAgECAhMzAAAEhV6Z
# 7A5ZL83XAAAAAASFMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTEzWhcNMjUwOTExMjAxMTEzWjB0MQsw
# bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM3WhcNMjYwNjE3MTgyMTM3WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQCfdGddwIOnbRYUyg03O3iz19XXZPmuhEmW/5uyEN+8mgxl+HJGeLGBR8YButGV
# LVK38RxcVcPYyFGQXcKcxgih4w4y4zJi3GvawLYHlsNExQwz+v0jgY/aejBS2EJY
# oUhLVE+UzRihV8ooxoftsmKLb2xb7BoFS6UAo3Zz4afnOdqI7FGoi7g4vx/0MIdi
# kwTn5N56TdIv3mwfkZCFmrsKpN0zR8HD8WYsvH3xKkG7u/xdqmhPPqMmnI2jOFw/
# /n2aL8W7i1Pasja8PnRXH/QaVH0M1nanL+LI9TsMb/enWfXOW65Gne5cqMN9Uofv
# ENtdwwEmJ3bZrcI9u4LZAkujAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU6m4qAkpz4641iK2irF8eWsSBcBkw
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMjkyNjAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AFFo/6E4LX51IqFuoKvUsi80QytGI5ASQ9zsPpBa0z78hutiJd6w154JkcIx/f7r
# EBK4NhD4DIFNfRiVdI7EacEs7OAS6QHF7Nt+eFRNOTtgHb9PExRy4EI/jnMwzQJV
# NokTxu2WgHr/fBsWs6G9AcIgvHjWNN3qRSrhsgEdqHc0bRDUf8UILAdEZOMBvKLC
# rmf+kJPEvPldgK7hFO/L9kmcVe67BnKejDKO73Sa56AJOhM7CkeATrJFxO9GLXos
# oKvrwBvynxAg18W+pagTAkJefzneuWSmniTurPCUE2JnvW7DalvONDOtG01sIVAB
# +ahO2wcUPa2Zm9AiDVBWTMz9XUoKMcvngi2oqbsDLhbK+pYrRUgRpNt0y1sxZsXO
# raGRF8lM2cWvtEkV5UL+TQM1ppv5unDHkW8JS+QnfPbB8dZVRyRmMQ4aY/tx5x5+
# sX6semJ//FbiclSMxSI+zINu1jYerdUwuCi+P6p7SmQmClhDM+6Q+btE2FtpsU0W
# +r6RdYFf/P+nK6j2otl9Nvr3tWLu+WXmz8MGM+18ynJ+lYbSmFWcAj7SYziAfT0s
# IwlQRFkyC71tsIZUhBHtxPliGUu362lIO0Lpe0DOrg8lspnEWOkHnCT5JEnWCbzu
# iVt8RX1IV07uIveNZuOBWLVCzWJjEGa+HhaEtavjy6i7MIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAQDvdWVXQ87GK0AAAAA
# BAMwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINfL
# pWARcSI2v5ypXRaeSwvLuu7hP0XgYbvQaaOIuiKWMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEADr/V9EQlvMcNLQduKLU/gz5PRRSoE8txgN52
# OuBIJS4+jPp3y82+4/09umeMdQ7+pwRQiuPAvmyZG0zGRoTz3PzpouceetqHnIHn
# ij0lT0y4hUQ0DqmZT1AA24GJmoPnM9ab2EcRTfUp7p0t1Fq5ITOEdFvvh6EPkyc/
# spxmI5bTlE0+anj9PmnLyFYnFtrGlmSywrDpIsjqnE8+ODtTabllcpAhLrZxInqu
# bHXIrT3cGjATJsRAg+38R5tYP7i6aI5sS9QGmeXhuvrJeFrOIqC2gxbV7iCJIrkE
# 5OGFIBZQkxLRZxt3VYdGAjBLj+pCY7OEjXpXvkdg47Xo8aQCKqGCF7AwghesBgor
# BgEEAYI3AwMBMYIXnDCCF5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCBVg4bCpxEOAWWIN2/4kB21BawVRDfKQ35G
# xRhhaLpK/AIGZ2KxlnK4GBMyMDI0MTIyMzE2NDIwNy43NDJaMASAAgH0oIHZpIHW
# MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT
# Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z
# b2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB9oMv
# JmpUXSLBAAEAAAH2MA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYD
# AQDASkh1cpvuUqfbqxele7LCSHEamVNBfFE4uY1FkGsAdUF/vnjpE1dnAD9vMOqy
# 5ZO49ILhP4jiP/P2Pn9ao+5TDtKmcQ+pZdzbG7t43yRXJC3nXvTGQroodPi9USQi
# 9rI+0gwuXRKBII7L+k3kMkKLmFrsWUjzgXVCLYa6ZH7BCALAcJWZTwWPoiT4HpqQ
# hJcYLB7pfetAVCeBEVZD8itKQ6QA5/LQR+9X6dlSj4Vxta4JnpxvgSrkjXCz+tlJ
# 67ABZ551lw23RWU1uyfgCfEFhBfiyPR2WSjskPl9ap6qrf8fNQ1sGYun2p4JdXxe
# UAKf1hVa/3TQXjvPTiRXCnJPAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUuCZyGiCuLYE0aU7j5TFqY05kko0w
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzUwNTM1OTAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBACjmqAp2Ci4sTHZci+qk
# tEAKsFk5HNVGKyWR2rFGXsd7cggZ04H5U4SV0fAL6fOE9dLvt4I7HBHLhpGdE5Uj
# Ly4NxLTG2bDAkeAVmxmd2uKWVGKym1aarDxXfv3GCN4mRX+Pn4c+py3S/6Kkt5eS
# DAIIsrzKw3Kh2SW1hCwXX/k1v4b+NH1Fjl+i/xPJspXCFuZB4aC5FLT5fgbRKqns
# WeAdn8DsrYQhT3QXLt6Nv3/dMzv7G/Cdpbdcoul8FYl+t3dmXM+SIClC3l2ae0wO
# lNrQ42yQEycuPU5OoqLT85jsZ7+4CaScfFINlO7l7Y7r/xauqHbSPQ1r3oIC+e71
# 5s2G3ClZa3y99aYx2lnXYe1srcrIx8NAXTViiypXVn9ZGmEkfNcfDiqGQwkml5z9
# nm3pWiBZ69adaBBbAFEjyJG4y0a76bel/4sDCVvaZzLM3TFbxVO9BQrjZRtbJZbk
# C3XArpLqZSfx53SuYdddxPX8pvcqFuEu8wcUeD05t9xNbJ4TtdAECJlEi0vvBxlm
# M5tzFXy2qZeqPMXHSQYqPgZ9jvScZ6NwznFD0+33kbzyhOSz/WuGbAu4cHZG8gKn
# lQVT4uA2Diex9DMs2WHiokNknYlLoUeWXW1QrJLpqO82TLyKTbBM/oZHAdIc0kzo
# STro9b3+vjn2809D0+SOOCVZMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
# IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg
# Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03
# a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr
# rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg
# OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy
# 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9
# sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh
# dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k
# A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB
# w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn
# Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90
# lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w
# ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o
# ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa
# BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG
# AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV
# HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG
# AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl
# AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb
# C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l
# hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6
# I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0
# wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560
# STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam
# ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa
# J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah
# XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA
# 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt
# Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr
# /Xmfwb1tbWrJUnMTDXpQzTGCGgowghoGAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAASFXpnsDlkvzdcAAAAABIUwDQYJYIZIAWUDBAIB
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEID8/Z0hz8wCpH2YjVYR3wACO
# qi7toMi0S892RCpCiXnDMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
# BQAEggEAR3ofVJe8H1PSnVv5GEV/iNRKzDHBYXTNKjw6gaEwywGiLnvok4fIy+o/
# pgoyuM4RLT6jq9o/62LWZPnRCXiQiidnt9u6BtjAQFoy9Hyz39SnG3SIfcXwQU6S
# Kn6sdIdkCnp9zgCw0A1um1l9ZESP36cub7lCkog6Qd1N+d5KAMuDMHX4MybWYjva
# YmW+c3RMH4HoBd6igF/hUaz0VTf+yrdIUaBIJ9UlWTMVkwokmQ9I79IwPU5hHnRu
# Ao8D6p++BagDKmVHo4bY/ADy4GDn4nrLA09mwd0YQPDZvb3K3Z2rIABM0UdS4+lG
# c/pZsaRUT7TE8NzWXP+vWQ9bdkhNbaGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCC
# F3wGCSqGSIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsq
# hkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
# AwQCAQUABCAd+KomD6n/vMp0PpchU0Vc9uK1oIZ/s0smWP9W6KAY4QIGaSc7gduW
# GBMyMDI1MTIxMDIyNDQ0NC41NjdaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l
# cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0w
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Wg
# ghHqMIIHIDCCBQigAwIBAgITMwAAAgO7HlwAOGx0ygABAAACAzANBgkqhkiG9w0B
# AQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
# VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNTAxMzAxOTQy
# NDZaFw0yNjA0MjIxOTQyNDZaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z
# MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0wNUUwLUQ5NDcxJTAjBgNV
# BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQChl0MH5wAnOx8Uh8RtidF0J0yaFDHJYHTpPvRR16X1
# KxGDYfT8PrcGjCLCiaOu3K1DmUIU4Rc5olndjappNuOgzwUoj43VbbJx5PFTY/a1
# Z80tpqVP0OoKJlUkfDPSBLFgXWj6VgayRCINtLsUasy0w5gysD7ILPZuiQjace5K
# xASjKf2MVX1qfEzYBbTGNEijSQCKwwyc0eavr4Fo3X/+sCuuAtkTWissU64k8rK6
# 0jsGRApiESdfuHr0yWAmc7jTOPNeGAx6KCL2ktpnGegLDd1IlE6Bu6BSwAIFHr7z
# OwIlFqyQuCe0SQALCbJhsT9y9iy61RJAXsU0u0TC5YYmTSbEI7g10dYx8Uj+vh9I
# nLoKYC5DpKb311bYVd0bytbzlfTRslRTJgotnfCAIGMLqEqk9/2VRGu9klJi1j9n
# VfqyYHYrMPOBXcrQYW0jmKNjOL47CaEArNzhDBia1wXdJANKqMvJ8pQe2m8/ciby
# DM+1BVZquNAov9N4tJF4ACtjX0jjXNDUMtSZoVFQH+FkWdfPWx1uBIkc97R+xRLu
# PjUypHZ5A3AALSke4TaRBvbvTBYyW2HenOT7nYLKTO4jw5Qq6cw3Z9zTKSPQ6D5l
# yiYpes5RR2MdMvJS4fCcPJFeaVOvuWFSQ/EGtVBShhmLB+5ewzFzdpf1UuJmuOQT
# TwIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFLIpWUB+EeeQ29sWe0VdzxWQGJJ9MB8G
# A1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCG
# Tmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy
# MFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4w
# XAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2Vy
# dHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwG
# A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQD
# AgeAMA0GCSqGSIb3DQEBCwUAA4ICAQCQEMbesD6TC08R0oYCdSC452AQrGf/O89G
# Q54CtgEsbxzwGDVUcmjXFcnaJSTNedBKVXkBgawRonP1LgxH4bzzVj2eWNmzGIwO
# 1FlhldAPOHAzLBEHRoSZ4pddFtaQxoabU/N1vWyICiN60It85gnF5JD4MMXyd6pS
# 8eADIi6TtjfgKPoumWa0BFQ/aEzjUrfPN1r7crK+qkmLztw/ENS7zemfyx4kGRgw
# Y1WBfFqm/nFlJDPQBicqeU3dOp9hj7WqD0Rc+/4VZ6wQjesIyCkv5uhUNy2LhNDi
# 2leYtAiIFpmjfNk4GngLvC2Tj9IrOMv20Srym5J/Fh7yWAiPeGs3yA3QapjZTtfr
# 7NfzpBIJQ4xT/ic4WGWqhGlRlVBI5u6Ojw3ZxSZCLg3vRC4KYypkh8FdIWoKirji
# dEGlXsNOo+UP/YG5KhebiudTBxGecfJCuuUspIdRhStHAQsjv/dAqWBLlhorq2OC
# aP+wFhE3WPgnnx5pflvlujocPgsN24++ddHrl3O1FFabW8m0UkDHSKCh8QTwTkYO
# wu99iExBVWlbYZRz2qOIBjL/ozEhtCB0auKhfTLLeuNGBUaBz+oZZ+X9UAECoMhk
# ETjb6YfNaI1T7vVAaiuhBoV/JCOQT+RYZrgykyPpzpmwMNFBD1vdW/29q9nkTWoE
# hcEOO0L9NzCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZI
# hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy
# MDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp
# bWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
# AQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25Phdg
# M/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPF
# dvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6
# GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBp
# Dco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50Zu
# yjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3E
# XzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0
# lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1q
# GFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ
# +QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PA
# PBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkw
# EgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxG
# NSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARV
# MFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWlj
# cm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAK
# BggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC
# AYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvX
# zpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20v
# cGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYI
# KwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG
# 9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0x
# M7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmC
# VgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449
# xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wM
# nosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDS
# PeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2d
# Y3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxn
# GSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+Crvs
# QWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokL
# jzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL
# 6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNN
# MIICNQIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn
# MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkRDMDAtMDVFMC1EOTQ3MSUwIwYDVQQD
# ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQDN
# rxRX/iz6ss1lBCXG8P1LFxD0e6CBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
# IFBDQSAyMDEwMB4XDTI0MDcyNTE4MzEwNFoXDTI1MTAyMjE4MzEwNFowgdMxCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jv
# c29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVs
# ZCBUU1MgRVNOOjZCMDUtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGlt
# ZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
# 0UJeLMR/N9WPBZhuKVFF+eWJZ68Wujdj4X6JR05cxO5CepNXo17rVazwWLkm5Aja
# Vh19ZVjDChHzimxsoaXxNu8IDggKwpXvpAAItv4Ux50e9S2uVwfKv57p9JKG+Q7V
# ONShujl1NCMkcgSrPdmd/8zcsmhzcNobLomrCAIORZ8IwhYy4siVQlf1NKhlyAzm
# kWJD0N+60IiogFBzg3yISsvroOx0x1xSi2PiRIQlTXE74MggZDIDKqH/hb9FT2kK
# /nV/aXjuo9LMrrRmn44oYYADe/rO95F+SG3uuuhf+H4IriXr0h9ptA6SwHJPS2Vm
# bNWCjQWq5G4YkrcqbPMax7vNXUwu7T65E8fFPd1IuE9RsG4TMAV7XkXBopmPNfvL
# 0hjxg44kpQn384V46o+zdQqy5K9dDlWm/J6vZtp5yA1PyD3w+HbGubS0niEQ1L6w
# GOrPfzIm0FdOn+xFo48ERl+Fxw/3OvXM5CY1EqnzEznPjzJc7OJwhJVR3VQDHjBc
# EFTOvS9E0diNu1eocw+ZCkz4Pu/oQv+gqU+bfxL8e7PFktfRDlM6FyOzjP4zuI25
# gD8tO9zJg6g6fRpaZc439mAbkl3zCVzTLDgchv6SxQajJtvvoQaZxQf0tRiPcbr2
# HWfMoqqd9uiQ0hTUEhG44FBSTeUPZeEenRCWadCW4G8CAwEAAaOCAUkwggFFMB0G
# A1UdDgQWBBRIwZsJuOcJfScPWcXZuBA4B89K8jAfBgNVHSMEGDAWgBSfpxVdAF5i
# XYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENB
# JTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRp
# bWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1Ud
# JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsF
# AAOCAgEA13kBirH1cHu1WYR1ysj125omGtQ0PaQkEzwGb70xtqSoI+svQihsgdTY
# xaPfp2IVFdgjaMaBi81wB8/nu866FfFKKdhdp3wnMZ91PpP4Ooe7Ncf6qICkgSuw
# gdIdQvqE0h8VQ5QW5sDV4Q0Jnj4f7KHYx4NiM8C4jTw8SQtsuxWiTH2Hikf3QYB7
# 1a7dB9zgHOkW0hgUEeWO9mh2wWqYS/Q48ASjOqYw/ha54oVOff22WaoH+/Hxd9NT
# EU/4vlvsRIMWT0jsnNI71jVArT4Q9Bt6VShWzyqraE6SKUoZrEwBpVsI0LMg2X3h
# OLblC1vxM3+wMyOh97aFOs7sFnuemtI2Mfj8qg16BZTJxXlpPurWrG+OBj4BoTDk
# C9AxXYB3yEtuwMs7pRWLyxIxw/wV9THKUGm+x+VE0POLwkrSMgjulSXkpfELHWWi
# CVslJbFIIB/4Alv+jQJSKAJuo9CErbm2qeDk/zjJYlYaVGMyKuYZ+uSRVKB2qkEP
# cEzG1dO9zIa1Mp32J+zzW3P7suJfjw62s3hDOLk+6lMQOR04x+2o17G3LceLkkxJ
# m41ErdiTjAmdClen9yl6HgMpGS4okjFCJX+CpOFX7gBA3PVxQWubisAQbL5HgTFB
# tQNEzcCdh1GYw/6nzzNNt+0GQnnobBddfOAiqkzvItqXjvGyK1QwggdxMIIFWaAD
# AgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv
# ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIy
# MjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
# MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5
# vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64
# NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhu
# je3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl
# 3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPg
# yY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I
# 5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2
# ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/
# TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy
# 16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y
# 1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6H
# XtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMB
# AAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQW
# BBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30B
# ATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
# L0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYB
# BAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMB
# Af8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBL
# oEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv
# TWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggr
# BgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNS
# b29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1Vffwq
# reEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27
# DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pv
# vinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9Ak
# vUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWK
# NsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2
# kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+
# c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep
# 8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+Dvk
# txW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1Zyvg
# DbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/
# 2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHW
# MIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT
# Hm5TaGllbGQgVFNTIEVTTjo2QjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9z
# b2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAFU9eSpdxs0a0
# 6JFIuGFHIj/I+36ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx
# MDANBgkqhkiG9w0BAQsFAAIFAOsTx1MwIhgPMjAyNDEyMjMxMTI2MTFaGA8yMDI0
# MTIyNDExMjYxMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA6xPHUwIBADAKAgEA
# AgIEpgIB/zAHAgEAAgIULjAKAgUA6xUY0wIBADA2BgorBgEEAYRZCgQCMSgwJjAM
# BgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEB
# CwUAA4IBAQDkPou5w9O3fL9lm7NIu3mAwCMpezmpCbx9mCUfLb4cXznb4psGEspn
# XaDg3PGX1yGC3GR5peByH/hiarlvYv5SZbofvP+iiYFxeLGi+usbC8FQnuWrgyqh
# 7RV01Fm2Is7PGF3NXQaXbGkSQUZzrekeRr4zdV2nIKshANlifSPb/wAd6BLcKtYS
# 3Kr9xUXgZeHxo6tD88GDxJ5FDsG1RxczsdCO5mVqFZUrQqz6Cs49xt7cq2XlEwMX
# 53L40YCUrvYYiTgqvxtOzg58ksUkP1YDfeP9Rel7pGXGyzJF0Fo+FAXiY098HPcW
# eRCGaVV55Keop55er/x0vYOQK3WYmR9ZMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0
# IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAH2gy8malRdIsEAAQAAAfYwDQYJYIZI
# AWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG
# 9w0BCQQxIgQgrAY6roZynzJwSUQzsAfof3O6FxHR94SlM3Hdh+QLWTowgfoGCyqG
# SIb3DQEJEAIvMYHqMIHnMIHkMIG9BCArYUzxlF6m5USLS4f8NXL/8aoNEVdsCZRm
# F+LlQjG2ojCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMz
# AAAB9oMvJmpUXSLBAAEAAAH2MCIEIOEmAHxbUTtc2fET28qfaLGRzaIhD4dw4/ak
# m6mLo6PCMA0GCSqGSIb3DQEBCwUABIICAH4zqNf+CV7yNKXAQwNuEZwzCHs4eJC4
# mNKMRp9e2W++JJaxtY3kLEBoGDKfz+8RYsjcLtNOg83Hd2gEmAmgvWfs/mZlhi8j
# tM5Yj9606ukzuF2797CDwZiXz5JTIs1wIm5+rWuAny0azioafaOZtcaxPqnANbUf
# UHnAYoZ0W6AkSnz99XrqRueh8b3Z7h2A5saVS1/MV1fjfImxH673GlexKRYORTFP
# A9XH8vCvVTIZobKSWa6y/KG4U5dkWrzJuLbT9Kr3x6yk0bO6epG09yy86HmlnmwQ
# bJwBedz4ZpKkvtIJ2U2PYvLti5bztm5WL/hWhDmtXBhoqKy1d/i4LDz7F4vXy9//
# 5Wy8zHMLw4ZFwfywP8/P5pZP7nlvIrordtefS2z3Ipea0thJxwyFJSU8c7OGvPof
# uHhYKMn+Lg1tj5QcIvT7KG0JGp/XWe/CEB9ruOkYZh9VKBlEU2CkDsWeTXFy5heV
# eMPMxRC/GBHPypBHHSrd8BtUsKgehcetdsfQrOI3VLV9gx8SGr8ehSU2Rg0U2UtK
# a4S5THXp0PksrjJLmykIsvBmMgl3uK4KJbu6zh3w5ACSS/OZXzrsowysGjn2QBwb
# hoIjCDhmNLLq2gupcAhPCgqUX6Ixmg8H0SlqoRp0mZTss7ZS+ErxTQoFBbLkoX5F
# 9HjkIOcM6/0F
# SIG # End signature block
# IFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7OQtPTAiGA8yMDI1MTIxMDE3MzI0
# NVoYDzIwMjUxMjExMTczMjQ1WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDs5C09
# AgEAMAcCAQACAgjlMAcCAQACAhNOMAoCBQDs5X69AgEAMDYGCisGAQQBhFkKBAIx
# KDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZI
# hvcNAQELBQADggEBAFXCcBVLkxGEigIad7gAMsj2+SQdBANpzq4qPJXOu81TM3HC
# rAkCUTm3FRNc6YPdpfvl07lGlv/NHFCLyXL20d6PZ/1wlF5+WR2OvWjrktwDxYv8
# cZqk7BrV9SB8xBe/GwVi7smKmlXhznqA6lFPO+VNfOwWcxn0H2yxEsAJKyDmgx/7
# M8xnMTKeK8ulgSy4EoyGgFIO+nGHqxS0yaXe+OgzErkaavB1Qw7jfmm5/wlBCnwz
# 0UsbaequeL9UjA6FUw3Cc3F+3/D38BzyjJtTxjUVn+QiVWwOfikRJ2F7oZwpsJo3
# yNIVpwJFpIV6VsqtxzaF0KQZBpS2lBGxVA17pFcxggQNMIIECQIBATCBkzB8MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy
# b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgO7HlwAOGx0ygABAAACAzAN
# BglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8G
# CSqGSIb3DQEJBDEiBCApggCahSc04fWyIz1KF4aeejwqHefyj2gzz7p9QsluFTCB
# +gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIEsD3RtxlvaTxFOZZnpQw0DksPmV
# duo5SyK9h9w++hMtMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
# c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
# MTACEzMAAAIDux5cADhsdMoAAQAAAgMwIgQgwIRXpw5w7cRbWSfOFZ15Z2Nf90Hi
# Ms/hZSpx+kv4aHcwDQYJKoZIhvcNAQELBQAEggIAM+zwgqPLhBOAumqVnUO/YRh7
# sePgzUWqveSw/J01TAD8JVXufiGmu4neLrGFki/Nz8ytun2DhJP/3xDRu39y/9Pb
# t2qKabzaoASwH95fTjHLYEp0PhqkEZ1hkaaYjVC3TAG0LgU2mrvkEjL3doD5MXu8
# WWQGcnB0Wera/3POf4ylyQbUUnzo/Pl9qUbjPVW/JouzzDzijObLcYp7IDgIDxGL
# sVJqMgzP1ZWBWsjjx4J0YiYORUnIVKWKPXt/0O3X9VO3zDfOnWRLF8mJj+ybEnqa
# Wd8LxLJnCxpmTAjtELLgC46UB0N4GHR0+ymSba35Ciz4Kzc+7R9E1Ajy1yd2rmGR
# M2u/eAV8MvKybIzgTd9Lukk9KJ5lvzV52CuYyzHOzYgcNt/mFgvM6gfMAef3CeN0
# EU7ECvTEYqno7krSRi6+HD+R14+7EwXbiR0E+KAB2Ppgj7GqHWKeL/Owyv0A1oEa
# 4ocdqMApLcY908U7IzNu5qo7PPas/RBsB9J52++fyZ/9RyP31IYKu8/5xI5Ef7aH
# XIopbEpuMHpHeuWlYWlfkULa5tjk4iPVCTRVsgn7IimLY/wgVOLL4ueOzZZ6aNws
# Q37w/ocvXIH/qXUllulfh5vINVYqXK3d+l0QT8LCMIxXpJSSgtcFcPJG6aSdOFRQ
# r6EOj+C9DH5MueMd9SY=
# SIG # End signature block

View File

@@ -477,7 +477,7 @@ get_normalized_quality() {
local quality="$(to_lowercase "$1")"
if [ ! -z "$quality" ]; then
case "$quality" in
daily | signed | validated | preview)
daily | preview)
echo "$quality"
return 0
;;
@@ -486,7 +486,7 @@ get_normalized_quality() {
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."
say_err "'$quality' is not a supported value for --quality option. Supported values are: daily, preview, ga. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues."
return 1
;;
esac
@@ -661,7 +661,7 @@ parse_globaljson_file_for_version() {
return 1
fi
sdk_section=$(cat $json_file | tr -d "\r" | awk '/"sdk"/,/}/')
sdk_section=$(cat "$json_file" | tr -d "\r" | awk '/"sdk"/,/}/')
if [ -z "$sdk_section" ]; then
say_err "Unable to parse the SDK node in \`$json_file\`"
return 1
@@ -783,7 +783,7 @@ get_specific_product_version() {
if machine_has "curl"
then
if ! specific_product_version=$(curl -s --fail "${download_link}${feed_credential}" 2>&1); then
if ! specific_product_version=$(curl -sL --fail "${download_link}${feed_credential}" 2>&1); then
continue
else
echo "${specific_product_version//[$'\t\r\n']}"
@@ -1169,11 +1169,11 @@ download() {
exit 1
fi
if [ "$failed" = false ] || [ $attempts -ge 3 ] || { [ ! -z $http_code ] && [ $http_code = "404" ]; }; then
if [ "$failed" = false ] || [ $attempts -ge 3 ] || { [ -n "${http_code-}" ] && [ "${http_code}" = "404" ]; }; then
break
fi
say "Download attempt #$attempts has failed: $http_code $download_error_msg"
say "Download attempt #$attempts has failed: ${http_code-} ${download_error_msg-}"
say "Attempt #$((attempts+1)) will start in $((attempts*10)) seconds."
sleep $((attempts*10))
done
@@ -1198,13 +1198,19 @@ downloadcurl() {
local curl_options="--retry 20 --retry-delay 2 --connect-timeout 15 -sSL -f --create-dirs "
local curl_exit_code=0;
if [ -z "$out_path" ]; then
curl $curl_options "$remote_path_with_credential" 2>&1
curl_output=$(curl $curl_options "$remote_path_with_credential" 2>&1)
curl_exit_code=$?
echo "$curl_output"
else
curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1
curl_output=$(curl $curl_options -o "$out_path" "$remote_path_with_credential" 2>&1)
curl_exit_code=$?
fi
# Regression in curl causes curl with --retry to return a 0 exit code even when it fails to download a file - https://github.com/curl/curl/issues/17554
if [ $curl_exit_code -eq 0 ] && echo "$curl_output" | grep -q "^curl: ([0-9]*) "; then
curl_exit_code=$(echo "$curl_output" | sed 's/curl: (\([0-9]*\)).*/\1/')
fi
if [ $curl_exit_code -gt 0 ]; then
download_error_msg="Unable to download $remote_path."
# Check for curl timeout codes
@@ -1272,61 +1278,6 @@ downloadwget() {
return 0
}
extract_stem() {
local url="$1"
# extract the protocol
proto="$(echo $1 | grep :// | sed -e's,^\(.*://\).*,\1,g')"
# remove the protocol
url="${1/$proto/}"
# extract the path (if any) - since we know all of our feeds have a first path segment, we can skip the first one. otherwise we'd use -f2- to get the full path
full_path="$(echo $url | grep / | cut -d/ -f2-)"
path="$(echo $full_path | cut -d/ -f2-)"
echo $path
}
check_url_exists() {
eval $invocation
local url="$1"
local code=""
if machine_has "curl"
then
code=$(curl --head -o /dev/null -w "%{http_code}" -s --fail "$url");
elif machine_has "wget"
then
# get the http response, grab the status code
server_response=$(wget -qO- --method=HEAD --server-response "$url" 2>&1)
code=$(echo "$server_response" | grep "HTTP/" | awk '{print $2}')
fi
if [ $code = "200" ]; then
return 0
else
return 1
fi
}
sanitize_redirect_url() {
eval $invocation
local url_stem
url_stem=$(extract_stem "$1")
say_verbose "Checking configured feeds for the asset at ${yellow:-}$url_stem${normal:-}"
for feed in "${feeds[@]}"
do
local trial_url="$feed/$url_stem"
say_verbose "Checking ${yellow:-}$trial_url${normal:-}"
if check_url_exists "$trial_url"; then
say_verbose "Found a match at ${yellow:-}$trial_url${normal:-}"
echo "$trial_url"
return 0
else
say_verbose "No match at ${yellow:-}$trial_url${normal:-}"
fi
done
return 1
}
get_download_link_from_aka_ms() {
eval $invocation
@@ -1361,13 +1312,13 @@ get_download_link_from_aka_ms() {
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' )
# Allow intermediate 301 redirects and tolerate proxy-injected 200s
broken_redirects=$( echo "$http_codes" | sed '$d' | grep -vE '^(301|200)$' )
# The response may end without final code 2xx/4xx/5xx somehow, e.g. network restrictions on www.bing.com causes redirecting to bing.com fails with connection refused.
# In this case it should not exclude the last.
last_http_code=$( echo "$http_codes" | tail -n 1 )
if ! [[ $last_http_code =~ ^(2|4|5)[0-9][0-9]$ ]]; then
broken_redirects=$( echo "$http_codes" | grep -v '301' )
broken_redirects=$( echo "$http_codes" | grep -vE '^(301|200)$' )
fi
# All HTTP codes are 301 (Moved Permanently), the redirect link exists.
@@ -1379,11 +1330,6 @@ get_download_link_from_aka_ms() {
return 1
fi
sanitized_redirect_url=$(sanitize_redirect_url "$aka_ms_download_link")
if [[ -n "$sanitized_redirect_url" ]]; then
aka_ms_download_link="$sanitized_redirect_url"
fi
say_verbose "The redirect location retrieved: '$aka_ms_download_link'."
return 0
else
@@ -1396,24 +1342,15 @@ get_feeds_to_use()
{
feeds=(
"https://builds.dotnet.microsoft.com/dotnet"
"https://dotnetcli.azureedge.net/dotnet"
"https://ci.dot.net/public"
"https://dotnetbuilds.azureedge.net/public"
)
if [[ -n "$azure_feed" ]]; then
feeds=("$azure_feed")
fi
if [[ "$no_cdn" == "true" ]]; then
feeds=(
"https://dotnetcli.blob.core.windows.net/dotnet"
"https://dotnetbuilds.blob.core.windows.net/public"
)
if [[ -n "$uncached_feed" ]]; then
feeds=("$uncached_feed")
fi
if [[ -n "$uncached_feed" ]]; then
feeds=("$uncached_feed")
fi
}
@@ -1545,7 +1482,7 @@ generate_regular_links() {
link_types+=("legacy")
else
legacy_download_link=""
say_verbose "Cound not construct a legacy_download_link; omitting..."
say_verbose "Could not construct a legacy_download_link; omitting..."
fi
# Check if the SDK version is already installed.
@@ -1643,12 +1580,12 @@ install_dotnet() {
download "$download_link" "$zip_path" 2>&1 || download_failed=true
if [ "$download_failed" = true ]; then
case $http_code in
case ${http_code-} in
404)
say "The resource at $link_type link '$download_link' is not available."
;;
*)
say "Failed to download $link_type link '$download_link': $download_error_msg"
say "Failed to download $link_type link '$download_link': ${http_code-} ${download_error_msg-}"
;;
esac
rm -f "$zip_path" 2>&1 && say_verbose "Temporary archive file $zip_path was removed"
@@ -1709,7 +1646,6 @@ install_dir="<auto>"
architecture="<auto>"
dry_run=false
no_path=false
no_cdn=false
azure_feed=""
uncached_feed=""
feed_credential=""
@@ -1782,10 +1718,6 @@ do
verbose=true
non_dynamic_parameters+=" $name"
;;
--no-cdn|-[Nn]o[Cc]dn)
no_cdn=true
non_dynamic_parameters+=" $name"
;;
--azure-feed|-[Aa]zure[Ff]eed)
shift
azure_feed="$1"
@@ -1862,9 +1794,8 @@ do
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 " The possible values are: daily, preview, GA."
echo " Works only in combination with channel. Not applicable for STS and LTS channels and will be ignored if those channels are used."
echo " 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."
@@ -1890,13 +1821,10 @@ do
echo " --verbose,-Verbose Display diagnostics information."
echo " --azure-feed,-AzureFeed For internal use only."
echo " Allows using a different storage to download SDK archives from."
echo " This parameter is only used if --no-cdn is false."
echo " --uncached-feed,-UncachedFeed For internal use only."
echo " Allows using a different storage to download SDK archives from."
echo " This parameter is only used if --no-cdn is true."
echo " --skip-non-versioned-files Skips non-versioned files if they already exist, such as the dotnet executable."
echo " -SkipNonVersionedFiles"
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
echo " Note: global.json must have a value for 'SDK:Version'"
echo " --keep-zip,-KeepZip If set, downloaded file is kept."

1918
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,12 @@
{
"name": "setup-dotnet",
"version": "4.0.0",
"version": "5.0.1",
"private": true,
"description": "setup dotnet action",
"main": "dist/setup/index.js",
"engines": {
"node": ">=24.0.0"
},
"scripts": {
"build": "ncc build -o dist/setup src/setup-dotnet.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
@@ -26,35 +29,35 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.2.4",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.1",
"@actions/cache": "^5.0.1",
"@actions/core": "^2.0.0",
"@actions/exec": "^2.0.0",
"@actions/github": "^6.0.0",
"@actions/glob": "^0.4.0",
"@actions/http-client": "^2.2.1",
"@actions/glob": "^0.5.0",
"@actions/http-client": "^3.0.0",
"@actions/io": "^1.0.2",
"fast-xml-parser": "^4.4.1",
"fast-xml-parser": "^5.3.6",
"json5": "^2.2.3",
"semver": "^7.6.0"
},
"devDependencies": {
"@types/jest": "^29.5.12",
"@types/node": "^20.11.29",
"@types/node": "^24.1.0",
"@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^7.3.0",
"@typescript-eslint/parser": "^7.3.0",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"@vercel/ncc": "^0.38.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-jest": "^27.9.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-node": "^11.1.0",
"husky": "^8.0.1",
"husky": "^9.1.7",
"jest": "^29.7.0",
"jest-circus": "^29.7.0",
"jest-each": "^29.7.0",
"prettier": "^3.2.5",
"ts-jest": "^29.1.2",
"typescript": "^5.4.2",
"typescript": "^5.9.2",
"wget-improved": "^3.2.1"
},
"jest": {

View File

@@ -102,16 +102,9 @@ export class DotnetVersionResolver {
maxRetries: 3
});
let response;
try {
response = await httpClient.getJson<any>(
DotnetVersionResolver.DotnetCoreIndexUrl
);
} catch (error) {
response = await httpClient.getJson<any>(
DotnetVersionResolver.DotnetCoreIndexFallbackUrl
);
}
const response = await httpClient.getJson<any>(
DotnetVersionResolver.DotnetCoreIndexUrl
);
const result = response.result || {};
const releasesInfo: any[] = result['releases-index'];
@@ -132,8 +125,6 @@ export class DotnetVersionResolver {
static DotnetCoreIndexUrl =
'https://builds.dotnet.microsoft.com/dotnet/release-metadata/releases-index.json';
static DotnetCoreIndexFallbackUrl =
'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
}
export class DotnetInstallScript {
@@ -193,6 +184,16 @@ export class DotnetInstallScript {
return this;
}
// When architecture is empty/undefined, the installer auto-detects the current runner architecture.
public useArchitecture(architecture?: string) {
if (!architecture) return this;
this.useArguments(
IS_WINDOWS ? '-Architecture' : '--architecture',
architecture
);
return this;
}
public useVersion(dotnetVersion: DotnetVersion, quality?: QualityOptions) {
if (dotnetVersion.type) {
this.useArguments(dotnetVersion.type, dotnetVersion.value);
@@ -259,6 +260,17 @@ export abstract class DotnetInstallDir {
}
}
export function normalizeArch(arch: string): string {
switch (arch.toLowerCase()) {
case 'amd64':
return 'x64';
case 'ia32':
return 'x86';
default:
return arch.toLowerCase();
}
}
export class DotnetCoreInstaller {
static {
DotnetInstallDir.setEnvironmentVariable();
@@ -266,18 +278,30 @@ export class DotnetCoreInstaller {
constructor(
private version: string,
private quality: QualityOptions
private quality: QualityOptions,
private architecture?: string
) {}
public async installDotnet(): Promise<string | null> {
const versionResolver = new DotnetVersionResolver(this.version);
const dotnetVersion = await versionResolver.createDotnetVersion();
const architectureArguments =
this.architecture &&
normalizeArch(this.architecture) !== normalizeArch(os.arch())
? [
IS_WINDOWS ? '-InstallDir' : '--install-dir',
IS_WINDOWS
? `"${path.join(DotnetInstallDir.dirPath, this.architecture)}"`
: path.join(DotnetInstallDir.dirPath, this.architecture)
]
: [];
/**
* Install dotnet runitme first in order to get
* Install dotnet runtime first in order to get
* the latest stable version of dotnet CLI
*/
const runtimeInstallOutput = await new DotnetInstallScript()
.useArchitecture(this.architecture)
// If dotnet CLI is already installed - avoid overwriting it
.useArguments(
IS_WINDOWS ? '-SkipNonVersionedFiles' : '--skip-non-versioned-files'
@@ -286,6 +310,7 @@ export class DotnetCoreInstaller {
.useArguments(IS_WINDOWS ? '-Runtime' : '--runtime', 'dotnet')
// Use latest stable version
.useArguments(IS_WINDOWS ? '-Channel' : '--channel', 'LTS')
.useArguments(...architectureArguments)
.execute();
if (runtimeInstallOutput.exitCode) {
@@ -303,12 +328,14 @@ export class DotnetCoreInstaller {
* dotnet CLI
*/
const dotnetInstallOutput = await new DotnetInstallScript()
.useArchitecture(this.architecture)
// Don't overwrite CLI because it should be already installed
.useArguments(
IS_WINDOWS ? '-SkipNonVersionedFiles' : '--skip-non-versioned-files'
)
// Use version provided by user
.useVersion(dotnetVersion, this.quality)
.useArguments(...architectureArguments)
.execute();
if (dotnetInstallOutput.exitCode) {

View File

@@ -1,8 +1,14 @@
import * as core from '@actions/core';
import {DotnetCoreInstaller, DotnetInstallDir} from './installer';
import * as exec from '@actions/exec';
import {
DotnetCoreInstaller,
DotnetInstallDir,
normalizeArch
} from './installer';
import * as fs from 'fs';
import path from 'path';
import semver from 'semver';
import os from 'os';
import * as auth from './authutil';
import {isCacheFeatureAvailable} from './cache-utils';
import {restoreCache} from './cache-restore';
@@ -16,6 +22,17 @@ const qualityOptions = [
'preview',
'ga'
] as const;
const supportedArchitectures = [
'x64',
'x86',
'arm64',
'amd64',
'arm',
's390x',
'ppc64le',
'riscv64'
] as const;
type SupportedArchitecture = (typeof supportedArchitectures)[number];
export type QualityOptions = (typeof qualityOptions)[number];
@@ -32,6 +49,7 @@ export async function run() {
//
const versions = core.getMultilineInput('dotnet-version');
const installedDotnetVersions: (string | null)[] = [];
const architecture = getArchitectureInput();
const globalJsonFileInput = core.getInput('global-json-file');
if (globalJsonFileInput) {
@@ -69,11 +87,46 @@ export async function run() {
let dotnetInstaller: DotnetCoreInstaller;
const uniqueVersions = new Set<string>(versions);
for (const version of uniqueVersions) {
dotnetInstaller = new DotnetCoreInstaller(version, quality);
dotnetInstaller = new DotnetCoreInstaller(
version,
quality,
architecture
);
const installedVersion = await dotnetInstaller.installDotnet();
installedDotnetVersions.push(installedVersion);
}
if (
architecture &&
normalizeArch(architecture) !== normalizeArch(os.arch())
) {
process.env['DOTNET_INSTALL_DIR'] = path.join(
DotnetInstallDir.dirPath,
architecture
);
}
DotnetInstallDir.addToPath();
const workloadsInput = core.getInput('workloads');
if (workloadsInput) {
const workloads = workloadsInput
.split(',')
.map(w => w.trim())
.filter(Boolean);
if (workloads.length) {
try {
core.info(`Refreshing workload manifests...`);
await exec.exec('dotnet', ['workload', 'update']);
core.info(`Installing workloads: ${workloads.join(', ')}`);
await exec.exec('dotnet', ['workload', 'install', ...workloads]);
} catch (err) {
throw new Error(
`Failed to install workloads [${workloads.join(', ')}]: ${err}`
);
}
}
}
}
const sourceUrl: string = core.getInput('source-url');
@@ -96,6 +149,20 @@ export async function run() {
}
}
function getArchitectureInput(): SupportedArchitecture | '' {
const raw = (core.getInput('architecture') || '').trim();
if (!raw) return '';
const normalized = raw.toLowerCase();
if ((supportedArchitectures as readonly string[]).includes(normalized)) {
return normalizeArch(normalized) as SupportedArchitecture;
}
throw new Error(
`Value '${raw}' is not supported for the 'architecture' option. Supported values are: ${supportedArchitectures.join(
', '
)}.`
);
}
function getVersionFromGlobalJson(globalJsonPath: string): string {
let version = '';
const globalJson = JSON5.parse(

View File

@@ -2,10 +2,10 @@
"compilerOptions": {
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"target": "ES2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"lib": [
"es6"
"ES2022"
],
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */