Merge 4500965761c4a98d189004e2fb2d30427eb2041e into ba848a34bbdefdb860a6d759e2fda6e0f6f4f2f1

This commit is contained in:
João Caracinha 2024-05-22 21:53:14 +00:00 committed by GitHub
commit 554b0af713
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
72 changed files with 138975 additions and 22885 deletions

View File

@ -229,6 +229,31 @@ jobs:
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2"
test-global-json-with-comments:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Write global.json
shell: bash
run: |
mkdir subdirectory
echo '/* should support comments */ {"sdk":{"version": "2.2.207","rollForward": "latestFeature"}} // should support comments' > ./subdirectory/global.json
- name: Setup dotnet
uses: ./
with:
global-json-file: ./subdirectory/global.json
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2"
test-setup-with-dotnet-quality:
runs-on: ${{ matrix.operating-system }}
strategy:
@ -251,6 +276,66 @@ jobs:
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-"
test-setup-with-cache:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Copy NuGet lock file to root
shell: bash
run: cp ./__tests__/e2e-test-csproj/packages.lock.json ./packages.lock.json
- name: Setup .NET Core 3.1
id: setup-dotnet
uses: ./
with:
dotnet-version: 3.1
cache: true
- name: Verify Cache
if: steps.setup-dotnet.outputs.cache-hit == 'true'
shell: bash
run: if [[ -e ${NUGET_PACKAGES} ]]; then exit 0; else exit 1; fi
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1"
test-setup-with-cache-dependency-path:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup .NET Core 3.1
id: setup-dotnet
uses: ./
with:
dotnet-version: 3.1
cache: true
cache-dependency-path: './__tests__/e2e-test-csproj/packages.lock.json'
- name: Verify Cache
if: steps.setup-dotnet.outputs.cache-hit == 'true'
shell: bash
run: if [[ -e ${NUGET_PACKAGES} ]]; then exit 0; else exit 1; fi
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1"
test-dotnet-version-output-during-single-version-installation:
runs-on: ${{ matrix.operating-system }}
strategy:
@ -366,3 +451,33 @@ jobs:
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$" -CheckNugetConfig
test-sequential-version-installation:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
lower-version: ['3.1.426']
higher-version: ['7.0.203']
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
# Install one version, use it for something, then switch to next version
- name: Setup dotnet (lower version)
uses: ./
with:
dotnet-version: ${{ matrix.lower-version }}
- name: Verify dotnet (lower version)
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.lower-version }}$"
- name: Setup dotnet (higher version)
uses: ./
with:
dotnet-version: ${{ matrix.higher-version }}
- name: Verify dotnet (higher version)
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.lower-version }}$", "^${{ matrix.higher-version }}$"

View File

@ -3,6 +3,7 @@ sources:
allowed:
- apache-2.0
- 0bsd
- bsd-2-clause
- bsd-3-clause
- isc
@ -12,3 +13,4 @@ allowed:
reviewed:
npm:
- sax # ISC + MIT

20
.licenses/npm/@actions/cache.dep.yml generated Normal file
View File

@ -0,0 +1,20 @@
---
name: "@actions/cache"
version: 3.2.1
type: npm
summary: Actions cache lib
homepage: https://github.com/actions/toolkit/tree/main/packages/cache
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@ -0,0 +1,20 @@
---
name: "@actions/glob"
version: 0.1.2
type: npm
summary: Actions glob lib
homepage: https://github.com/actions/toolkit/tree/main/packages/glob
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@ -0,0 +1,20 @@
---
name: "@actions/glob"
version: 0.3.0
type: npm
summary: Actions glob lib
homepage: https://github.com/actions/toolkit/tree/main/packages/glob
license: mit
licenses:
- sources: LICENSE.md
text: |-
The MIT License (MIT)
Copyright 2019 GitHub
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@ -0,0 +1,32 @@
---
name: "@azure/abort-controller"
version: 1.1.0
type: npm
summary: Microsoft Azure SDK for JavaScript - Aborter
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/abort-controller/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

33
.licenses/npm/@azure/core-auth.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: "@azure/core-auth"
version: 1.4.0
type: npm
summary: Provides low-level interfaces and helper methods for authentication in Azure
SDK
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-auth/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

33
.licenses/npm/@azure/core-http.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: "@azure/core-http"
version: 3.0.1
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-http/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

33
.licenses/npm/@azure/core-lro.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: "@azure/core-lro"
version: 2.5.2
type: npm
summary: Isomorphic client library for supporting long-running operations in node.js
and browser.
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-lro/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

32
.licenses/npm/@azure/core-paging.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@azure/core-paging"
version: 1.5.0
type: npm
summary: Core types for paging async iterable iterators
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/core-paging/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

View File

@ -0,0 +1,32 @@
---
name: "@azure/core-tracing"
version: 1.0.0-preview.13
type: npm
summary: Provides low-level interfaces and helper methods for tracing in Azure SDK
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-tracing/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

32
.licenses/npm/@azure/core-util.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@azure/core-util"
version: 1.3.1
type: npm
summary: Core library for shared utility methods
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/core/core-util/
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

32
.licenses/npm/@azure/logger.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@azure/logger"
version: 1.0.4
type: npm
summary: Microsoft Azure SDK for JavaScript - Logger
homepage: https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger/README.md
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

33
.licenses/npm/@azure/ms-rest-js.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: "@azure/ms-rest-js"
version: 2.7.0
type: npm
summary: Isomorphic client Runtime for Typescript/node.js/browser javascript client
libraries generated using AutoRest
homepage: https://github.com/Azure/ms-rest-js
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
notices: []

View File

@ -0,0 +1,32 @@
---
name: "@azure/storage-blob"
version: 12.14.0
type: npm
summary: Microsoft Azure Storage SDK for JavaScript - Blob
homepage: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/storage-blob/
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2020 Microsoft
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

223
.licenses/npm/@opentelemetry/api.dep.yml generated Normal file
View File

@ -0,0 +1,223 @@
---
name: "@opentelemetry/api"
version: 1.4.1
type: npm
summary: Public API for OpenTelemetry
homepage: https://github.com/open-telemetry/opentelemetry-js/tree/main/api
license: apache-2.0
licenses:
- sources: LICENSE
text: |2
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- sources: README.md
text: |-
Apache 2.0 - See [LICENSE][license-url] for more information.
[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md
notices: []

32
.licenses/npm/@types/node-fetch.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@types/node-fetch"
version: 2.6.3
type: npm
summary: TypeScript definitions for node-fetch
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node-fetch
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
notices: []

32
.licenses/npm/@types/node.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@types/node"
version: 16.11.25
type: npm
summary: TypeScript definitions for Node.js
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
notices: []

32
.licenses/npm/@types/tunnel.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: "@types/tunnel"
version: 0.0.3
type: npm
summary: TypeScript definitions for tunnel
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/tunnel
license: mit
licenses:
- sources: LICENSE
text: |2
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
notices: []

32
.licenses/npm/abort-controller.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: abort-controller
version: 3.0.0
type: npm
summary: An implementation of WHATWG AbortController interface.
homepage: https://github.com/mysticatea/abort-controller#readme
license: mit
licenses:
- sources: LICENSE
text: |
MIT License
Copyright (c) 2017 Toru Nagashima
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

34
.licenses/npm/asynckit.dep.yml generated Normal file
View File

@ -0,0 +1,34 @@
---
name: asynckit
version: 0.4.0
type: npm
summary: Minimal async jobs utility library, with streams support
homepage: https://github.com/alexindigo/asynckit#readme
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2016 Alex Indigo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- sources: README.md
text: AsyncKit is licensed under the MIT license.
notices: []

55
.licenses/npm/balanced-match.dep.yml generated Normal file
View File

@ -0,0 +1,55 @@
---
name: balanced-match
version: 1.0.2
type: npm
summary: Match balanced character pairs, like "{" and "}"
homepage: https://github.com/juliangruber/balanced-match
license: mit
licenses:
- sources: LICENSE.md
text: |
(MIT)
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- sources: README.md
text: |-
(MIT)
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

55
.licenses/npm/brace-expansion.dep.yml generated Normal file
View File

@ -0,0 +1,55 @@
---
name: brace-expansion
version: 1.1.11
type: npm
summary: Brace expansion as known from sh/bash
homepage: https://github.com/juliangruber/brace-expansion
license: mit
licenses:
- sources: LICENSE
text: |
MIT License
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- sources: README.md
text: |-
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

32
.licenses/npm/combined-stream.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: combined-stream
version: 1.0.8
type: npm
summary: A stream that emits multiple other streams one after another.
homepage: https://github.com/felixge/node-combined-stream
license: mit
licenses:
- sources: License
text: |
Copyright (c) 2011 Debuggable Limited <felix@debuggable.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: Readme.md
text: combined-stream is licensed under the MIT license.
notices: []

31
.licenses/npm/concat-map.dep.yml generated Normal file
View File

@ -0,0 +1,31 @@
---
name: concat-map
version: 0.0.1
type: npm
summary: concatenative mapdashery
homepage:
license: other
licenses:
- sources: LICENSE
text: |
This software is released under the MIT license:
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.markdown
text: MIT
notices: []

32
.licenses/npm/delayed-stream.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: delayed-stream
version: 1.0.0
type: npm
summary: Buffers events from a stream until you are ready to handle them.
homepage: https://github.com/felixge/node-delayed-stream
license: mit
licenses:
- sources: License
text: |
Copyright (c) 2011 Debuggable Limited <felix@debuggable.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: Readme.md
text: delayed-stream is licensed under the MIT license.
notices: []

33
.licenses/npm/event-target-shim.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: event-target-shim
version: 5.0.1
type: npm
summary: An implementation of WHATWG EventTarget interface.
homepage: https://github.com/mysticatea/event-target-shim
license: mit
licenses:
- sources: LICENSE
text: |+
The MIT License (MIT)
Copyright (c) 2015 Toru Nagashima
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices: []

38
.licenses/npm/events.dep.yml generated Normal file
View File

@ -0,0 +1,38 @@
---
name: events
version: 3.3.0
type: npm
summary: Node's event emitter for all engines.
homepage:
license: mit
licenses:
- sources: LICENSE
text: |
MIT
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: Readme.md
text: |-
[MIT](./LICENSE)
[node.js docs]: https://nodejs.org/dist/v11.13.0/docs/api/events.html
notices: []

View File

@ -1,6 +1,6 @@
---
name: fast-xml-parser
version: 4.0.10
version: 4.2.5
type: npm
summary: Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback.
homepage: https://github.com/NaturalIntelligence/fast-xml-parser#readme

33
.licenses/npm/form-data-2.5.1.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: form-data
version: 2.5.1
type: npm
summary: A library to create readable "multipart/form-data" streams. Can be used to
submit forms and file uploads to other web applications.
homepage:
license: mit
licenses:
- sources: License
text: |
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: README.md
text: Form-Data is released under the [MIT](License) license.
notices: []

33
.licenses/npm/form-data-3.0.1.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: form-data
version: 3.0.1
type: npm
summary: A library to create readable "multipart/form-data" streams. Can be used to
submit forms and file uploads to other web applications.
homepage:
license: mit
licenses:
- sources: License
text: |
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: Readme.md
text: Form-Data is released under the [MIT](License) license.
notices: []

33
.licenses/npm/form-data-4.0.0.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: form-data
version: 4.0.0
type: npm
summary: A library to create readable "multipart/form-data" streams. Can be used to
submit forms and file uploads to other web applications.
homepage:
license: mit
licenses:
- sources: License
text: |
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
- sources: Readme.md
text: Form-Data is released under the [MIT](License) license.
notices: []

36
.licenses/npm/json5.dep.yml generated Normal file
View File

@ -0,0 +1,36 @@
---
name: json5
version: 2.2.3
type: npm
summary: JSON for Humans
homepage: http://json5.org/
license: mit
licenses:
- sources: LICENSE.md
text: |
MIT License
Copyright (c) 2012-2018 Aseem Kishore, and [others].
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[others]: https://github.com/json5/json5/contributors
- sources: README.md
text: MIT. See [LICENSE.md](./LICENSE.md) for details.
notices: []

34
.licenses/npm/mime-db.dep.yml generated Normal file
View File

@ -0,0 +1,34 @@
---
name: mime-db
version: 1.52.0
type: npm
summary: Media Type Database
homepage:
license: mit
licenses:
- sources: LICENSE
text: |
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015-2022 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

47
.licenses/npm/mime-types.dep.yml generated Normal file
View File

@ -0,0 +1,47 @@
---
name: mime-types
version: 2.1.35
type: npm
summary: The ultimate javascript content-type utility.
homepage:
license: mit
licenses:
- sources: LICENSE
text: |
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- sources: README.md
text: |-
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/jshttp/mime-types/master?label=ci
[ci-url]: https://github.com/jshttp/mime-types/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/mime-types/master
[coveralls-url]: https://coveralls.io/r/jshttp/mime-types?branch=master
[node-version-image]: https://badgen.net/npm/node/mime-types
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/mime-types
[npm-url]: https://npmjs.org/package/mime-types
[npm-version-image]: https://badgen.net/npm/v/mime-types
notices: []

26
.licenses/npm/minimatch.dep.yml generated Normal file
View File

@ -0,0 +1,26 @@
---
name: minimatch
version: 3.1.2
type: npm
summary: a glob matcher in javascript
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []

33
.licenses/npm/process.dep.yml generated Normal file
View File

@ -0,0 +1,33 @@
---
name: process
version: 0.11.10
type: npm
summary: process information for node.js and browsers
homepage:
license: mit
licenses:
- sources: LICENSE
text: |
(The MIT License)
Copyright (c) 2013 Roman Shtylman <shtylman@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

52
.licenses/npm/sax.dep.yml generated Normal file
View File

@ -0,0 +1,52 @@
---
name: sax
version: 1.2.4
type: npm
summary: An evented streaming XML parser in JavaScript
homepage:
license: other
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
====
`String.fromCodePoint` by Mathias Bynens used according to terms of MIT
License, as follows:
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
notices: []

View File

@ -1,9 +1,9 @@
---
name: semver
version: 6.3.0
version: 5.7.2
type: npm
summary: The semantic version parser used by npm.
homepage: https://github.com/npm/node-semver#readme
homepage:
license: isc
licenses:
- sources: LICENSE

View File

@ -1,6 +1,6 @@
---
name: semver
version: 5.7.0
version: 6.3.1
type: npm
summary: The semantic version parser used by npm.
homepage: https://github.com/npm/node-semver#readme

View File

@ -1,6 +1,6 @@
---
name: signal-exit
version: 3.0.2
version: 3.0.7
type: npm
summary: when you want to fire an event no matter how a process exits.
homepage: https://github.com/tapjs/signal-exit

35
.licenses/npm/tslib-1.14.1.dep.yml generated Normal file
View File

@ -0,0 +1,35 @@
---
name: tslib
version: 1.14.1
type: npm
summary: Runtime library for TypeScript helper functions
homepage: https://www.typescriptlang.org/
license: 0bsd
licenses:
- sources: LICENSE.txt
text: |-
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
notices:
- sources: CopyrightNotice.txt
text: "/*! *****************************************************************************\r\nCopyright
(c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute
this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE
SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE,
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS
SOFTWARE.\r\n*****************************************************************************
*/"

23
.licenses/npm/tslib-2.5.0.dep.yml generated Normal file
View File

@ -0,0 +1,23 @@
---
name: tslib
version: 2.5.0
type: npm
summary: Runtime library for TypeScript helper functions
homepage: https://www.typescriptlang.org/
license: 0bsd
licenses:
- sources: LICENSE.txt
text: |-
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
notices: []

View File

@ -3,8 +3,8 @@ name: universal-user-agent
version: 4.0.0
type: npm
summary: Get a user agent string in both browser and node
homepage: https://github.com/gr2m/universal-user-agent#readme
license: other
homepage:
license: isc
licenses:
- sources: LICENSE.md
text: |

39
.licenses/npm/uuid-3.4.0.dep.yml generated Normal file
View File

@ -0,0 +1,39 @@
---
name: uuid
version: 3.4.0
type: npm
summary: RFC4122 (v1, v4, and v5) UUIDs
homepage:
license: mit
licenses:
- sources: LICENSE.md
text: |
The MIT License (MIT)
Copyright (c) 2010-2016 Robert Kieffer and other contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
notices:
- sources: AUTHORS
text: |-
Robert Kieffer <robert@broofa.com>
Christoph Tavan <dev@tavan.de>
AJ ONeal <coolaj86@gmail.com>
Vincent Voyer <vincent@zeroload.net>
Roman Shtylman <shtylman@gmail.com>

30
.licenses/npm/xml2js.dep.yml generated Normal file
View File

@ -0,0 +1,30 @@
---
name: xml2js
version: 0.5.0
type: npm
summary: Simple XML to JavaScript object converter.
homepage: https://github.com/Leonidas-from-XIV/node-xml2js
license: mit
licenses:
- sources: LICENSE
text: |
Copyright 2010, 2011, 2012, 2013. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
notices: []

32
.licenses/npm/xmlbuilder.dep.yml generated Normal file
View File

@ -0,0 +1,32 @@
---
name: xmlbuilder
version: 11.0.1
type: npm
summary: An XML builder for node.js
homepage: http://github.com/oozcitak/xmlbuilder-js
license: mit
licenses:
- sources: LICENSE
text: |
The MIT License (MIT)
Copyright (c) 2013 Ozgur Ozcitak
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
notices: []

View File

@ -82,6 +82,63 @@ steps:
working-directory: csharp
```
## Caching NuGet Packages
The action has a built-in functionality for caching and restoring dependencies. It uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood for caching global packages data but requires less configuration settings. The `cache` input is optional, and caching is turned off by default.
The action searches for [NuGet Lock files](https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies) (`packages.lock.json`) in the repository root, calculates their hash and uses it as a part of the cache key. If lock file does not exist, this action throws error. Use `cache-dependency-path` for cases when multiple dependency files are used, or they are located in different subdirectories.
> **Warning**: Caching NuGet packages is available since .NET SDK 2.1.500 and 2.2.100 as the NuGet lock file [is available](https://learn.microsoft.com/nuget/consume-packages/package-references-in-project-files#locking-dependencies) only for NuGet 4.9 and above.
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.x
cache: true
- run: dotnet restore --locked-mode
```
> **Note**: This action will only restore `global-packages` folder, so you will probably get the [NU1403](https://learn.microsoft.com/nuget/reference/errors-and-warnings/nu1403) error when running `dotnet restore`.
> To avoid this, you can use [`DisableImplicitNuGetFallbackFolder`](https://github.com/dotnet/reproducible-builds/blob/abfe986832aa28597d3340b92469d1a702013d23/Documentation/Reproducible-MSBuild/Techniques/DisableImplicitNuGetFallbackFolder.md) option.
```xml
<PropertyGroup>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
</PropertyGroup>
```
### Reduce caching size
> **Note**: Use [`NUGET_PACKAGES`](https://learn.microsoft.com/nuget/reference/cli-reference/cli-ref-environment-variables) environment variable if available. Some action runners already has huge libraries. (ex. Xamarin)
```yaml
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.x
cache: true
- run: dotnet restore --locked-mode
```
### Caching NuGet packages in monorepos
```yaml
env:
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@v3
- uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.x
cache: true
cache-dependency-path: subdir/packages.lock.json
- run: dotnet restore --locked-mode
```
## Matrix Testing
Using `setup-dotnet` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of .NET SDK:
```yml
@ -214,6 +271,9 @@ When the `dotnet-version` input is used along with the `global-json-file` input,
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 2.2.207
```
### `cache-hit`
A boolean value to indicate an exact match was found for the cache key (follows [actions/cache](https://github.com/actions/cache#outputs))
## Environment variables
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
@ -224,25 +284,28 @@ Some environment variables may be necessary for your particular case or to impro
| DOTNET_NOLOGO |Removes logo and telemetry message from first run of dotnet cli|*false*|
| DOTNET_CLI_TELEMETRY_OPTOUT |Opt-out of telemetry being sent to Microsoft|*false*|
| DOTNET_MULTILEVEL_LOOKUP |Configures whether the global install location is used as a fall-back|*true*|
| NUGET_PACKAGES |Configures a path to the [NuGet `global-packages` folder](https://learn.microsoft.com/nuget/consume-packages/managing-the-global-packages-and-cache-folders)|*default value for each OS* |
The default value of the `DOTNET_INSTALL_DIR` environment variable depends on the operation system which is used on a runner:
| **Operation system** | **Default value** |
| ----------- | ----------- |
| **Windows** | `C:\Program Files\dotnet` |
| **Ubuntu** | `/usr/share/dotnet` |
| **macOS** | `/Users/runner/.dotnet` |
The default values of the `DOTNET_INSTALL_DIR` and `NUGET_PACKAGES` environment variables depend on the operation system which is used on a runner:
| **Operation system** | `DOTNET_INSTALL_DIR` | `NUGET_PACKAGES` |
| ----------- | ----------- | ----------- |
| **Windows** | `C:\Program Files\dotnet` | `%userprofile%\.nuget\packages` |
| **Ubuntu** | `/usr/share/dotnet` | `~/.nuget/packages` |
| **macOS** | `/Users/runner/.dotnet` | `~/.nuget/packages` |
**Example usage**:
**Example usage of environment variable**:
```yml
build:
runs-on: ubuntu-latest
env:
DOTNET_INSTALL_DIR: "path/to/directory"
NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages
steps:
- uses: actions/checkout@main
- uses: actions/setup-dotnet@v3
with:
dotnet-version: '3.1.x'
cache: true
```
## License

View File

@ -0,0 +1,101 @@
import {readdir} from 'node:fs/promises';
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import {restoreCache} from '../src/cache-restore';
import {getNuGetFolderPath} from '../src/cache-utils';
import {lockFilePatterns} from '../src/constants';
jest.mock('node:fs/promises');
jest.mock('@actions/cache');
jest.mock('@actions/core');
jest.mock('@actions/glob');
jest.mock('../src/cache-utils');
describe('cache-restore tests', () => {
describe.each(lockFilePatterns)('restoreCache("%s")', lockFilePattern => {
/** Store original process.env.GITHUB_WORKSPACE */
let githubWorkspace: string | undefined;
beforeAll(() => {
githubWorkspace = process.env.GITHUB_WORKSPACE;
jest.mocked(getNuGetFolderPath).mockResolvedValue({
'global-packages': 'global-packages',
'http-cache': 'http-cache',
temp: 'temp',
'plugins-cache': 'plugins-cache'
});
});
beforeEach(() => {
process.env.GITHUB_WORKSPACE = './';
jest.mocked(glob.hashFiles).mockClear();
jest.mocked(core.saveState).mockClear();
jest.mocked(core.setOutput).mockClear();
jest.mocked(cache.restoreCache).mockClear();
});
afterEach(() => (process.env.GITHUB_WORKSPACE = githubWorkspace));
it('throws error when lock file is not found', async () => {
jest.mocked(glob.hashFiles).mockResolvedValue('');
await expect(restoreCache(lockFilePattern)).rejects.toThrow();
expect(jest.mocked(core.saveState)).not.toHaveBeenCalled();
expect(jest.mocked(core.setOutput)).not.toHaveBeenCalled();
expect(jest.mocked(cache.restoreCache)).not.toHaveBeenCalled();
});
it('does not call core.saveState("CACHE_RESULT") when cache.restoreCache() returns falsy', async () => {
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
jest.mocked(cache.restoreCache).mockResolvedValue(undefined);
await restoreCache(lockFilePattern);
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
'CACHE_KEY',
expectedKey
);
expect(jest.mocked(core.saveState)).not.toHaveBeenCalledWith(
'CACHE_RESULT',
expectedKey
);
expect(jest.mocked(core.setOutput)).toHaveBeenCalledWith(
'cache-hit',
false
);
});
it('calls core.saveState("CACHE_RESULT") when cache.restoreCache() returns key', async () => {
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
jest.mocked(cache.restoreCache).mockResolvedValue(expectedKey);
await restoreCache(lockFilePattern);
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
'CACHE_KEY',
expectedKey
);
expect(jest.mocked(core.saveState)).toHaveBeenCalledWith(
'CACHE_RESULT',
expectedKey
);
expect(jest.mocked(core.setOutput)).toHaveBeenCalledWith(
'cache-hit',
true
);
});
it('calls glob.hashFiles("/packages.lock.json") if cacheDependencyPath is falsy', async () => {
const expectedKey = `dotnet-cache-${process.env.RUNNER_OS}-hash`;
jest.mocked(glob.hashFiles).mockResolvedValue('hash');
jest.mocked(cache.restoreCache).mockResolvedValue(expectedKey);
jest.mocked(readdir).mockResolvedValue([lockFilePattern] as any);
await restoreCache('');
expect(jest.mocked(glob.hashFiles)).not.toHaveBeenCalledWith('');
expect(jest.mocked(glob.hashFiles)).toHaveBeenCalledWith(lockFilePattern);
});
});
});

View File

@ -0,0 +1,87 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import fs from 'node:fs';
import {run} from '../src/cache-save';
import {getNuGetFolderPath} from '../src/cache-utils';
jest.mock('@actions/cache');
jest.mock('@actions/core');
jest.mock('node:fs');
jest.mock('../src/cache-utils');
describe('cache-save tests', () => {
beforeAll(() => {
jest.mocked(getNuGetFolderPath).mockResolvedValue({
'global-packages': 'global-packages',
'http-cache': 'http-cache',
temp: 'temp',
'plugins-cache': 'plugins-cache'
});
});
beforeEach(() => {
jest.mocked(core.setFailed).mockClear();
jest.mocked(core.getState).mockClear();
jest.mocked(core.setOutput).mockClear();
jest.mocked(cache.saveCache).mockClear();
jest.mocked(fs.existsSync).mockClear();
});
it('does not save cache when inputs:cache === false', async () => {
jest.mocked(core.getBooleanInput).mockReturnValue(false);
await run();
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
expect(jest.mocked(core.getState)).not.toHaveBeenCalled();
expect(jest.mocked(fs.existsSync)).not.toHaveBeenCalled();
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
});
it('does not save cache when core.getState("CACHE_KEY") returns ""', async () => {
jest.mocked(core.getBooleanInput).mockReturnValue(true);
jest.mocked(core.getState).mockReturnValue('');
await run();
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
expect(jest.mocked(fs.existsSync)).not.toHaveBeenCalled();
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
});
it('throws Error when cachePath not exists', async () => {
jest.mocked(core.getBooleanInput).mockReturnValue(true);
jest.mocked(core.getState).mockReturnValue('cache-key');
jest.mocked(fs.existsSync).mockReturnValue(false);
await run();
expect(jest.mocked(core.setFailed)).toHaveBeenCalled();
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
});
it('does not save cache when state.CACHE_KEY === state.CACHE_RESULT', async () => {
jest.mocked(core.getBooleanInput).mockReturnValue(true);
jest.mocked(core.getState).mockReturnValue('cache-key');
jest.mocked(fs.existsSync).mockReturnValue(true);
await run();
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
expect(jest.mocked(cache.saveCache)).not.toHaveBeenCalled();
});
it('saves cache when state.CACHE_KEY !== state.CACHE_RESULT', async () => {
jest.mocked(core.getBooleanInput).mockReturnValue(true);
jest.mocked(core.getState).mockImplementation(s => s);
jest.mocked(fs.existsSync).mockReturnValue(true);
await run();
expect(jest.mocked(core.setFailed)).not.toHaveBeenCalled();
expect(jest.mocked(core.getState)).toHaveBeenCalledTimes(2);
expect(jest.mocked(cache.saveCache)).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,122 @@
import * as cache from '@actions/cache';
import * as exec from '@actions/exec';
import {getNuGetFolderPath, isCacheFeatureAvailable} from '../src/cache-utils';
jest.mock('@actions/cache');
jest.mock('@actions/core');
jest.mock('@actions/exec');
describe('cache-utils tests', () => {
describe('getNuGetFolderPath()', () => {
it.each([
[
`
http-cache: /home/codespace/.local/share/NuGet/v3-cache
global-packages: /var/nuget
temp: /tmp/NuGetScratch
plugins-cache: /home/codespace/.local/share/NuGet/plugins-cache
`,
{
'http-cache': '/home/codespace/.local/share/NuGet/v3-cache',
'global-packages': '/var/nuget',
temp: '/tmp/NuGetScratch',
'plugins-cache': '/home/codespace/.local/share/NuGet/plugins-cache'
}
],
[
`
http-cache: /home/codespace/.local/share/NuGet/v3-cache
global-packages: /var/nuget
temp: /tmp/NuGetScratch
plugins-cache: /home/codespace/.local/share/NuGet/plugins-cache
`,
{
'http-cache': '/home/codespace/.local/share/NuGet/v3-cache',
'global-packages': '/var/nuget',
temp: '/tmp/NuGetScratch',
'plugins-cache': '/home/codespace/.local/share/NuGet/plugins-cache'
}
],
[
`
http-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache
global-packages: C:\\Users\\user\\.nuget\\packages\\
temp: C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch
plugins-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache
`,
{
'http-cache': 'C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache',
'global-packages': 'C:\\Users\\user\\.nuget\\packages\\',
temp: 'C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch',
'plugins-cache':
'C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache'
}
],
[
`
http-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache
global-packages: C:\\Users\\user\\.nuget\\packages\\
temp: C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch
plugins-cache: C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache
`,
{
'http-cache': 'C:\\Users\\user\\AppData\\Local\\NuGet\\v3-cache',
'global-packages': 'C:\\Users\\user\\.nuget\\packages\\',
temp: 'C:\\Users\\user\\AppData\\Local\\Temp\\NuGetScratch',
'plugins-cache':
'C:\\Users\\user\\AppData\\Local\\NuGet\\plugins-cache'
}
]
])('(stdout: "%s") returns %p', async (stdout, expected) => {
jest
.mocked(exec.getExecOutput)
.mockResolvedValue({stdout, stderr: '', exitCode: 0});
const pathes = await getNuGetFolderPath();
expect(pathes).toStrictEqual(expected);
});
it.each([
`
error: An invalid local resource name was provided. Provide one of the following values: http-cache, temp, global-packages, all.
Usage: dotnet nuget locals [arguments] [options]
Arguments:
Cache Location(s) Specifies the cache location(s) to list or clear.
<all | http-cache | global-packages | temp>
Options:
-h|--help Show help information
--force-english-output Forces the application to run using an invariant, English-based culture.
-c|--clear Clear the selected local resources or cache location(s).
-l|--list List the selected local resources or cache location(s).
`,
'bash: dotnet: command not found',
''
])('(stderr: "%s", exitCode: 1) throws Error', async stderr => {
jest
.mocked(exec.getExecOutput)
.mockResolvedValue({stdout: '', stderr, exitCode: 1});
await expect(getNuGetFolderPath()).rejects.toThrow();
});
});
describe.each(['', 'https://github.com/', 'https://example.com/'])(
'isCacheFeatureAvailable()',
url => {
// Save & Restore env
let serverUrlEnv: string | undefined;
beforeAll(() => (serverUrlEnv = process.env['GITHUB_SERVER_URL']));
beforeEach(() => (process.env['GITHUB_SERVER_URL'] = url));
afterEach(() => (process.env['GITHUB_SERVER_URL'] = serverUrlEnv));
it('returns true when cache.isFeatureAvailable() === true', () => {
jest.mocked(cache.isFeatureAvailable).mockReturnValue(true);
expect(isCacheFeatureAvailable()).toBe(true);
});
it('returns false when cache.isFeatureAvailable() === false', () => {
jest.mocked(cache.isFeatureAvailable).mockReturnValue(false);
expect(isCacheFeatureAvailable()).toBe(false);
});
}
);
});

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>$(TEST_TARGET_FRAMEWORK)</TargetFramework>
<IsPackable>false</IsPackable>
<DisableImplicitNuGetFallbackFolder>true</DisableImplicitNuGetFallbackFolder>
</PropertyGroup>
<ItemGroup>

View File

@ -1,5 +1,7 @@
import each from 'jest-each';
import semver from 'semver';
import fs from 'fs';
import fspromises from 'fs/promises';
import * as exec from '@actions/exec';
import * as core from '@actions/core';
import * as io from '@actions/io';
@ -21,14 +23,25 @@ describe('installer tests', () => {
const warningSpy = jest.spyOn(core, 'warning');
const whichSpy = jest.spyOn(io, 'which');
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
const chmodSyncSpy = jest.spyOn(fs, 'chmodSync');
const readdirSpy = jest.spyOn(fspromises, 'readdir');
describe('installDotnet() tests', () => {
beforeAll(() => {
whichSpy.mockImplementation(() => Promise.resolve('PathToShell'));
chmodSyncSpy.mockImplementation(() => {});
readdirSpy.mockImplementation(() => Promise.resolve([]));
});
afterAll(() => {
jest.resetAllMocks();
});
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 inputQuality = '' as QualityOptions;
const errorMessage = 'fictitious error message!';
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 1,
@ -36,6 +49,7 @@ describe('installer tests', () => {
stderr: errorMessage
});
});
const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
inputQuality
@ -88,8 +102,15 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();
/**
* First time script would be called to
* install runtime, here we checking only the
* second one that installs actual SDK. i.e. 1
*/
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[0][1] as string[]
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedArgument = IS_WINDOWS
? `-Version ${inputVersion}`
@ -171,8 +192,15 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();
/**
* First time script would be called to
* install runtime, here we checking only the
* second one that installs actual SDK. i.e. 1
*/
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[0][1] as string[]
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedArgument = IS_WINDOWS
? `-Quality ${inputQuality}`
@ -204,8 +232,15 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();
/**
* First time script would be called to
* install runtime, here we checking only the
* second one that installs actual SDK. i.e. 1
*/
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[0][1] as string[]
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
const expectedArgument = IS_WINDOWS
? `-Channel 6.0`
@ -238,8 +273,15 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();
/**
* First time script would be called to
* install runtime, here we checking only the
* second one that installs actual SDK. i.e. 1
*/
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[0][1] as string[]
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
expect(scriptArguments).toContain(
@ -269,8 +311,15 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();
/**
* First time script would be called to
* install runtime, here we checking only the
* second one that installs actual SDK. i.e. 1
*/
const callIndex = 1;
const scriptArguments = (
getExecOutputSpy.mock.calls[0][1] as string[]
getExecOutputSpy.mock.calls[callIndex][1] as string[]
).join(' ');
expect(scriptArguments).toContain(
@ -283,14 +332,14 @@ describe('installer tests', () => {
describe('addToPath() tests', () => {
it(`should export DOTNET_ROOT env.var with value from DOTNET_INSTALL_DIR env.var`, async () => {
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
installer.DotnetCoreInstaller.addToPath();
installer.DotnetInstallDir.addToPath();
const dotnet_root = process.env['DOTNET_ROOT'];
expect(dotnet_root).toBe(process.env['DOTNET_INSTALL_DIR']);
});
it(`should export value from DOTNET_INSTALL_DIR env.var to the PATH`, async () => {
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
installer.DotnetCoreInstaller.addToPath();
installer.DotnetInstallDir.addToPath();
const path = process.env['PATH'];
expect(path).toContain(process.env['DOTNET_INSTALL_DIR']);
});
@ -298,7 +347,7 @@ describe('installer tests', () => {
});
describe('DotnetVersionResolver tests', () => {
describe('createDotNetVersion() tests', () => {
describe('createDotnetVersion() tests', () => {
each([
'3.1',
'3.x',
@ -315,7 +364,7 @@ describe('installer tests', () => {
version
);
const versionObject =
await dotnetVersionResolver.createDotNetVersion();
await dotnetVersionResolver.createDotnetVersion();
expect(!!versionObject.value).toBe(true);
}
@ -354,7 +403,7 @@ describe('installer tests', () => {
);
await expect(
async () => await dotnetVersionResolver.createDotNetVersion()
async () => await dotnetVersionResolver.createDotnetVersion()
).rejects.toThrow();
}
);
@ -366,7 +415,7 @@ describe('installer tests', () => {
version
);
const versionObject =
await dotnetVersionResolver.createDotNetVersion();
await dotnetVersionResolver.createDotnetVersion();
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
true
@ -381,7 +430,7 @@ describe('installer tests', () => {
version
);
const versionObject =
await dotnetVersionResolver.createDotNetVersion();
await dotnetVersionResolver.createDotnetVersion();
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
true
@ -397,7 +446,7 @@ describe('installer tests', () => {
version
);
const versionObject =
await dotnetVersionResolver.createDotNetVersion();
await dotnetVersionResolver.createDotnetVersion();
expect(versionObject.type.toLowerCase().includes('version')).toBe(
true
@ -413,7 +462,7 @@ describe('installer tests', () => {
version
);
const versionObject =
await dotnetVersionResolver.createDotNetVersion();
await dotnetVersionResolver.createDotnetVersion();
const windowsRegEx = new RegExp(/^-(Version|Channel)/);
const nonWindowsRegEx = new RegExp(/^--(version|channel)/);
@ -433,7 +482,7 @@ describe('installer tests', () => {
version
);
await expect(
async () => await dotnetVersionResolver.createDotNetVersion()
async () => await dotnetVersionResolver.createDotnetVersion()
).rejects.toThrow(
`'dotnet-version' was supplied in invalid format: ${version}! The A.B.Cxx syntax is available since the .NET 5.0 release.`
);

View File

@ -4,13 +4,16 @@ import semver from 'semver';
import * as auth from '../src/authutil';
import * as setup from '../src/setup-dotnet';
import {DotnetCoreInstaller} from '../src/installer';
import {DotnetCoreInstaller, DotnetInstallDir} from '../src/installer';
import * as cacheUtils from '../src/cache-utils';
import * as cacheRestore from '../src/cache-restore';
describe('setup-dotnet tests', () => {
const inputs = {} as any;
const getInputSpy = jest.spyOn(core, 'getInput');
const getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
const getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
const setFailedSpy = jest.spyOn(core, 'setFailed');
const warningSpy = jest.spyOn(core, 'warning');
const debugSpy = jest.spyOn(core, 'debug');
@ -25,17 +28,25 @@ describe('setup-dotnet tests', () => {
DotnetCoreInstaller.prototype,
'installDotnet'
);
const addToPathSpy = jest.spyOn(DotnetCoreInstaller, 'addToPath');
const isCacheFeatureAvailableSpy = jest.spyOn(
cacheUtils,
'isCacheFeatureAvailable'
);
const restoreCacheSpy = jest.spyOn(cacheRestore, 'restoreCache');
const configAuthenticationSpy = jest.spyOn(auth, 'configAuthentication');
const addToPathOriginal = DotnetInstallDir.addToPath;
describe('run() tests', () => {
beforeEach(() => {
DotnetInstallDir.addToPath = jest.fn();
getMultilineInputSpy.mockImplementation(input => inputs[input as string]);
getInputSpy.mockImplementation(input => inputs[input as string]);
getBooleanInputSpy.mockImplementation(input => inputs[input as string]);
});
afterEach(() => {
DotnetInstallDir.addToPath = addToPathOriginal;
jest.clearAllMocks();
jest.resetAllMocks();
});
@ -96,10 +107,9 @@ describe('setup-dotnet tests', () => {
inputs['dotnet-quality'] = '';
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
addToPathSpy.mockImplementation(() => {});
await setup.run();
expect(addToPathSpy).toHaveBeenCalledTimes(1);
expect(DotnetInstallDir.addToPath).toHaveBeenCalledTimes(1);
});
it('should call auth.configAuthentication() if source-url input is provided', async () => {
@ -140,10 +150,9 @@ describe('setup-dotnet tests', () => {
installDotnetSpy.mockImplementation(() =>
Promise.resolve(`${inputs['dotnet-version']}`)
);
addToPathSpy.mockImplementation(() => {});
await setup.run();
expect(setOutputSpy).toHaveBeenCalledTimes(1);
expect(DotnetInstallDir.addToPath).toHaveBeenCalledTimes(1);
});
it(`shouldn't call setOutput() if parsing dotnet-installer logs failed`, async () => {
@ -151,7 +160,6 @@ describe('setup-dotnet tests', () => {
const warningMessage = `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`;
installDotnetSpy.mockImplementation(() => Promise.resolve(null));
addToPathSpy.mockImplementation(() => {});
await setup.run();
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
@ -162,12 +170,56 @@ describe('setup-dotnet tests', () => {
inputs['dotnet-version'] = [];
const warningMessage = `The 'dotnet-version' output will not be set.`;
addToPathSpy.mockImplementation(() => {});
await setup.run();
expect(infoSpy).toHaveBeenCalledWith(warningMessage);
expect(setOutputSpy).not.toHaveBeenCalled();
});
it(`should get 'cache-dependency-path' and call restoreCache() if input cache is set to true and cache feature is available`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-quality'] = '';
inputs['cache'] = true;
inputs['cache-dependency-path'] = 'fictitious.package.lock.json';
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
isCacheFeatureAvailableSpy.mockImplementation(() => true);
restoreCacheSpy.mockImplementation(() => Promise.resolve());
await setup.run();
expect(isCacheFeatureAvailableSpy).toHaveBeenCalledTimes(1);
expect(restoreCacheSpy).toHaveBeenCalledWith(
inputs['cache-dependency-path']
);
});
it(`shouldn't call restoreCache() if input cache isn't set to true`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-quality'] = '';
inputs['cache'] = false;
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
isCacheFeatureAvailableSpy.mockImplementation(() => true);
restoreCacheSpy.mockImplementation(() => Promise.resolve());
await setup.run();
expect(restoreCacheSpy).not.toHaveBeenCalled();
});
it(`shouldn't call restoreCache() if cache feature isn't available`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
inputs['dotnet-quality'] = '';
inputs['cache'] = true;
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
isCacheFeatureAvailableSpy.mockImplementation(() => false);
restoreCacheSpy.mockImplementation(() => Promise.resolve());
await setup.run();
expect(restoreCacheSpy).not.toHaveBeenCalled();
});
});
});

View File

@ -17,9 +17,20 @@ inputs:
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
config-file:
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
cache:
description: 'Optional input to enable caching of the NuGet global-packages folder'
required: false
default: false
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
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: 'node16'
main: 'dist/index.js'
main: 'dist/setup/index.js'
post: 'dist/cache-save/index.js'
post-if: success()

58989
dist/cache-save/index.js vendored Normal file

File diff suppressed because one or more lines are too long

21305
dist/index.js vendored

File diff suppressed because one or more lines are too long

73550
dist/setup/index.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -98,6 +98,10 @@
.PARAMETER DownloadTimeout
Determines timeout duration in seconds for dowloading of the SDK file
Default: 1200 seconds (20 minutes)
.PARAMETER KeepZip
If set, downloaded file is kept
.PARAMETER ZipPath
Use that path to store installer, generated by default
#>
[cmdletbinding()]
param(
@ -121,7 +125,9 @@ param(
[string[]]$ProxyBypassList=@(),
[switch]$SkipNonVersionedFiles,
[switch]$NoCdn,
[int]$DownloadTimeout=1200
[int]$DownloadTimeout=1200,
[switch]$KeepZip,
[string]$ZipPath=[System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
)
Set-StrictMode -Version Latest
@ -176,6 +182,23 @@ function Measure-Action($name, $block) {
Say-Verbose "⏱ Action '$name' took $totalSeconds seconds"
}
function Get-Remote-File-Size($zipUri) {
try {
$response = Invoke-WebRequest -Uri $zipUri -Method Head
$fileSize = $response.Headers["Content-Length"]
if ((![string]::IsNullOrEmpty($fileSize))) {
Say "Remote file $zipUri size is $fileSize bytes."
return $fileSize
}
}
catch {
Say-Verbose "Content-Length header was not extracted for $zipUri."
}
return $null
}
function Say-Invocation($Invocation) {
$command = $Invocation.MyCommand;
$args = (($Invocation.BoundParameters.Keys | foreach { "-$_ `"$($Invocation.BoundParameters[$_])`"" }) -join " ")
@ -869,6 +892,8 @@ function DownloadFile($Source, [string]$OutPath) {
$File = [System.IO.File]::Create($OutPath)
$Stream.CopyTo($File)
$File.Close()
ValidateRemoteLocalFileSizes -LocalFileOutPath $OutPath -SourceUri $Source
}
finally {
if ($null -ne $Stream) {
@ -877,19 +902,40 @@ function DownloadFile($Source, [string]$OutPath) {
}
}
function ValidateRemoteLocalFileSizes([string]$LocalFileOutPath, $SourceUri) {
try {
$remoteFileSize = Get-Remote-File-Size -zipUri $SourceUri
$fileSize = [long](Get-Item $LocalFileOutPath).Length
Say "Downloaded file $SourceUri size is $fileSize bytes."
if ((![string]::IsNullOrEmpty($remoteFileSize)) -and !([string]::IsNullOrEmpty($fileSize)) ) {
if ($remoteFileSize -ne $fileSize) {
Say "The remote and local file sizes are not equal. Remote file size is $remoteFileSize bytes and local size is $fileSize bytes. The local package may be corrupted."
}
else {
Say "The remote and local file sizes are equal."
}
}
else {
Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
}
}
catch {
Say "Either downloaded or local package size can not be measured. One of them may be corrupted."
}
}
function SafeRemoveFile($Path) {
try {
if (Test-Path $Path) {
Remove-Item $Path
Say-Verbose "The temporary file `"$Path`" was removed."
}
else
{
else {
Say-Verbose "The temporary file `"$Path`" does not exist, therefore is not removed."
}
}
catch
{
catch {
Say-Warning "Failed to remove the temporary file: `"$Path`", remove it manually."
}
}
@ -1100,6 +1146,13 @@ function Resolve-AssetName-And-RelativePath([string] $Runtime) {
}
function Prepare-Install-Directory {
$diskSpaceWarning = "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space.";
if ($PSVersionTable.PSVersion.Major -lt 7) {
Say-Verbose $diskSpaceWarning
return
}
New-Item -ItemType Directory -Force -Path $InstallRoot | Out-Null
$installDrive = $((Get-Item $InstallRoot -Force).PSDrive.Name);
@ -1108,9 +1161,10 @@ function Prepare-Install-Directory {
$diskInfo = Get-PSDrive -Name $installDrive
}
catch {
Say-Warning "Failed to check the disk space. Installation will continue, but it may fail if you do not have enough disk space."
Say-Warning $diskSpaceWarning
}
# The check is relevant for PS version >= 7, the result can be irrelevant for older versions. See https://github.com/PowerShell/PowerShell/issues/12442.
if ( ($null -ne $diskInfo) -and ($diskInfo.Free / 1MB -le 100)) {
throw "There is not enough disk space on drive ${installDrive}:"
}
@ -1216,7 +1270,6 @@ if ($DryRun) {
Measure-Action "Installation directory preparation" { Prepare-Install-Directory }
$ZipPath = [System.IO.Path]::combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())
Say-Verbose "Zip path: $ZipPath"
$DownloadSucceeded = $false
@ -1289,7 +1342,9 @@ if (!$isAssetInstalled) {
throw "`"$assetName`" with version = $($DownloadedLink.effectiveVersion) failed to install with an unknown error."
}
if (-not $KeepZip) {
SafeRemoveFile -Path $ZipPath
}
Measure-Action "Setting up shell environment" { Prepend-Sdk-InstallRoot-To-Path -InstallRoot $InstallRoot }
@ -1300,40 +1355,40 @@ Say "Installation finished"
# SIG # Begin signature block
# MIInvwYJKoZIhvcNAQcCoIInsDCCJ6wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBhfTi3SRn7+vyy
# uCXKPjhiawegWZ493EcaOEycbgkZcKCCDXYwggX0MIID3KADAgECAhMzAAACy7d1
# OfsCcUI2AAAAAALLMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCACRu+yvG+6rftW
# 7639o2K9YFU32HKgY4Dqe9C3db/p7qCCDXYwggX0MIID3KADAgECAhMzAAADTrU8
# esGEb+srAAAAAANOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NTU5WhcNMjMwNTExMjA0NTU5WjB0MQsw
# bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI5WhcNMjQwMzE0MTg0MzI5WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQC3sN0WcdGpGXPZIb5iNfFB0xZ8rnJvYnxD6Uf2BHXglpbTEfoe+mO//oLWkRxA
# wppditsSVOD0oglKbtnh9Wp2DARLcxbGaW4YanOWSB1LyLRpHnnQ5POlh2U5trg4
# 3gQjvlNZlQB3lL+zrPtbNvMA7E0Wkmo+Z6YFnsf7aek+KGzaGboAeFO4uKZjQXY5
# RmMzE70Bwaz7hvA05jDURdRKH0i/1yK96TDuP7JyRFLOvA3UXNWz00R9w7ppMDcN
# lXtrmbPigv3xE9FfpfmJRtiOZQKd73K72Wujmj6/Su3+DBTpOq7NgdntW2lJfX3X
# a6oe4F9Pk9xRhkwHsk7Ju9E/AgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUrg/nt/gj+BBLd1jZWYhok7v5/w4w
# AQDdCKiNI6IBFWuvJUmf6WdOJqZmIwYs5G7AJD5UbcL6tsC+EBPDbr36pFGo1bsU
# p53nRyFYnncoMg8FK0d8jLlw0lgexDDr7gicf2zOBFWqfv/nSLwzJFNP5W03DF/1
# 1oZ12rSFqGlm+O46cRjTDFBpMRCZZGddZlRBjivby0eI1VgTD1TvAdfBYQe82fhm
# WQkYR/lWmAK+vW/1+bO7jHaxXTNCxLIBW07F8PBjUcwFxxyfbe2mHB4h1L4U0Ofa
# +HX/aREQ7SqYZz59sXM2ySOfvYyIjnqSO80NGBaz5DvzIG88J0+BNhOu2jl6Dfcq
# jYQs1H/PMSQIK6E7lXDXSpXzAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUnMc7Zn/ukKBsBiWkwdNfsN5pdwAw
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzQ3MDUyODAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# MBQGA1UEBRMNMjMwMDEyKzUwMDUxNjAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAJL5t6pVjIRlQ8j4dAFJ
# ZnMke3rRHeQDOPFxswM47HRvgQa2E1jea2aYiMk1WmdqWnYw1bal4IzRlSVf4czf
# zx2vjOIOiaGllW2ByHkfKApngOzJmAQ8F15xSHPRvNMmvpC3PFLvKMf3y5SyPJxh
# 922TTq0q5epJv1SgZDWlUlHL/Ex1nX8kzBRhHvc6D6F5la+oAO4A3o/ZC05OOgm4
# EJxZP9MqUi5iid2dw4Jg/HvtDpCcLj1GLIhCDaebKegajCJlMhhxnDXrGFLJfX8j
# 7k7LUvrZDsQniJZ3D66K+3SZTLhvwK7dMGVFuUUJUfDifrlCTjKG9mxsPDllfyck
# 4zGnRZv8Jw9RgE1zAghnU14L0vVUNOzi/4bE7wIsiRyIcCcVoXRneBA3n/frLXvd
# jDsbb2lpGu78+s1zbO5N0bhHWq4j5WMutrspBxEhqG2PSBjC5Ypi+jhtfu3+x76N
# mBvsyKuxx9+Hm/ALnlzKxr4KyMR3/z4IRMzA1QyppNk65Ui+jB14g+w4vole33M1
# pVqVckrmSebUkmjnCshCiH12IFgHZF7gRwE4YZrJ7QjxZeoZqHaKsQLRMp653beB
# fHfeva9zJPhBSdVcCW7x9q0c2HVPLJHX9YCUU714I+qtLpDGrdbZxD9mikPqL/To
# /1lDZ0ch8FtePhME7houuoPcMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAD21v9pHoLdBSNlFAjmk
# mx4XxOZAPsVxxXbDyQv1+kGDe9XpgBnT1lXnx7JDpFMKBwAyIwdInmvhK9pGBa31
# TyeL3p7R2s0L8SABPPRJHAEk4NHpBXxHjm4TKjezAbSqqbgsy10Y7KApy+9UrKa2
# kGmsuASsk95PVm5vem7OmTs42vm0BJUU+JPQLg8Y/sdj3TtSfLYYZAaJwTAIgi7d
# hzn5hatLo7Dhz+4T+MrFd+6LUa2U3zr97QwzDthx+RP9/RZnur4inzSQsG5DCVIM
# pA1l2NWEA3KAca0tI2l6hQNYsaKL1kefdfHCrPxEry8onJjyGGv9YKoLv6AOO7Oh
# JEmbQlz/xksYG2N/JSOJ+QqYpGTEuYFYVWain7He6jgb41JbpOGKDdE/b+V2q/gX
# UgFe2gdwTpCDsvh8SMRoq1/BNXcr7iTAU38Vgr83iVtPYmFhZOVM0ULp/kKTVoir
# IpP2KCxT4OekOctt8grYnhJ16QMjmMv5o53hjNFXOxigkQWYzUO+6w50g0FAeFa8
# 5ugCCB6lXEk21FFB1FdIHpjSQf+LP/W2OV/HfhC3uTPgKbRtXo83TZYEudooyZ/A
# Vu08sibZ3MkGOJORLERNwKm2G7oqdOv4Qj8Z0JrGgMzj46NFKAxkLSpE5oHQYP1H
# tPx1lPfD7iNSbJsP6LiUHXH1MIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
@ -1376,64 +1431,64 @@ Say "Installation finished"
# /Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAALLt3U5+wJxQjYAAAAAAsswDQYJYIZIAWUDBAIB
# Z25pbmcgUENBIDIwMTECEzMAAANOtTx6wYRv6ysAAAAAA04wDQYJYIZIAWUDBAIB
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFmuaTXYQ37AFvsEol24fdW+
# nRqHcc1fr+VQVdqhXc/vMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPHo6D4ixtuX2mtmXYtzP7Xh
# 5SbbHtBt9hwIKfR9nNCHMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
# BQAEggEAjY5XW5Ly7TJ1OTbeIR98xU+2dmtw7L71ws+ICnQCGhj2xJDUK+5yrTfO
# 8C98l/P4ynFi33Dl8z2YElqUCuqEXbiCzz06lIL4NuibC5DV/X80ZmICR/NYd2v1
# ww7IH+7dpsHAowBBindCYpVwQ3Ea3kDWgsjPAinAysFFushSOnNWFvrF6vi2smrs
# smbrAAhEhSfLd1Pxxdw73hQ0YjM/D3F3opaybMQ0blpHhOaqtbiyYzvk0doIzBEc
# trSH4NDIc3yLNj5VbjSczpexE+hyQNY4xCtwco4bVtXhONUihv08AIKR8+sIaI7A
# mM/SWrrwGYSSSxydKqDei7biKG4jDqGCFykwghclBgorBgEEAYI3AwMBMYIXFTCC
# BQAEggEAKaYy0/f2nIWjmd2w2g7hU/pz6ahK3cIahIejHpTW8JXUR3neUB9oFm8x
# GiAtgKY6zzxKsMGRJfULOEB+jV8y1TK5aAUtNWog8o7i9hl/W3JLsRtcduGhqvR8
# oYFq4xkYPDwAjklDN96cWNqWmqsUULs/jxx4Ef0o9/2Cy9FWYwvyDK/o0bdfotsl
# +cr3Aj1fIOSkrMKjEoScITOvfGCDgNqVsu+62itzX0QvIq7yW8aqJ5xd2r94IOry
# u6iMdQFYSxR7xpIaDjKLHCH8tTmKAlrFFekhaxe1WuTvNBt154Zl1U7ukSO12s1N
# ezHYEW4AoLd4MO9zmXwDZmo3RLzFHKGCFykwghclBgorBgEEAYI3AwMBMYIXFTCC
# FxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsq
# hkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
# AwQCAQUABCB6Hzt2gUb/WZK8fvVnOocriE4rYr6mscZi3gZnBCpiigIGZBr2iMZU
# GBMyMDIzMDMzMTE1MjEwNi41MTZaMASAAgH0oIHYpIHVMIHSMQswCQYDVQQGEwJV
# AwQCAQUABCCiX6fcUDSacytCBP6o92QnwRIQCE6w6Se15jgm1UebNAIGZN/N9Z2v
# GBMyMDIzMDkxODEwMDUxOS4zMjJaMASAAgH0oIHYpIHVMIHSMQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl
# bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNO
# OjA4NDItNEJFNi1DMjlBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
# ZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAGybkADf26plJIAAQAAAbIwDQYJ
# OkQwODItNEJGRC1FRUJBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBT
# ZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAG6Hz8Z98F1vXwAAQAAAbowDQYJ
# KoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjIw
# OTIwMjAyMjAxWhcNMjMxMjE0MjAyMjAxWjCB0jELMAkGA1UEBhMCVVMxEzARBgNV
# OTIwMjAyMjE5WhcNMjMxMjE0MjAyMjE5WjCB0jELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl
# cmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowODQyLTRC
# RTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMqiZTIde/lQ4rC+Bml5f/Wu
# q/xKTxrfbG23HofmQ+qZAN4GyO73PF3y9OAfpt7Qf2jcldWOGUB+HzBuwllYyP3f
# x4MY8zvuAuB37FvoytnNC2DKnVrVlHOVcGUL9CnmhDNMA2/nskjIf2IoiG9J0qLY
# r8duvHdQJ9Li2Pq9guySb9mvUL60ogslCO9gkh6FiEDwMrwUr8Wja6jFpUTny8tg
# 0N0cnCN2w4fKkp5qZcbUYFYicLSb/6A7pHCtX6xnjqwhmJoib3vkKJyVxbuFLRhV
# XxH95b0LHeNhifn3jvo2j+/4QV10jEpXVW+iC9BsTtR69xvTjU51ZgP7BR4YDEWq
# 7JsylSOv5B5THTDXRf184URzFhTyb8OZQKY7mqMh7c8J8w1sEM4XDUF2UZNy829N
# VCzG2tfdEXZaHxF8RmxpQYBxyhZwY1rotuIS+gfN2eq+hkAT3ipGn8/KmDwDtzAb
# nfuXjApgeZqwgcYJ8pDJ+y/xU6ouzJz1Bve5TTihkiA7wQsQe6R60Zk9dPdNzw0M
# K5niRzuQZAt4GI96FhjhlUWcUZOCkv/JXM/OGu/rgSplYwdmPLzzfDtXyuy/GCU5
# I4l08g6iifXypMgoYkkceOAAz4vx1x0BOnZWfI3fSwqNUvoN7ncTT+MB4Vpvf1QB
# ppjBAQUuvui6eCG0MCVNAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUmfIngFzZEZlP
# kjDOVluBSDDaanEwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYD
# cmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpEMDgyLTRC
# RkQtRUVCQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIhOFYMzkjWAE9UVnXF9hRGv
# 0xBRxc+I5Hu3hxVFXyK3u38xusEb0pLkwjgGtDsaLLbrlMxqX3tFb/3BgEPEC3L0
# wX76gD8zHt+wiBV5mq5BWop29qRrgMJKKCPcpQnSjs9B/4XMFFvrpdPicZDv43FL
# gz9fHqMq0LJDw5JAHGDS30TCY9OF43P4d44Z9lE7CaVS2pJMF3L453MXB5yYK/KD
# bilhERP1jxn2yl+tGCRguIAsMG0oeOhXaw8uSGOhS6ACSHb+ebi0038MFHyoTNhK
# f+SYo4OpSY3xP4+swBBTKDoYP1wH+CfxG6h9fymBJQPQZaqfl0riiDLjmDunQtH1
# GD64Air5k9Jdwhq5wLmSWXjyFVL+IDfOpdixJ6f5o+MhE6H4t31w+prygHmd2UHQ
# 657UGx6FNuzwC+SpAHmV76MZYac4uAhTgaP47P2eeS1ockvyhl9ya+9JzPfMkug3
# xevzFADWiLRMr066EMV7q3JSRAsnCS9GQ08C4FKPbSh8OPM33Lng0ffxANnHAAX/
# DE7cHcx7l9jaV3Acmkj7oqir4Eh2u5YxwiaTE37XaMumX2ES3PJ5NBaXq7YdLJwy
# SD+U9pk/tl4dQ1t/Eeo7uDTliOyQkD8I74xpVB0T31/67KHfkBkFVvy6wye21V+9
# IC8uSD++RgD3RwtN2kE/AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUimLm8QMeJa25
# j9MWeabI2HSvZOUwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYD
# VR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
# cmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwG
# CCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIw
# MjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
# CDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBANxHtu3FzIabaDbW
# qswdKBlAhKXRCN+5CSMiv2TYa4i2QuWIm+99piwAhDhADfbqor1zyLi95Y6GQnvI
# WUgdeC7oL1ZtZye92zYK+EIfwYZmhS+CH4infAzUvscHZF3wlrJUfPUIDGVP0lCY
# Vse9mguvG0dqkY4ayQPEHOvJubgZZaOdg/N8dInd6fGeOc+0DoGzB+LieObJ2Q0A
# tEt3XN3iX8Cp6+dZTX8xwE/LvhRwPpb/+nKshO7TVuvenwdTwqB/LT6CNPaElwFe
# KxKrqRTPMbHeg+i+KnBLfwmhEXsMg2s1QX7JIxfvT96md0eiMjiMEO22LbOzmLMN
# d3LINowAnRBAJtX+3/e390B9sMGMHp+a1V+hgs62AopBl0p/00li30DN5wEQ5If3
# 5Zk7b/T6pEx6rJUDYCti7zCbikjKTanBnOc99zGMlej5X+fC/k5ExUCrOs3/VzGR
# CZt5LvVQSdWqq/QMzTEmim4sbzASK9imEkjNtZZyvC1CsUcD1voFktld4mKMjE+u
# DEV3IddD+DrRk94nVzNPSuZXewfVOnXHSeqG7xM3V7fl2aL4v1OhL2+JwO1Tx3B0
# irO1O9qbNdJk355bntd1RSVKgM22KFBHnoL7Js7pRhBiaKmVTQGoOb+j1Qa7q+ci
# xGo48Vh9k35BDsJS/DLoXFSPDl4mMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJ
# CDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBAF/I8U6hbZhvDcn9
# 6nZ6tkbSEjXPvKZ6wroaXcgstEhpgaeEwleLuPXHLzEWtuJuYz4eshmhXqFr49lb
# AcX5SN5/cEsP0xdFayb7U5P94JZd3HjFvpWRNoNBhF3SDM0A38sI2H+hjhB/VfX1
# XcZiei1ROPAyCHcBgHLyQrEu6mnb3HhbIdr8h0Ta7WFylGhLSFW6wmzKusP6aOlm
# nGSac5NMfla6lRvTYHd28rbbCgfSm1RhTgoZj+W8DTKtiEMwubHJ3mIPKmo8xtJI
# WXPnXq6XKgldrL5cynLMX/0WX65OuWbHV5GTELdfWvGV3DaZrHPUQ/UP31Keqb2x
# jVCb30LVwgbjIvYS77N1dARkN8F/9pJ1gO4IvZWMwyMlKKFGojO1f1wbjSWcA/57
# tsc+t2blrMWgSNHgzDr01jbPSupRjy3Ht9ZZs4xN02eiX3eG297NrtC6l4c/gzn2
# 0eqoqWx/uHWxmTgB0F5osBuTHOe77DyEA0uhArGlgKP91jghgt/OVHoH65g0QqCt
# gZ+36mnCEg6IOhFoFrCc0fJFGVmb1+17gEe+HRMM7jBk4O06J+IooFrI3e3PJjPr
# Qano/MyE3h+zAuBWGMDRcUlNKCDU7dGnWvH3XWwLrCCIcz+3GwRUMsLsDdPW2OVv
# 7v1eEJiMSIZ2P+M7L20Q8aznU4OAMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJ
# mQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNh
@ -1476,39 +1531,39 @@ Say "Installation finished"
# tB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB0jELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxh
# bmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjow
# ODQyLTRCRTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
# dmljZaIjCgEBMAcGBSsOAwIaAxUAjhJ+EeySRfn2KCNsjn9cF9AUSTqggYMwgYCk
# bmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpE
# MDgyLTRCRkQtRUVCQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy
# dmljZaIjCgEBMAcGBSsOAwIaAxUAdqNHe113gCJ87aZIGa5QBUqIwvKggYMwgYCk
# fjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIF
# AOfRUdUwIhgPMjAyMzAzMzEyMDM0MjlaGA8yMDIzMDQwMTIwMzQyOVowdDA6Bgor
# BgEEAYRZCgQBMSwwKjAKAgUA59FR1QIBADAHAgEAAgIKJDAHAgEAAgIRLzAKAgUA
# 59KjVQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID
# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAJlOESCa/uRR1x6GunE8
# K/WgHWTpSE31EITDOfTMvDcF4ptngCS5aOc4gfzmhNNehWfP6EOrgoSQzJYZ4YCh
# fYbHNMk56f18sq8t7y2hgR7KixcEo/4HVzeSdaOclHNc4Gn7kCGpMvpT3Xz9Lzc7
# UKWDZ0zkNKnbS8TZLNueVQwfMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMx
# AOiyf1swIhgPMjAyMzA5MTgxNTQ4NDNaGA8yMDIzMDkxOTE1NDg0M1owdDA6Bgor
# BgEEAYRZCgQBMSwwKjAKAgUA6LJ/WwIBADAHAgEAAgIJSjAHAgEAAgISJDAKAgUA
# 6LPQ2wIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAID
# B6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAGK+6UVMbVgt4qWdPk/1
# tYxGjavQWgZ3LPfp9l3mh/tQK2RhpjsBgKJO+VVBXcUW3YQb5qP9g40+jrcIFlfy
# vrAK3UpbfuIZ6DJ6AayEF30fseVPvwaqjl/BJlKUL3ofsjEMcZPdpfHQv4Zdj3rr
# cWGEIG68RqDIePRRKRZEJtI0MYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgUENBIDIwMTACEzMAAAGybkADf26plJIAAQAAAbIwDQYJYIZIAWUDBAIB
# U3RhbXAgUENBIDIwMTACEzMAAAG6Hz8Z98F1vXwAAQAAAbowDQYJYIZIAWUDBAIB
# BQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx
# IgQgXhJRuHCXk3arJvifIY3DBe9Ce9EmlP1y6U4XkgL31DkwgfoGCyqGSIb3DQEJ
# EAIvMYHqMIHnMIHkMIG9BCBTeM485+E+t4PEVieUoFKX7PVyLo/nzu+htJPCG04+
# NTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# IgQgYadrVhYugkNn/ywjh6tJ37ntH5tUO1WvoJ2sa5Mz6LIwgfoGCyqGSIb3DQEJ
# EAIvMYHqMIHnMIHkMIG9BCApVb08M25w+tYGWsmlGtp1gy1nPcqWfqgMF3nlWYVz
# BTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABsm5A
# A39uqZSSAAEAAAGyMCIEIGGWlnNnYHrB5HguWG0/nJd/WvSrCogze+QCpenu3IM5
# MA0GCSqGSIb3DQEBCwUABIICADVOLTuNxeEnBOfZpb7Nv4uf91W/Ho5i99zenDSJ
# x5QHVs+bKXmgc3a7/SSsliAT3zygHc7cH4zARbCZePLTivByKmeG08Ka35eyR+FK
# awSNrI/X+eVIC6nw/egCwviBC1NAG8jHGkuScbHeiiGajvS6lp3ORML7UexMuE4w
# 9SEumoghljCLZMwCSvw+3WxhQoBEZroR8u+PID2RdD0vi85FjKPWcZZijVLqHeFi
# TnuFqwRCLTV0MV+dDCbjwXneIqV+AVlnqb9iDMr3ZhISlRcy9XJNpY5vQBj/wqUW
# vefrmpdz0LNkdtXYThPkyl3mha2KsoQi5SA9zSjlAjFgY3ppmXvi3Frbfqk+iL+f
# l/Qc4+B71jG4t28lTWKteJiHqo+6AUXK2rlAl0d74yvhO6N8lMMtXhdJc8JABYn1
# v2/KKZn5RvPFF8QP7Ac1saIe1+gUFNcsYOLaMm/xl8E6kefWwZnm5Rhm606g1AC/
# N5Wo08aAs0ymTPH91dEbmOURXLbA3vCyG7kbfgnhCs/j7oQHWaFDzEYuXDIA4ICT
# dxPUTltbq3OWdp0PAS8JSEKPQFaOoQEnPa4adrXWxMvOmel8IGqJiQ+BPOaLQG64
# Qu2tMkH/5szb1fsEnCe8SJmy5ESF+kmpnLBtJ17Y9o+9nJHF5ddFmvzy+LUaIqDN
# cOfH
# JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAABuh8/
# GffBdb18AAEAAAG6MCIEIMHkOGC427PqmUI7Oe7xVuezks+e+hMM+17Nfgn9Gbmw
# MA0GCSqGSIb3DQEBCwUABIICAEKE7ZkmQ1xDsee8ZSZP8Kkt2YJLG3nLR32JBRu3
# uX7TPTDw9phd40N2ryva3Xjzht/JOPa0F4mg++YIwylXVIR6EqKNVLsIA/X8AGFa
# ti+AJp6qNe9grV8DBK00whojtMK8JZhufOb7LEon5rBFEnJx3g8JhCvAqXFzxw+M
# ctqJFm6+1ynuI7mKayA89TOLBmI4RviICjMZlsW3kNXRS1GryKt7H+C8y9kiLEMX
# efauGyoMO8sToIxgrq2HZF88/b+y8c3cX+Q5iazWLzMYeWUUPrqWcIbjGjIFBMl9
# weOXEAZVo6TSGDZOQkYi/FZxKWllnxVRN1S2Al5IUUvgXGl9ZpsW2DyM1S8Qxe+a
# VrxwkOWKzHlnFo1qGz0Iq9ImHVqr2dOC5bDVMu+jlOA1LiZC5aHxuxaHWBN73Wp7
# Hjy8h73drsmmiXovOWly7lWLatIuPJh00iiyBXdDtjmeDjso3aadUII5FQ1QWZ4F
# 4VWo161Gx+TxGlUt//4Hns5bn4UEGE43g9OCQuQ/WFMqdb3dHCzkkHDhWHbdpBy7
# oHHEsAdgjMdQHWfnxhCj0ZHEOupc9j1CXpQtN/B6uzsQQ/Mp34Rhsgn+/REVAwpS
# O7G69KWZrePZJiNrV/+eRn8ya6s8WNQAGB5zIQc8o+K9RGctLBOWcsRya9sqvL6r
# xUQ2
# SIG # End signature block

View File

@ -310,6 +310,14 @@ get_machine_architecture() {
echo "s390x"
return 0
;;
ppc64le)
echo "ppc64le"
return 0
;;
loongarch64)
echo "loongarch64"
return 0
;;
esac
fi
@ -347,6 +355,14 @@ get_normalized_architecture_from_architecture() {
echo "s390x"
return 0
;;
ppc64le)
echo "ppc64le"
return 0
;;
loongarch64)
echo "loongarch64"
return 0
;;
esac
say_err "Architecture \`$architecture\` not supported. If you think this is a bug, report it at https://github.com/dotnet/install-scripts/issues"
@ -538,6 +554,40 @@ is_dotnet_package_installed() {
fi
}
# args:
# downloaded file - $1
# remote_file_size - $2
validate_remote_local_file_sizes()
{
eval $invocation
local downloaded_file="$1"
local remote_file_size="$2"
local file_size=''
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
file_size="$(stat -c '%s' "$downloaded_file")"
elif [[ "$OSTYPE" == "darwin"* ]]; then
# hardcode in order to avoid conflicts with GNU stat
file_size="$(/usr/bin/stat -f '%z' "$downloaded_file")"
fi
if [ -n "$file_size" ]; then
say "Downloaded file size is $file_size bytes."
if [ -n "$remote_file_size" ] && [ -n "$file_size" ]; then
if [ "$remote_file_size" -ne "$file_size" ]; then
say "The remote and local file sizes are not equal. The remote file size is $remote_file_size bytes and the local size is $file_size bytes. The local package may be corrupted."
else
say "The remote and local file sizes are equal."
fi
fi
else
say "Either downloaded or local package size can not be measured. One of them may be corrupted."
fi
}
# args:
# azure_feed - $1
# channel - $2
@ -906,14 +956,39 @@ copy_files_or_dirs_from_list() {
done
}
# args:
# zip_uri - $1
get_remote_file_size() {
local zip_uri="$1"
if machine_has "curl"; then
file_size=$(curl -sI "$zip_uri" | grep -i content-length | awk '{ num = $2 + 0; print num }')
elif machine_has "wget"; then
file_size=$(wget --spider --server-response -O /dev/null "$zip_uri" 2>&1 | grep -i 'Content-Length:' | awk '{ num = $2 + 0; print num }')
else
say "Neither curl nor wget is available on this system."
return
fi
if [ -n "$file_size" ]; then
say "Remote file $zip_uri size is $file_size bytes."
echo "$file_size"
else
say_verbose "Content-Length header was not extracted for $zip_uri."
echo ""
fi
}
# args:
# zip_path - $1
# out_path - $2
# remote_file_size - $3
extract_dotnet_package() {
eval $invocation
local zip_path="$1"
local out_path="$2"
local remote_file_size="$3"
local temp_out_path="$(mktemp -d "$temporary_file_template")"
@ -924,8 +999,12 @@ extract_dotnet_package() {
find "$temp_out_path" -type f | grep -Eo "$folders_with_version_regex" | sort | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" false
find "$temp_out_path" -type f | grep -Ev "$folders_with_version_regex" | copy_files_or_dirs_from_list "$temp_out_path" "$out_path" "$override_non_versioned_files"
validate_remote_local_file_sizes "$zip_path" "$remote_file_size"
rm -rf "$temp_out_path"
if [ -z ${keep_zip+x} ]; then
rm -f "$zip_path" && say_verbose "Temporary zip file $zip_path was removed"
fi
if [ "$failed" = true ]; then
say_err "Extraction failed"
@ -1419,9 +1498,10 @@ install_dotnet() {
eval $invocation
local download_failed=false
local download_completed=false
local remote_file_size=0
mkdir -p "$install_root"
zip_path="$(mktemp "$temporary_file_template")"
zip_path="${zip_path:-$(mktemp "$temporary_file_template")}"
say_verbose "Zip path: $zip_path"
for link_index in "${!download_links[@]}"
@ -1459,8 +1539,10 @@ install_dotnet() {
return 1
fi
remote_file_size="$(get_remote_file_size "$download_link")"
say "Extracting zip from $download_link"
extract_dotnet_package "$zip_path" "$install_root" || return 1
extract_dotnet_package "$zip_path" "$install_root" "$remote_file_size" || return 1
# Check if the SDK version is installed; if not, fail the installation.
# if the version contains "RTM" or "servicing"; check if a 'release-type' SDK version is installed.
@ -1610,6 +1692,14 @@ do
override_non_versioned_files=false
non_dynamic_parameters+=" $name"
;;
--keep-zip|-[Kk]eep[Zz]ip)
keep_zip=true
non_dynamic_parameters+=" $name"
;;
--zip-path|-[Zz]ip[Pp]ath)
shift
zip_path="$1"
;;
-?|--?|-h|--help|-[Hh]elp)
script_name="$(basename "$0")"
echo ".NET Tools Installer"
@ -1655,7 +1745,7 @@ do
echo " -InstallDir"
echo " --architecture <ARCHITECTURE> Architecture of dotnet binaries to be installed, Defaults to \`$architecture\`."
echo " --arch,-Architecture,-Arch"
echo " Possible values: x64, arm, arm64 and s390x"
echo " Possible values: x64, arm, arm64, s390x, ppc64le and loongarch64"
echo " --os <system> Specifies operating system to be used when selecting the installer."
echo " Overrides the OS determination approach used by the script. Supported values: osx, linux, linux-musl, freebsd, rhel.6."
echo " In case any other value is provided, the platform will be determined by the script based on machine configuration."
@ -1680,6 +1770,8 @@ do
echo " --no-cdn,-NoCdn Disable downloading from the Azure CDN, and use the uncached feed directly."
echo " --jsonfile <JSONFILE> Determines the SDK version from a user specified global.json file."
echo " Note: global.json must have a value for 'SDK:Version'"
echo " --keep-zip,-KeepZip If set, downloaded file is kept."
echo " --zip-path, -ZipPath If set, downloaded file is stored at the specified path."
echo " -?,--?,-h,--help,-Help Shows this help message"
echo ""
echo "Install Location:"

3464
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,9 +3,9 @@
"version": "3.0.2",
"private": true,
"description": "setup dotnet action",
"main": "lib/setup-dotnet.js",
"main": "dist/setup/index.js",
"scripts": {
"build": "tsc && ncc build",
"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}\"",
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"",
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"",
@ -26,27 +26,32 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.0.0",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4",
"@actions/exec": "^1.1.1",
"@actions/github": "^1.1.0",
"@actions/glob": "^0.3.0",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.2",
"fast-xml-parser": "^4.0.10",
"semver": "^6.3.0"
"fast-xml-parser": "^4.3.4",
"json5": "^2.2.3",
"semver": "^6.3.1"
},
"devDependencies": {
"@types/jest": "^27.0.2",
"@types/jest": "^27.5.2",
"@types/node": "^16.11.25",
"@types/semver": "^6.2.2",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@vercel/ncc": "^0.33.4",
"@vercel/ncc": "^0.34.0",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-node": "^11.1.0",
"husky": "^8.0.1",
"jest": "^27.2.5",
"jest-circus": "^27.2.5",
"jest": "^27.5.1",
"jest-circus": "^27.5.1",
"jest-each": "^27.5.1",
"prettier": "^2.8.4",
"ts-jest": "^27.0.5",
"typescript": "^4.8.4",

50
src/cache-restore.ts Normal file
View File

@ -0,0 +1,50 @@
import {readdir} from 'node:fs/promises';
import {join} from 'node:path';
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as glob from '@actions/glob';
import {getNuGetFolderPath} from './cache-utils';
import {lockFilePatterns, State, Outputs} from './constants';
export const restoreCache = async (cacheDependencyPath?: string) => {
const lockFilePath = cacheDependencyPath || (await findLockFile());
const fileHash = await glob.hashFiles(lockFilePath);
if (!fileHash) {
throw new Error(
'Some specified paths were not resolved, unable to cache dependencies.'
);
}
const platform = process.env.RUNNER_OS;
const primaryKey = `dotnet-cache-${platform}-${fileHash}`;
core.debug(`primary key is ${primaryKey}`);
core.saveState(State.CachePrimaryKey, primaryKey);
const {'global-packages': cachePath} = await getNuGetFolderPath();
const cacheKey = await cache.restoreCache([cachePath], primaryKey);
core.setOutput(Outputs.CacheHit, Boolean(cacheKey));
if (!cacheKey) {
core.info('Dotnet cache is not found');
return;
}
core.saveState(State.CacheMatchedKey, cacheKey);
core.info(`Cache restored from key: ${cacheKey}`);
};
const findLockFile = async () => {
const workspace = process.env.GITHUB_WORKSPACE!;
const rootContent = await readdir(workspace);
const lockFile = lockFilePatterns.find(item => rootContent.includes(item));
if (!lockFile) {
throw new Error(
`Dependencies lock file is not found in ${workspace}. Supported file patterns: ${lockFilePatterns.toString()}`
);
}
return join(workspace, lockFile);
};

57
src/cache-save.ts Normal file
View File

@ -0,0 +1,57 @@
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import fs from 'node:fs';
import {getNuGetFolderPath} from './cache-utils';
import {State} from './constants';
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
// throw an uncaught exception. Instead of failing this action, just warn.
process.on('uncaughtException', e => {
const warningPrefix = '[warning]';
core.info(`${warningPrefix}${e.message}`);
});
export async function run() {
try {
if (core.getBooleanInput('cache')) {
await cachePackages();
}
} catch (error) {
core.setFailed(error.message);
}
}
const cachePackages = async () => {
const state = core.getState(State.CacheMatchedKey);
const primaryKey = core.getState(State.CachePrimaryKey);
if (!primaryKey) {
core.info('Primary key was not generated, not saving cache.');
return;
}
const {'global-packages': cachePath} = await getNuGetFolderPath();
if (!fs.existsSync(cachePath)) {
throw new Error(
`Cache folder path is retrieved for .NET CLI but doesn't exist on disk: ${cachePath}`
);
}
if (primaryKey === state) {
core.info(
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`
);
return;
}
const cacheId = await cache.saveCache([cachePath], primaryKey);
if (cacheId == -1) {
return;
}
core.info(`Cache saved with the key: ${primaryKey}`);
};
run();

98
src/cache-utils.ts Normal file
View File

@ -0,0 +1,98 @@
import * as cache from '@actions/cache';
import * as core from '@actions/core';
import * as exec from '@actions/exec';
import {cliCommand} from './constants';
type NuGetFolderName =
| 'http-cache'
| 'global-packages'
| 'temp'
| 'plugins-cache';
/**
* Get NuGet global packages, cache, and temp folders from .NET CLI.
* @returns (Folder Name)-(Path) mappings
* @see https://docs.microsoft.com/nuget/consume-packages/managing-the-global-packages-and-cache-folders
* @example
* Windows
* ```json
* {
* "http-cache": "C:\\Users\\user1\\AppData\\Local\\NuGet\\v3-cache",
* "global-packages": "C:\\Users\\user1\\.nuget\\packages\\",
* "temp": "C:\\Users\\user1\\AppData\\Local\\Temp\\NuGetScratch",
* "plugins-cache": "C:\\Users\\user1\\AppData\\Local\\NuGet\\plugins-cache"
* }
* ```
*
* Mac/Linux
* ```json
* {
* "http-cache": "/home/user1/.local/share/NuGet/v3-cache",
* "global-packages": "/home/user1/.nuget/packages/",
* "temp": "/tmp/NuGetScratch",
* "plugins-cache": "/home/user1/.local/share/NuGet/plugins-cache"
* }
* ```
*/
export const getNuGetFolderPath = async () => {
const {stdout, stderr, exitCode} = await exec.getExecOutput(
cliCommand,
undefined,
{ignoreReturnCode: true, silent: true}
);
if (exitCode) {
throw new Error(
!stderr.trim()
? `The '${cliCommand}' command failed with exit code: ${exitCode}`
: stderr
);
}
const result: Record<NuGetFolderName, string> = {
'http-cache': '',
'global-packages': '',
temp: '',
'plugins-cache': ''
};
const regex = /(?:^|\s)(?<key>[a-z-]+): (?<path>.+[/\\].+)$/gm;
let match: RegExpExecArray | null;
while ((match = regex.exec(stdout)) !== null) {
const key = match.groups!.key;
if ((key as NuGetFolderName) in result) {
result[key] = match.groups!.path;
}
}
return result;
};
export function isCacheFeatureAvailable(): boolean {
if (cache.isFeatureAvailable()) {
return true;
}
if (isGhes()) {
core.warning(
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.'
);
return false;
}
core.warning(
'The runner was not able to contact the cache service. Caching will be skipped'
);
return false;
}
/**
* Returns this action runs on GitHub Enterprise Server or not.
* (port from https://github.com/actions/toolkit/blob/457303960f03375db6f033e214b9f90d79c3fe5c/packages/cache/src/internal/cacheUtils.ts#L134)
*/
function isGhes(): boolean {
const url = process.env['GITHUB_SERVER_URL'] || 'https://github.com';
return new URL(url).hostname.toUpperCase() !== 'GITHUB.COM';
}

19
src/constants.ts Normal file
View File

@ -0,0 +1,19 @@
/** NuGet lock file patterns */
export const lockFilePatterns = ['packages.lock.json'];
/**
* .NET CLI command to list local NuGet resources.
* @see https://docs.microsoft.com/dotnet/core/tools/dotnet-nuget-locals
*/
export const cliCommand =
'dotnet nuget locals all --list --force-english-output';
export enum State {
CachePrimaryKey = 'CACHE_KEY',
CacheMatchedKey = 'CACHE_RESULT'
}
export enum Outputs {
CacheHit = 'cache-hit',
DotnetVersion = 'dotnet-version'
}

View File

@ -7,7 +7,7 @@ import {chmodSync} from 'fs';
import path from 'path';
import os from 'os';
import semver from 'semver';
import {IS_LINUX, IS_WINDOWS} from './utils';
import {IS_WINDOWS, PLATFORM} from './utils';
import {QualityOptions} from './setup-dotnet';
export interface DotnetVersion {
@ -81,7 +81,7 @@ export class DotnetVersionResolver {
parseInt(major) >= QUALITY_INPUT_MINIMAL_MAJOR_TAG ? true : false;
}
public async createDotNetVersion(): Promise<DotnetVersion> {
public async createDotnetVersion(): Promise<DotnetVersion> {
await this.resolveVersionInput();
if (!this.resolvedArgument.type) {
return this.resolvedArgument;
@ -102,7 +102,7 @@ export class DotnetVersionResolver {
maxRetries: 3
});
const response = await httpClient.getJson<any>(
DotnetVersionResolver.DotNetCoreIndexUrl
DotnetVersionResolver.DotnetCoreIndexUrl
);
const result = response.result || {};
const releasesInfo: any[] = result['releases-index'];
@ -114,85 +114,37 @@ export class DotnetVersionResolver {
if (!releaseInfo) {
throw new Error(
`Could not find info for version with major tag: "${majorTag}" at ${DotnetVersionResolver.DotNetCoreIndexUrl}`
`Could not find info for version with major tag: "${majorTag}" at ${DotnetVersionResolver.DotnetCoreIndexUrl}`
);
}
return releaseInfo['channel-version'];
}
static DotNetCoreIndexUrl =
static DotnetCoreIndexUrl =
'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
}
export class DotnetCoreInstaller {
private version: string;
private quality: QualityOptions;
export class DotnetInstallScript {
private scriptName = IS_WINDOWS ? 'install-dotnet.ps1' : 'install-dotnet.sh';
private escapedScript: string;
private scriptArguments: string[] = [];
constructor() {
this.escapedScript = path
.join(__dirname, '..', '..', 'externals', this.scriptName)
.replace(/'/g, "''");
static {
const installationDirectoryWindows = path.join(
process.env['PROGRAMFILES'] + '',
'dotnet'
);
const installationDirectoryLinux = '/usr/share/dotnet';
const installationDirectoryMac = path.join(
process.env['HOME'] + '',
'.dotnet'
);
const dotnetInstallDir: string | undefined =
process.env['DOTNET_INSTALL_DIR'];
if (dotnetInstallDir) {
process.env['DOTNET_INSTALL_DIR'] =
this.convertInstallPathToAbsolute(dotnetInstallDir);
} else {
if (IS_WINDOWS) {
process.env['DOTNET_INSTALL_DIR'] = installationDirectoryWindows;
} else {
process.env['DOTNET_INSTALL_DIR'] = IS_LINUX
? installationDirectoryLinux
: installationDirectoryMac;
}
}
this.setupScriptPowershell();
return;
}
constructor(version: string, quality: QualityOptions) {
this.version = version;
this.quality = quality;
this.setupScriptBash();
}
private static convertInstallPathToAbsolute(installDir: string): string {
let transformedPath;
if (path.isAbsolute(installDir)) {
transformedPath = installDir;
} else {
transformedPath = installDir.startsWith('~')
? path.join(os.homedir(), installDir.slice(1))
: (transformedPath = path.join(process.cwd(), installDir));
}
return path.normalize(transformedPath);
}
static addToPath() {
core.addPath(process.env['DOTNET_INSTALL_DIR']!);
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
}
private setQuality(
dotnetVersion: DotnetVersion,
scriptArguments: string[]
): void {
const option = IS_WINDOWS ? '-Quality' : '--quality';
if (dotnetVersion.qualityFlag) {
scriptArguments.push(option, this.quality);
} else {
core.warning(
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${this.version}. 'dotnet-quality' input is ignored.`
);
}
}
public async installDotnet(): Promise<string | null> {
const windowsDefaultOptions = [
private setupScriptPowershell() {
this.scriptArguments = [
'-NoLogo',
'-Sta',
'-NoProfile',
@ -201,68 +153,157 @@ export class DotnetCoreInstaller {
'Unrestricted',
'-Command'
];
const scriptName = IS_WINDOWS ? 'install-dotnet.ps1' : 'install-dotnet.sh';
const escapedScript = path
.join(__dirname, '..', 'externals', scriptName)
.replace(/'/g, "''");
let scriptArguments: string[];
let scriptPath = '';
const versionResolver = new DotnetVersionResolver(this.version);
const dotnetVersion = await versionResolver.createDotNetVersion();
if (IS_WINDOWS) {
scriptArguments = ['&', `'${escapedScript}'`];
if (dotnetVersion.type) {
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
}
if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments);
}
this.scriptArguments.push('&', `'${this.escapedScript}'`);
if (process.env['https_proxy'] != null) {
scriptArguments.push(`-ProxyAddress ${process.env['https_proxy']}`);
this.scriptArguments.push(`-ProxyAddress ${process.env['https_proxy']}`);
}
// This is not currently an option
if (process.env['no_proxy'] != null) {
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
this.scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
}
}
scriptPath =
(await io.which('pwsh', false)) || (await io.which('powershell', true));
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
} else {
chmodSync(escapedScript, '777');
scriptPath = await io.which(escapedScript, true);
scriptArguments = [];
private setupScriptBash() {
chmodSync(this.escapedScript, '777');
}
private async getScriptPath() {
if (IS_WINDOWS) {
return (await io.which('pwsh', false)) || io.which('powershell', true);
}
return io.which(this.escapedScript, true);
}
public useArguments(...args: string[]) {
this.scriptArguments.push(...args);
return this;
}
public useVersion(dotnetVersion: DotnetVersion, quality?: QualityOptions) {
if (dotnetVersion.type) {
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
this.useArguments(dotnetVersion.type, dotnetVersion.value);
}
if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments);
if (quality && !dotnetVersion.qualityFlag) {
core.warning(
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${dotnetVersion.value}. 'dotnet-quality' input is ignored.`
);
return this;
}
if (quality) {
this.useArguments(IS_WINDOWS ? '-Quality' : '--quality', quality);
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
return this;
}
public async execute() {
const getExecOutputOptions = {
ignoreReturnCode: true,
env: process.env as {string: string}
};
const {exitCode, stdout, stderr} = await exec.getExecOutput(
`"${scriptPath}"`,
scriptArguments,
return exec.getExecOutput(
`"${await this.getScriptPath()}"`,
this.scriptArguments,
getExecOutputOptions
);
if (exitCode) {
throw new Error(
`Failed to install dotnet, exit code: ${exitCode}. ${stderr}`
}
}
export abstract class DotnetInstallDir {
private static readonly default = {
linux: '/usr/share/dotnet',
mac: path.join(process.env['HOME'] + '', '.dotnet'),
windows: path.join(process.env['PROGRAMFILES'] + '', 'dotnet')
};
public static readonly dirPath = process.env['DOTNET_INSTALL_DIR']
? DotnetInstallDir.convertInstallPathToAbsolute(
process.env['DOTNET_INSTALL_DIR']
)
: DotnetInstallDir.default[PLATFORM];
private static convertInstallPathToAbsolute(installDir: string): string {
if (path.isAbsolute(installDir)) return path.normalize(installDir);
const transformedPath = installDir.startsWith('~')
? path.join(os.homedir(), installDir.slice(1))
: path.join(process.cwd(), installDir);
return path.normalize(transformedPath);
}
public static addToPath() {
core.addPath(process.env['DOTNET_INSTALL_DIR']!);
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
}
public static setEnvironmentVariable() {
process.env['DOTNET_INSTALL_DIR'] = DotnetInstallDir.dirPath;
}
}
export class DotnetCoreInstaller {
static {
DotnetInstallDir.setEnvironmentVariable();
}
constructor(private version: string, private quality: QualityOptions) {}
public async installDotnet(): Promise<string | null> {
const versionResolver = new DotnetVersionResolver(this.version);
const dotnetVersion = await versionResolver.createDotnetVersion();
/**
* Install dotnet runitme first in order to get
* the latest stable version of dotnet CLI
*/
const runtimeInstallOutput = await new DotnetInstallScript()
// If dotnet CLI is already installed - avoid overwriting it
.useArguments(
IS_WINDOWS ? '-SkipNonVersionedFiles' : '--skip-non-versioned-files'
)
// Install only runtime + CLI
.useArguments(IS_WINDOWS ? '-Runtime' : '--runtime', 'dotnet')
// Use latest stable version
.useArguments(IS_WINDOWS ? '-Channel' : '--channel', 'LTS')
.execute();
if (runtimeInstallOutput.exitCode) {
/**
* dotnetInstallScript will install CLI and runtime even if previous script haven't succeded,
* so at this point it's too early to throw an error
*/
core.warning(
`Failed to install dotnet runtime + cli, exit code: ${runtimeInstallOutput.exitCode}. ${runtimeInstallOutput.stderr}`
);
}
return this.parseInstalledVersion(stdout);
/**
* Install dotnet over the latest version of
* dotnet CLI
*/
const dotnetInstallOutput = await new DotnetInstallScript()
// 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)
.execute();
if (dotnetInstallOutput.exitCode) {
throw new Error(
`Failed to install dotnet, exit code: ${dotnetInstallOutput.exitCode}. ${dotnetInstallOutput.stderr}`
);
}
return this.parseInstalledVersion(dotnetInstallOutput.stdout);
}
private parseInstalledVersion(stdout: string): string | null {

View File

@ -1,9 +1,13 @@
import * as core from '@actions/core';
import {DotnetCoreInstaller} from './installer';
import {DotnetCoreInstaller, DotnetInstallDir} from './installer';
import * as fs from 'fs';
import path from 'path';
import semver from 'semver';
import * as auth from './authutil';
import {isCacheFeatureAvailable} from './cache-utils';
import {restoreCache} from './cache-restore';
import {Outputs} from './constants';
import JSON5 from 'json5';
const qualityOptions = [
'daily',
@ -69,7 +73,7 @@ export async function run() {
const installedVersion = await dotnetInstaller.installDotnet();
installedDotnetVersions.push(installedVersion);
}
DotnetCoreInstaller.addToPath();
DotnetInstallDir.addToPath();
}
const sourceUrl: string = core.getInput('source-url');
@ -80,7 +84,12 @@ export async function run() {
outputInstalledVersion(installedDotnetVersions, globalJsonFileInput);
const matchersPath = path.join(__dirname, '..', '.github');
if (core.getBooleanInput('cache') && isCacheFeatureAvailable()) {
const cacheDependencyPath = core.getInput('cache-dependency-path');
await restoreCache(cacheDependencyPath);
}
const matchersPath = path.join(__dirname, '..', '..', '.github');
core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`);
} catch (error) {
core.setFailed(error.message);
@ -89,9 +98,14 @@ export async function run() {
function getVersionFromGlobalJson(globalJsonPath: string): string {
let version = '';
const globalJson = JSON.parse(
const globalJson = JSON5.parse(
// .trim() is necessary to strip BOM https://github.com/nodejs/node/issues/20649
fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim()
fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim(),
// is necessary as JSON5 supports wider variety of options for numbers: https://www.npmjs.com/package/json5#numbers
(key, value) => {
if (key === 'version' || key === 'rollForward') return String(value);
return value;
}
);
if (globalJson.sdk && globalJson.sdk.version) {
version = globalJson.sdk.version;
@ -109,20 +123,20 @@ function outputInstalledVersion(
globalJsonFileInput: string
): void {
if (!installedVersions.length) {
core.info(`The 'dotnet-version' output will not be set.`);
core.info(`The '${Outputs.DotnetVersion}' output will not be set.`);
return;
}
if (installedVersions.includes(null)) {
core.warning(
`Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`
`Failed to output the installed version of .NET. The '${Outputs.DotnetVersion}' output will not be set.`
);
return;
}
if (globalJsonFileInput) {
const versionToOutput = installedVersions.at(-1); // .NET SDK version parsed from the global.json file is installed last
core.setOutput('dotnet-version', versionToOutput);
core.setOutput(Outputs.DotnetVersion, versionToOutput);
return;
}
@ -134,7 +148,7 @@ function outputInstalledVersion(
}
);
core.setOutput('dotnet-version', versionToOutput);
core.setOutput(Outputs.DotnetVersion, versionToOutput);
}
run();

View File

@ -1,2 +1,6 @@
export const IS_WINDOWS = process.platform === 'win32';
export const IS_LINUX = process.platform === 'linux';
export const PLATFORM = ((): 'windows' | 'linux' | 'mac' => {
if (process.platform === 'win32') return 'windows';
if (process.platform === 'linux') return 'linux';
return 'mac';
})();