Compare commits

...

31 Commits

Author SHA1 Message Date
607fce577a Update the link to the .Net Core releases index file (#337) 2022-10-24 14:21:32 +02:00
501b34e8f6 Merge pull request #336 from e-korolevskii/refactor-nuget-cfg-parse
Refactor nuget cfg parse
2022-10-24 09:42:37 +02:00
b827fcce4d build 2022-10-13 16:35:12 +02:00
239baf3c5b Merge branch 'main' into refactor-nuget-cfg-parse 2022-10-13 16:34:35 +02:00
4d4a70f4a5 Add logic for processing DOTNET_INSTALL_DIR environment variable (#332) 2022-10-10 14:27:29 +02:00
70c3f4d098 Merge pull request #331 from rentziass/rentziass/update-actions-core
Update @actions/core to 1.10.0
2022-10-07 13:50:06 +02:00
9260643816 Update @actions/core to 1.10.0 2022-10-06 12:05:06 +01:00
45c9f236cf Enable ability to change .NET SDK installation directory by DOTNET_INSTALL_DIR environment variable (#329) 2022-10-04 10:22:05 +02:00
6d6c7c9313 build 2022-09-30 09:33:54 +02:00
e753bbf2ff remove build 2022-09-30 09:33:03 +02:00
629365b26e Merge branch 'main' into refactor-nuget-cfg-parse 2022-09-30 09:28:48 +02:00
942a0bea39 format 2022-09-30 02:37:51 +02:00
26db2473e9 fix empty first line 2022-09-30 02:23:20 +02:00
467621733d add packageSourceCredentials 2022-09-30 02:19:09 +02:00
bdd38d13dc build 2022-09-30 02:05:09 +02:00
1d2f8f9eaf add debug log 2022-09-30 02:04:34 +02:00
354d280fa3 refactor using of XMLBuilder 2022-09-30 01:54:05 +02:00
0ff311b0d0 add nested dep license 2022-09-29 18:43:45 +02:00
bc65ba63d3 update license 2022-09-29 18:30:09 +02:00
90642fa8c5 update parser to v4 2022-09-29 18:23:42 +02:00
c7e7147fd3 Add ability to write resolved version of SDK into the output variable (#324) 2022-09-29 17:45:25 +02:00
cf081e76a2 merge main & build 2022-09-28 15:30:56 +02:00
4ca3c96b49 Merge branch 'main' into refactor-nuget-cfg-parse 2022-09-28 09:30:07 +02:00
0705ef0281 Implement proposal stated in ADR for setup-dotnet v3 and functionality from feature request #219 (#315) 2022-09-27 14:47:12 +02:00
cc76dfab99 format 2022-09-21 15:14:01 +03:00
1f2c90bb99 Merge branch 'main' into refactor-nuget-cfg-parse 2022-09-19 20:18:40 +02:00
251997c37d updated installers 2022-09-19 20:18:24 +02:00
5d7bc0454b update installers 2022-08-31 16:01:51 +02:00
792e988dae build 2022-08-31 15:43:30 +02:00
e5034212c9 refactoring 2022-08-31 15:41:59 +02:00
0997db20d4 refactoring 2022-08-31 15:41:46 +02:00
29 changed files with 4474 additions and 8722 deletions

2
.gitattributes vendored
View File

@ -1 +1 @@
.licenses/** -diff linguist-generated=true .licenses/** -diff linguist-generated=true

View File

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

View File

@ -78,7 +78,7 @@ jobs:
uses: ./ uses: ./
with: with:
dotnet-version: 3.1.201 dotnet-version: 3.1.201
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place # We are including this variable to force the generation of the nuget config file to verify that it is created in the correct place
source-url: https://api.nuget.org/v3/index.json source-url: https://api.nuget.org/v3/index.json
env: env:
NUGET_AUTH_TOKEN: NOTATOKEN NUGET_AUTH_TOKEN: NOTATOKEN
@ -115,6 +115,30 @@ jobs:
shell: pwsh shell: pwsh
run: __tests__/verify-dotnet.ps1 3.1 2.2 run: __tests__/verify-dotnet.ps1 3.1 2.2
test-setup-prerelease-version:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup dotnet '2.2'
uses: ./
with:
dotnet-version: '2.2'
- name: Setup dotnet '3.1.100-preview1-014459'
uses: ./
with:
dotnet-version: '3.1.100-preview1-014459'
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 3.1.100-preview1-014459
test-setup-latest-patch-version: test-setup-latest-patch-version:
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
strategy: strategy:
@ -131,13 +155,13 @@ jobs:
uses: ./ uses: ./
with: with:
dotnet-version: 3.1.x dotnet-version: 3.1.x
- name: Setup dotnet 2.2.x - name: Setup dotnet 2.2.X
uses: ./ uses: ./
with: with:
dotnet-version: 2.2.x dotnet-version: 2.2.X
- name: Verify dotnet - name: Verify dotnet
shell: pwsh shell: pwsh
run: __tests__/verify-dotnet.ps1 3.1 2.2 run: __tests__/verify-dotnet.ps1 '2.2' '3.1'
test-setup-with-wildcard: test-setup-with-wildcard:
runs-on: ${{ matrix.operating-system }} runs-on: ${{ matrix.operating-system }}
@ -189,6 +213,85 @@ jobs:
shell: pwsh shell: pwsh
run: __tests__/verify-dotnet.ps1 2.2 3.1 run: __tests__/verify-dotnet.ps1 2.2 3.1
test-setup-with-dotnet-quality:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup dotnet 7.0 with preview quality
uses: ./
with:
dotnet-version: "7.0"
dotnet-quality: "preview"
- name: Verify preview version
shell: pwsh
run: |
$version = & dotnet --version
Write-Host "Installed version: $version"
if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" }
test-dotnet-version-output-during-single-version-installation:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup dotnet 6.0.401
uses: ./
id: step1
with:
dotnet-version: "6.0.401"
- name: Verify value of the dotnet-version output
shell: pwsh
run: |
$version = & dotnet --version
Write-Host "Installed version: $version"
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
test-dotnet-version-output-during-multiple-version-installation:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup dotnet 6.0.401, 5.0.408, 7.0.100-rc.1.22431.12
uses: ./
id: step2
with:
dotnet-version: |
7.0.100-rc.1.22431.12
6.0.401
5.0.408
- name: Verify value of the dotnet-version output
shell: pwsh
run: |
$version = "7.0.100-rc.1.22431.12"
if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
test-proxy: test-proxy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: container:

View File

@ -1,6 +1,6 @@
--- ---
name: "@actions/core" name: "@actions/core"
version: 1.6.0 version: 1.10.0
type: npm type: npm
summary: Actions core lib summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core homepage: https://github.com/actions/toolkit/tree/main/packages/core

View File

@ -1,30 +1,20 @@
--- ---
name: "@actions/exec" name: "@actions/exec"
version: 1.0.4 version: 1.1.1
type: npm type: npm
summary: Actions exec lib summary: Actions exec lib
homepage: https://github.com/actions/toolkit/tree/master/packages/exec homepage: https://github.com/actions/toolkit/tree/main/packages/exec
license: mit license: mit
licenses: licenses:
- sources: Auto-generated MIT license text - sources: LICENSE.md
text: | text: |-
MIT License The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy Copyright 2019 GitHub
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 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:
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
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: [] notices: []

View File

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

View File

@ -1,9 +1,9 @@
--- ---
name: "@actions/http-client" name: "@actions/http-client"
version: 1.0.11 version: 2.0.1
type: npm type: npm
summary: Actions Http Client summary: Actions Http Client
homepage: https://github.com/actions/http-client#readme homepage: https://github.com/actions/toolkit/tree/main/packages/http-client
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE

View File

@ -1,30 +1,20 @@
--- ---
name: "@actions/io" name: "@actions/io"
version: 1.0.2 version: 1.1.2
type: npm type: npm
summary: Actions io lib summary: Actions io lib
homepage: https://github.com/actions/toolkit/tree/master/packages/io homepage: https://github.com/actions/toolkit/tree/main/packages/io
license: mit license: mit
licenses: licenses:
- sources: Auto-generated MIT license text - sources: LICENSE.md
text: | text: |-
MIT License The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy Copyright 2019 GitHub
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 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:
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 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.
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: [] notices: []

View File

@ -1,27 +1,11 @@
--- ---
name: fast-xml-parser name: fast-xml-parser
version: 3.17.4 version: 4.0.10
type: npm type: npm
summary: Validate XML or Parse XML to JS/JSON very fast without C/C++ based libraries 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 homepage: https://github.com/NaturalIntelligence/fast-xml-parser#readme
license: mit license: mit
licenses: licenses:
- sources: LICENSE - sources: LICENSE
text: "MIT License\n\nCopyright (c) 2017 Amit Kumar Gupta\n\nPermission is hereby text: "MIT License\n\nCopyright (c) 2017 Amit Kumar Gupta\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
granted, free of charge, to any person obtaining a copy\nof this software and
associated documentation files (the \"Software\"), to deal\nin the Software without
restriction, including without limitation the rights\nto use, copy, modify, merge,
publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit
persons to whom the Software is\nfurnished to do so, subject to the following
conditions:\n\nIf you use this library in a public repository then you give us
the right to mention your company name and logo in user's list without further
permission required, but you can request them to be taken down within 30 days.
\n\nThe above copyright notice and this permission notice shall be included in
all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED
\"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE
AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR
THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
notices: [] notices: []

11
.licenses/npm/strnum.dep.yml generated Normal file
View File

@ -0,0 +1,11 @@
---
name: strnum
version: 1.0.5
type: npm
summary: Parse string into Number based on configuration
homepage: https://github.com/NaturalIntelligence/strnum
license: mit
licenses:
- sources: LICENSE
text: "MIT License\n\nCopyright (c) 2021 Natural Intelligence\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
notices: []

20
.licenses/npm/uuid.dep.yml generated Normal file
View File

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

View File

@ -1,24 +0,0 @@
---
name: xmlbuilder
version: 13.0.2
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)\r\n\r\nCopyright (c) 2013 Ozgur Ozcitak\r\n\r\nPermission
is hereby granted, free of charge, to any person obtaining a copy\r\nof this software
and associated documentation files (the \"Software\"), to deal\r\nin the Software
without restriction, including without limitation the rights\r\nto use, copy,
modify, merge, publish, distribute, sublicense, and/or sell\r\ncopies of the Software,
and to permit persons to whom the Software is\r\nfurnished to do so, subject to
the following conditions:\r\n\r\nThe above copyright notice and this permission
notice shall be included in\r\nall copies or substantial portions of the Software.\r\n\r\nTHE
SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\nIMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\nFITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\nAUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\nLIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\nOUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r\nTHE SOFTWARE.\r\n"
notices: []

View File

@ -7,5 +7,6 @@
"trailingComma": "none", "trailingComma": "none",
"bracketSpacing": false, "bracketSpacing": false,
"arrowParens": "avoid", "arrowParens": "avoid",
"parser": "typescript" "parser": "typescript",
"endOfLine": "auto"
} }

176
README.md
View File

@ -8,62 +8,82 @@ This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for
- registering problem matchers for error output - registering problem matchers for error output
- setting up authentication to private package sources like GitHub Packages - setting up authentication to private package sources like GitHub Packages
Please Note: GitHub hosted runners have some versions of the .NET SDK > **Note**: GitHub hosted runners have some versions of the .NET SDK
preinstalled. Installed versions are subject to change. Please refer to the preinstalled. Installed versions are subject to change. Please refer to the
documentation documentation
[software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software) [software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software)
for .NET SDK versions that are currently available. for .NET SDK versions that are currently available.
# Usage ## Usage
See [action.yml](action.yml) See [action.yml](action.yml)
Basic: **Basic**:
```yaml ```yaml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: '3.1.x' # SDK Version to use; x will use the latest version of the 3.1 channel dotnet-version: '3.1.x'
- run: dotnet build <my project> - run: dotnet build <my project>
``` ```
Multiple versions:
> Note: In case multiple versions are installed, the latest .NET version will be used by default unless another version is specified in the `global.json` file.
**Multiple version installation**:
```yml ```yml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v2 uses: actions/setup-dotnet@v3
with: with:
dotnet-version: | dotnet-version: |
3.1.x 3.1.x
5.0.x 5.0.x
- run: dotnet build <my project> - run: dotnet build <my project>
``` ```
Preview version: > **Note**: In case multiple versions are installed, the latest .NET version will be used by default unless another version is specified in the `global.json` file.
## Supported version syntax
The `dotnet-version` input supports following syntax:
- **A.B.C** (e.g 6.0.400, 7.0.100-preview.7.22377.5) - installs exact version of .NET SDK
- **A.B** or **A.B.x** (e.g. 3.1, 3.1.x) - installs the latest patch version of .NET SDK on the channel `3.1`, including prerelease versions (preview, rc)
- **A** or **A.x** (e.g. 3, 3.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
## Using the `dotnet-quality` input
This input sets up the action to install the latest build of the specified quality in the channel. The possible values of `dotnet-quality` are: **daily**, **signed**, **validated**, **preview**, **ga**.
> **Note**: `dotnet-quality` input can be used only with .NET SDK version in 'A.B', 'A.B.x', 'A' and 'A.x' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
```yml ```yml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: '6.0.x' dotnet-version: '6.0.x'
include-prerelease: true dotnet-quality: 'preview'
- run: dotnet build <my project> - run: dotnet build <my project>
``` ```
global.json in a subdirectory:
## Using the `global-json-file` input
`setup-dotnet` action can read .NET SDK version from a `global.json` file. Input `global-json-file` is used for specifying the path to the `global.json`. If the file that was supplied to `global-json-file` input doesn't exist, the action will fail with error.
>**Note**: In case both `dotnet-version` and `global-json-file` inputs are used, versions from both inputs will be installed.
```yml ```yml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v3
with: with:
global-json-file: csharp/global.json global-json-file: csharp/global.json
- run: dotnet build <my project> - run: dotnet build <my project>
working-directory: csharp working-directory: csharp
``` ```
Matrix Testing: ## Matrix Testing
```yaml Using `setup-dotnet` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of .NET SDK:
```yml
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -74,38 +94,20 @@ jobs:
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Setup dotnet - name: Setup dotnet
uses: actions/setup-dotnet@v2 uses: actions/setup-dotnet@v3
with: with:
dotnet-version: ${{ matrix.dotnet }} dotnet-version: ${{ matrix.dotnet }}
- run: dotnet build <my project> - run: dotnet build <my project>
``` ```
## Setting up authentication for nuget feeds
Side by Side Testing: ### Github Package Registry (GPR)
```yaml ```yml
jobs:
build:
runs-on: ubuntu-latest
name: Dotnet Side by Side testing sample
steps:
- uses: actions/checkout@v3
- name: Setup dotnet
uses: actions/setup-dotnet@v2
with:
dotnet-version: |
2.1.x
3.1.x
- run: dotnet build <my project>
- run: dotnet test <my project>
```
Authentication for nuget feeds:
```yaml
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
# Authenticates packages to push to GPR - uses: actions/setup-dotnet@v3
- uses: actions/setup-dotnet@v2
with: with:
dotnet-version: '3.1.x' # SDK Version to use. dotnet-version: '3.1.x'
source-url: https://nuget.pkg.github.com/<owner>/index.json source-url: https://nuget.pkg.github.com/<owner>/index.json
env: env:
NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
@ -114,19 +116,22 @@ steps:
run: dotnet pack --configuration Release <my project> run: dotnet pack --configuration Release <my project>
- name: Publish the package to GPR - name: Publish the package to GPR
run: dotnet nuget push <my project>/bin/Release/*.nupkg run: dotnet nuget push <my project>/bin/Release/*.nupkg
```
# Authenticates packages to push to Azure Artifacts ### Azure Artifacts
- uses: actions/setup-dotnet@v2 ```yml
- uses: actions/setup-dotnet@v3
with: with:
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
env: env:
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
- name: Publish the package to Azure Artifacts - name: Publish the package to Azure Artifacts
run: dotnet nuget push <my project>/bin/Release/*.nupkg run: dotnet nuget push <my project>/bin/Release/*.nupkg
```
# Authenticates packages to push to nuget.org. ### nuget.org
# It's only the way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations. ```yml
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: 3.1.x dotnet-version: 3.1.x
- name: Publish the package to nuget.org - name: Publish the package to nuget.org
@ -134,32 +139,91 @@ steps:
env: env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }} NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
``` ```
> **Note**: It's the only way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
## Environment Variables to use with dotnet # Outputs and environment variables
## Outputs
### `dotnet-version`
Using the **dotnet-version** output it's possible to get the installed by the action .NET SDK version.
**Single version installation**
In case of a single version installation, the `dotnet-version` output contains the version that is installed by the action.
```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: 3.1.422
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 3.1.422
```
**Multiple version installation**
In case of a multiple version installation, the `dotnet-version` output contains the latest version that is installed by the action.
```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: |
3.1.422
5.0.408
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 5.0.408
```
**Installation from global.json**
When the `dotnet-version` input is used along with the `global-json-file` input, the `dotnet-version` output contains the version resolved from the `global.json`.
```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: |
3.1.422
5.0.408
global-json-file: "./global.json" # contains version 2.2.207
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 2.2.207
```
## Environment variables
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false) | **Env.variable** | **Description** | **Default value** |
- DOTNET_CLI_TELEMETRY_OPTOUT - opt-out of telemetry being sent to Microsoft (default: false) | ----------- | ----------- | ----------- |
- DOTNET_MULTILEVEL_LOOKUP - configures whether the global install location is used as a fall-back (default: true) | DOTNET_INSTALL_DIR |Specifies a directory where .NET SDKs should be installed by the action.|*default value for each OS* |
| DOTNET_NOLOGO |Removes logo and telemetry message from first run of dotnet cli|*false*|
| DOTNET_CLI_TELEMETRY_OPTOUT |Opt-out of telemetry being sent to Microsoft|*false*|
| DOTNET_MULTILEVEL_LOOKUP |Configures whether the global install location is used as a fall-back|*true*|
Example usage: The default value of the `DOTNET_INSTALL_DIR` environment variable depends on the operation system which is used on a runner:
```yaml | **Operation system** | **Default value** |
| ----------- | ----------- |
| **Windows** | `C:\Program Files\dotnet` |
| **Ubuntu** | `/usr/share/dotnet` |
| **macOS** | `/Users/runner/.dotnet` |
**Example usage**:
```yml
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
DOTNET_NOLOGO: true DOTNET_INSTALL_DIR: "path/to/directory"
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
- uses: actions/setup-dotnet@v2 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: '3.1.x' # SDK Version to use. dotnet-version: '3.1.x'
``` ```
# License ## License
The scripts and documentation in this project are released under the [MIT License](LICENSE) The scripts and documentation in this project are released under the [MIT License](LICENSE)
# Contributions ## Contributions
Contributions are welcome! See [Contributor's Guide](docs/contributors.md) Contributions are welcome! See [Contributor's Guide](docs/contributors.md)

View File

@ -1,15 +1,11 @@
import io = require('@actions/io'); import * as io from '@actions/io';
import fs = require('fs'); import fs from 'fs';
import path = require('path'); import path from 'path';
const fakeSourcesDirForTesting = path.join( const fakeSourcesDirForTesting = path.join(
__dirname, __dirname,
'runner', 'runner',
path.join( path.join(Math.random().toString(36).substring(7)),
Math.random()
.toString(36)
.substring(7)
),
's' 's'
); );

View File

@ -1,5 +1,3 @@
import fs = require('fs');
describe('csc tests', () => { describe('csc tests', () => {
it('Valid regular expression', async () => { it('Valid regular expression', async () => {
var cscFile = require('../.github/csc.json'); var cscFile = require('../.github/csc.json');

View File

@ -1,34 +1,55 @@
import io = require('@actions/io'); import * as io from '@actions/io';
import fs = require('fs'); import * as os from 'os';
import os = require('os'); import fs from 'fs';
import path = require('path'); import path from 'path';
import hc = require('@actions/http-client'); import each from 'jest-each';
import * as hc from '@actions/http-client';
import * as installer from '../src/installer';
import {QualityOptions} from '../src/setup-dotnet';
const toolDir = path.join(__dirname, 'runner', 'tools'); import {IS_WINDOWS} from '../src/utils';
import {IS_LINUX} from '../src/utils';
let toolDir: string;
if (IS_WINDOWS) {
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
} else if (IS_LINUX) {
toolDir = '/usr/share/dotnet';
} else {
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
}
const tempDir = path.join(__dirname, 'runner', 'temp'); const tempDir = path.join(__dirname, 'runner', 'temp');
process.env['RUNNER_TOOL_CACHE'] = toolDir; process.env['RUNNER_TOOL_CACHE'] = toolDir;
process.env['RUNNER_TEMP'] = tempDir; process.env['RUNNER_TEMP'] = tempDir;
import * as installer from '../src/installer';
const IS_WINDOWS = process.platform === 'win32'; describe('DotnetCoreInstaller tests', () => {
describe('installer tests', () => {
beforeAll(async () => { beforeAll(async () => {
process.env.RUNNER_TOOL_CACHE = toolDir; process.env.RUNNER_TOOL_CACHE = toolDir;
process.env.DOTNET_INSTALL_DIR = toolDir; process.env.DOTNET_INSTALL_DIR = toolDir;
process.env.RUNNER_TEMP = tempDir; process.env.RUNNER_TEMP = tempDir;
process.env.DOTNET_ROOT = ''; process.env.DOTNET_ROOT = '';
await io.rmRF(toolDir);
await io.rmRF(tempDir);
});
afterAll(async () => {
try { try {
await io.rmRF(toolDir); await io.rmRF(`${toolDir}/*`);
await io.rmRF(tempDir); await io.rmRF(`${tempDir}/*`);
} catch { } catch (err) {
console.log('Failed to remove test directories'); console.log(
`Failed to remove test directories, check the error message:${os.EOL}`,
err.message
);
}
}, 30000);
afterEach(async () => {
try {
await io.rmRF(`${toolDir}/*`);
await io.rmRF(`${tempDir}/*`);
} catch (err) {
console.log(
`Failed to remove test directories, check the error message:${os.EOL}`,
err.message
);
} }
}, 30000); }, 30000);
@ -86,14 +107,19 @@ describe('installer tests', () => {
expect(process.env.PATH?.startsWith(toolDir)).toBe(true); expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
}, 600000); //This needs some time to download on "slower" internet connections }, 600000); //This needs some time to download on "slower" internet connections
it('Returns string with installed SDK version', async () => {
const version = '3.1.120';
let installedVersion: string;
installedVersion = await getDotnet(version);
expect(installedVersion).toBe('3.1.120');
}, 600000);
it('Throws if no location contains correct dotnet version', async () => { it('Throws if no location contains correct dotnet version', async () => {
let thrown = false; await expect(async () => {
try {
await getDotnet('1000.0.0'); await getDotnet('1000.0.0');
} catch { }).rejects.toThrow();
thrown = true;
}
expect(thrown).toBe(true);
}, 30000); }, 30000);
it('Uses an up to date bash download script', async () => { it('Uses an up to date bash download script', async () => {
@ -137,6 +163,112 @@ describe('installer tests', () => {
}, 30000); }, 30000);
}); });
describe('DotnetVersionResolver tests', () => {
each([
'3.1',
'3.x',
'3.1.x',
'3.1.*',
'3.1.X',
'3.1.2',
'3.1.0-preview1'
]).test(
"if valid version: '%s' is supplied, it should return version object with some value",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
const versionObject = await dotnetVersionResolver.createDotNetVersion();
expect(!!versionObject.value).toBeTruthy;
}
);
each([
'.',
'..',
' . ',
'. ',
' .',
' . . ',
' .. ',
' . ',
'-1.-1',
'-1',
'-1.-1.-1',
'..3',
'1..3',
'1..',
'.2.3',
'.2.x',
'*.',
'1.2.',
'1.2.-abc',
'a.b',
'a.b.c',
'a.b.c-preview',
' 0 . 1 . 2 ',
'invalid'
]).test(
"if invalid version: '%s' is supplied, it should throw",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
await expect(
async () => await dotnetVersionResolver.createDotNetVersion()
).rejects.toThrow();
}
);
each(['3.1', '3.1.x', '3.1.*', '3.1.X']).test(
"if version: '%s' that can be resolved to 'channel' option is supplied, it should set quality flag to 'true' and type to 'channel' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
const versionObject = await dotnetVersionResolver.createDotNetVersion();
expect(versionObject.type.toLowerCase().includes('channel')).toBeTruthy;
expect(versionObject.qualityFlag).toBeTruthy;
}
);
each(['3.1.2', '3.1.0-preview1']).test(
"if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
const versionObject = await dotnetVersionResolver.createDotNetVersion();
expect(versionObject.type.toLowerCase().includes('version')).toBeTruthy;
expect(versionObject.qualityFlag).toBeFalsy;
}
);
each(['3.1.2', '3.1']).test(
'it should create proper line arguments for powershell/bash installation scripts',
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
const versionObject = await dotnetVersionResolver.createDotNetVersion();
const windowsRegEx = new RegExp(/^-[VC]/);
const nonWindowsRegEx = new RegExp(/^--[vc]/);
if (IS_WINDOWS) {
expect(windowsRegEx.test(versionObject.type)).toBeTruthy;
expect(nonWindowsRegEx.test(versionObject.type)).toBeFalsy;
} else {
expect(nonWindowsRegEx.test(versionObject.type)).toBeTruthy;
expect(windowsRegEx.test(versionObject.type)).toBeFalsy;
}
}
);
});
function normalizeFileContents(contents: string): string { function normalizeFileContents(contents: string): string {
return contents return contents
.trim() .trim()
@ -144,8 +276,15 @@ function normalizeFileContents(contents: string): string {
.replace(new RegExp('\r', 'g'), '\n'); .replace(new RegExp('\r', 'g'), '\n');
} }
async function getDotnet(version: string): Promise<void> { async function getDotnet(
const dotnetInstaller = new installer.DotnetCoreInstaller(version); version: string,
await dotnetInstaller.installDotnet(); quality: string = ''
): Promise<string> {
const dotnetInstaller = new installer.DotnetCoreInstaller(
version,
quality as QualityOptions
);
const installedVersion = await dotnetInstaller.installDotnet();
installer.DotnetCoreInstaller.addToPath(); installer.DotnetCoreInstaller.addToPath();
return installedVersion;
} }

View File

@ -1,32 +1,52 @@
import io = require('@actions/io'); import * as io from '@actions/io';
import fs = require('fs'); import * as core from '@actions/core';
import os = require('os'); import fs from 'fs';
import path = require('path'); import os from 'os';
import path from 'path';
const toolDir = path.join(__dirname, 'runner', 'tools2');
const tempDir = path.join(__dirname, 'runner', 'temp2');
import * as setup from '../src/setup-dotnet'; import * as setup from '../src/setup-dotnet';
import * as dotnetInstaller from '../src/installer'; import {IS_WINDOWS} from '../src/utils';
import {IS_LINUX} from '../src/utils';
const IS_WINDOWS = process.platform === 'win32'; let toolDir: string;
if (IS_WINDOWS) {
toolDir = path.join(process.env['PROGRAMFILES'] + '', 'dotnet');
} else if (IS_LINUX) {
toolDir = '/usr/share/dotnet';
} else {
toolDir = path.join(process.env['HOME'] + '', '.dotnet');
}
const tempDir = path.join(__dirname, 'runner', 'temp2');
describe('setup-dotnet tests', () => { describe('setup-dotnet tests', () => {
let getInputSpy = jest.spyOn(core, 'getInput');
let getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
let setOutputSpy = jest.spyOn(core, 'setOutput');
let inputs = {} as any;
beforeAll(async () => { beforeAll(async () => {
process.env.RUNNER_TOOL_CACHE = toolDir; process.env.RUNNER_TOOL_CACHE = toolDir;
process.env.DOTNET_INSTALL_DIR = toolDir; process.env.DOTNET_INSTALL_DIR = toolDir;
process.env.RUNNER_TEMP = tempDir; process.env.RUNNER_TEMP = tempDir;
process.env['INPUT_INCLUDE-PRERELEASE'] = 'false'; try {
await io.rmRF(toolDir); await io.rmRF(`${toolDir}/*`);
await io.rmRF(tempDir); await io.rmRF(`${tempDir}/*`);
}); } catch (err) {
console.log(err.message);
console.log('Failed to remove test directories');
}
}, 30000);
afterEach(async () => { afterEach(async () => {
try { try {
await io.rmRF(path.join(process.cwd(), 'global.json')); await io.rmRF(path.join(process.cwd(), 'global.json'));
await io.rmRF(toolDir); await io.rmRF(`${toolDir}/*`);
await io.rmRF(tempDir); await io.rmRF(`${tempDir}/*`);
} catch { } catch (err) {
console.log(err.message);
console.log('Failed to remove test directories'); console.log('Failed to remove test directories');
} }
}, 30000); }, 30000);
@ -47,25 +67,32 @@ describe('setup-dotnet tests', () => {
} }
}, 400000); }, 400000);
it('Acquires version of dotnet from global.json with rollForward option, install the latest patch', async () => { it("Sets output with the latest installed by action version if global.json file isn't specified", async () => {
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
getMultilineInputSpy.mockImplementation(input => inputs[input]);
await setup.run();
expect(setOutputSpy).toBeCalledWith('dotnet-version', '6.0.401');
}, 400000);
it("Sets output with the version specified in global.json, if it's present", async () => {
const globalJsonPath = path.join(process.cwd(), 'global.json'); const globalJsonPath = path.join(process.cwd(), 'global.json');
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version":"3.1.201",${os.EOL}"rollForward":"latestFeature"${os.EOL}}${os.EOL}}`; const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.0.103"${os.EOL}}${os.EOL}}`;
if (!fs.existsSync(globalJsonPath)) { if (!fs.existsSync(globalJsonPath)) {
fs.writeFileSync(globalJsonPath, jsonContents); fs.writeFileSync(globalJsonPath, jsonContents);
} }
const version = '3.1'; inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
const installer = new dotnetInstaller.DotnetCoreInstaller(version); inputs['global-json-file'] = './global.json';
const patchVersion = await installer.resolveVersion(
new dotnetInstaller.DotNetVersionInfo(version) getMultilineInputSpy.mockImplementation(input => inputs[input]);
);
getInputSpy.mockImplementation(input => inputs[input]);
await setup.run(); await setup.run();
expect(fs.existsSync(path.join(toolDir, 'sdk', patchVersion))).toBe(true); expect(setOutputSpy).toBeCalledWith('dotnet-version', '3.0.103');
if (IS_WINDOWS) {
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
} else {
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
}
}, 400000); }, 400000);
}); });

View File

@ -1,17 +1,7 @@
#!/bin/bash #!/bin/bash
if [[ "$(git status --porcelain)" != "" ]]; then if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
echo ---------------------------------------- echo "Detected uncommitted changes after build. See status below:"
echo git status
echo ----------------------------------------
git status
echo ----------------------------------------
echo git diff
echo ----------------------------------------
git diff git diff
echo ----------------------------------------
echo Troubleshooting
echo ----------------------------------------
echo "::error::Unstaged changes detected. Locally try running: git clean -ffdx && npm ci && npm run pre-checkin"
exit 1 exit 1
fi fi

View File

@ -1,91 +0,0 @@
import each from 'jest-each';
import * as installer from '../src/installer';
describe('version tests', () => {
each(['3.1.999', '3.1.101-preview.3']).test(
"Exact version '%s' should be the same",
vers => {
let versInfo = new installer.DotNetVersionInfo(vers);
expect(versInfo.isExactVersion()).toBe(true);
expect(versInfo.version()).toBe(vers);
}
);
each([
['3.x', '3.x'],
['3.*', '3.*'],
['3.1.x', '3.1'],
['1.1.*', '1.1'],
['2.0', '2.0']
]).test("Generic version '%s' should be '%s'", (vers, resVers) => {
let versInfo = new installer.DotNetVersionInfo(vers);
expect(versInfo.isExactVersion()).toBe(false);
expect(versInfo.version()).toBe(resVers);
});
each([
'',
'.',
'..',
' . ',
'. ',
' .',
' . . ',
' .. ',
' . ',
'-1.-1',
'-1',
'-1.-1.-1',
'..3',
'1..3',
'1..',
'.2.3',
'.2.x',
'1',
'*.*.1',
'*.1',
'*.',
'1.2.',
'1.2.-abc',
'a.b',
'a.b.c',
'a.b.c-preview',
' 0 . 1 . 2 '
]).test("Malformed version '%s' should throw", vers => {
expect(() => new installer.DotNetVersionInfo(vers)).toThrow();
});
each([
['3.1.x', '3.1.'],
['3.1.*', '3.1.'],
['3.1', '3.1.'],
['5.0.0-preview.6', '5.0.0-preview.6'],
['3.1.201', '3.1.201']
]).test(
"Resolving version '%s' as '%s'",
async (input, expectedVersion) => {
const dotnetInstaller = new installer.DotnetCoreInstaller(input);
let versInfo = await dotnetInstaller.resolveVersion(
new installer.DotNetVersionInfo(input)
);
console.log(versInfo);
expect(versInfo.startsWith(expectedVersion));
},
100000
);
it('Resolving a nonexistent generic version fails', async () => {
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
try {
await dotnetInstaller.resolveVersion(
new installer.DotNetVersionInfo('999.1.x')
);
fail();
} catch {
expect(true);
}
}, 100000);
});

View File

@ -6,7 +6,9 @@ branding:
color: green color: green
inputs: inputs:
dotnet-version: dotnet-version:
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x' description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x, 3.x'
dotnet-quality:
description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.'
global-json-file: global-json-file:
description: 'Optional global.json location, if your global.json isn''t located in the root of the repo.' description: 'Optional global.json location, if your global.json isn''t located in the root of the repo.'
source-url: source-url:
@ -15,10 +17,9 @@ inputs:
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url' 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: config-file:
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.' description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
include-prerelease: outputs:
description: 'Whether prerelease versions should be matched with non-exact versions (for example 5.0.0-preview.6 being matched by 5, 5.0, 5.x or 5.0.x). Defaults to false if not provided.' dotnet-version:
required: False description: 'Contains the installed by action .NET SDK version for reuse.'
default: 'false'
runs: runs:
using: 'node16' using: 'node16'
main: 'dist/index.js' main: 'dist/index.js'

11157
dist/index.js vendored

File diff suppressed because it is too large Load Diff

412
package-lock.json generated
View File

@ -1,22 +1,21 @@
{ {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "2.1.0", "version": "3.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "2.1.0", "version": "3.0.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.6.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4", "@actions/exec": "^1.0.4",
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/http-client": "^1.0.8", "@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"fast-xml-parser": "^3.15.1", "fast-xml-parser": "^4.0.10",
"semver": "^6.3.0", "semver": "^6.3.0"
"xmlbuilder": "^13.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
@ -26,32 +25,25 @@
"husky": "^8.0.1", "husky": "^8.0.1",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^2.7.1",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "^3.9.7", "typescript": "^4.8.4",
"wget-improved": "^3.2.1" "wget-improved": "^3.2.1"
} }
}, },
"node_modules/@actions/core": { "node_modules/@actions/core": {
"version": "1.6.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": { "dependencies": {
"@actions/http-client": "^1.0.11" "@actions/http-client": "^2.0.1",
} "uuid": "^8.3.2"
},
"node_modules/@actions/core/node_modules/@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"dependencies": {
"tunnel": "0.0.6"
} }
}, },
"node_modules/@actions/exec": { "node_modules/@actions/exec": {
"version": "1.0.4", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==", "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"dependencies": { "dependencies": {
"@actions/io": "^1.0.1" "@actions/io": "^1.0.1"
} }
@ -66,25 +58,17 @@
} }
}, },
"node_modules/@actions/http-client": { "node_modules/@actions/http-client": {
"version": "1.0.8", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"dependencies": { "dependencies": {
"tunnel": "0.0.6" "tunnel": "^0.0.6"
}
},
"node_modules/@actions/http-client/node_modules/tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
"engines": {
"node": ">=0.6.11 <=0.7.0 || >=0.7.3"
} }
}, },
"node_modules/@actions/io": { "node_modules/@actions/io": {
"version": "1.0.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" "integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
}, },
"node_modules/@babel/code-frame": { "node_modules/@babel/code-frame": {
"version": "7.15.8", "version": "7.15.8",
@ -928,15 +912,6 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
} }
}, },
"node_modules/@jest/types/node_modules/@types/yargs": {
"version": "16.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
"integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"dependencies": {
"@types/yargs-parser": "*"
}
},
"node_modules/@octokit/endpoint": { "node_modules/@octokit/endpoint": {
"version": "5.3.5", "version": "5.3.5",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.5.tgz", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.3.5.tgz",
@ -1176,66 +1151,6 @@
"pretty-format": "^27.0.0" "pretty-format": "^27.0.0"
} }
}, },
"node_modules/@types/jest/node_modules/ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/@types/jest/node_modules/diff-sequences": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"dev": true,
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-diff": {
"version": "27.2.5",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz",
"integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==",
"dev": true,
"dependencies": {
"chalk": "^4.0.0",
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.0.6",
"pretty-format": "^27.2.5"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/@types/jest/node_modules/jest-get-type": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
"integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true,
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/@types/jest/node_modules/pretty-format": {
"version": "27.2.5",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz",
"integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==",
"dev": true,
"dependencies": {
"@jest/types": "^27.2.5",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
},
"engines": {
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
}
},
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "16.11.25", "version": "16.11.25",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.25.tgz",
@ -1623,14 +1538,20 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001265", "version": "1.0.30001382",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz",
"integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", "integrity": "sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==",
"dev": true, "dev": true,
"funding": { "funding": [
"type": "opencollective", {
"url": "https://opencollective.com/browserslist" "type": "opencollective",
} "url": "https://opencollective.com/browserslist"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
}
]
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "4.1.0", "version": "4.1.0",
@ -2070,12 +1991,14 @@
"dev": true "dev": true
}, },
"node_modules/fast-xml-parser": { "node_modules/fast-xml-parser": {
"version": "3.17.4", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.17.4.tgz", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.10.tgz",
"integrity": "sha512-qudnQuyYBgnvzf5Lj/yxMcf4L9NcVWihXJg7CiU1L+oUCq8MUnFEfH2/nXR/W5uq+yvUN1h7z6s7vs2v1WkL1A==", "integrity": "sha512-mYMMIk7Ho1QOiedyvafdyPamn1Vlda+5n95lcn0g79UiCQoLQ2xfPQ8m3pcxBMpVaftYXtoIE2wrNTjmLQnnkg==",
"hasInstallScript": true, "dependencies": {
"strnum": "^1.0.5"
},
"bin": { "bin": {
"xml2js": "cli.js" "fxparser": "src/cli/cli.js"
}, },
"funding": { "funding": {
"type": "paypal", "type": "paypal",
@ -3285,36 +3208,6 @@
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
} }
}, },
"node_modules/jest-util/node_modules/ci-info": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
"integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
"dev": true
},
"node_modules/jest-util/node_modules/is-ci": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
"integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
"dev": true,
"dependencies": {
"ci-info": "^3.1.1"
},
"bin": {
"is-ci": "bin.js"
}
},
"node_modules/jest-util/node_modules/picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true,
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/jest-validate": { "node_modules/jest-validate": {
"version": "27.2.5", "version": "27.2.5",
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.5.tgz", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.2.5.tgz",
@ -3991,15 +3884,18 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "1.19.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
"engines": { "engines": {
"node": ">=4" "node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
} }
}, },
"node_modules/pretty-format": { "node_modules/pretty-format": {
@ -4312,6 +4208,11 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/strnum": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
},
"node_modules/supports-color": { "node_modules/supports-color": {
"version": "7.1.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
@ -4487,15 +4388,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/ts-jest/node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/tunnel": { "node_modules/tunnel": {
"version": "0.0.6", "version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
@ -4547,9 +4439,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "3.9.7", "version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -4576,6 +4468,14 @@
"node": ">= 4.0.0" "node": ">= 4.0.0"
} }
}, },
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/v8-to-istanbul": { "node_modules/v8-to-istanbul": {
"version": "8.1.0", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz",
@ -4775,14 +4675,6 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true "dev": true
}, },
"node_modules/xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==",
"engines": {
"node": ">=6.0"
}
},
"node_modules/xmlchars": { "node_modules/xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
@ -4834,27 +4726,18 @@
}, },
"dependencies": { "dependencies": {
"@actions/core": { "@actions/core": {
"version": "1.6.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.6.0.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-NB1UAZomZlCV/LmJqkLhNTqtKfFXJZAUPcfl/zqG7EfsQdeUJtaWO98SGbuQ3pydJ3fHl2CvI/51OKYlCYYcaw==", "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"requires": { "requires": {
"@actions/http-client": "^1.0.11" "@actions/http-client": "^2.0.1",
}, "uuid": "^8.3.2"
"dependencies": {
"@actions/http-client": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.11.tgz",
"integrity": "sha512-VRYHGQV1rqnROJqdMvGUbY/Kn8vriQe/F9HR2AlYHzmKuM/p3kjNuXhmdBfcVgsvRWTz5C5XW5xvndZrVBuAYg==",
"requires": {
"tunnel": "0.0.6"
}
}
} }
}, },
"@actions/exec": { "@actions/exec": {
"version": "1.0.4", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.4.tgz", "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
"integrity": "sha512-4DPChWow9yc9W3WqEbUj8Nr86xkpyE29ZzWjXucHItclLbEW6jr80Zx4nqv18QL6KK65+cifiQZXvnqgTV6oHw==", "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
"requires": { "requires": {
"@actions/io": "^1.0.1" "@actions/io": "^1.0.1"
} }
@ -4869,24 +4752,17 @@
} }
}, },
"@actions/http-client": { "@actions/http-client": {
"version": "1.0.8", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "^0.0.6"
},
"dependencies": {
"tunnel": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="
}
} }
}, },
"@actions/io": { "@actions/io": {
"version": "1.0.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
"integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" "integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
}, },
"@babel/code-frame": { "@babel/code-frame": {
"version": "7.15.8", "version": "7.15.8",
@ -5534,17 +5410,6 @@
"@types/node": "*", "@types/node": "*",
"@types/yargs": "^16.0.0", "@types/yargs": "^16.0.0",
"chalk": "^4.0.0" "chalk": "^4.0.0"
},
"dependencies": {
"@types/yargs": {
"version": "16.0.4",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
"integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
"dev": true,
"requires": {
"@types/yargs-parser": "*"
}
}
} }
}, },
"@octokit/endpoint": { "@octokit/endpoint": {
@ -5775,50 +5640,6 @@
"requires": { "requires": {
"jest-diff": "^27.0.0", "jest-diff": "^27.0.0",
"pretty-format": "^27.0.0" "pretty-format": "^27.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"dev": true
},
"diff-sequences": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz",
"integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==",
"dev": true
},
"jest-diff": {
"version": "27.2.5",
"resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz",
"integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"diff-sequences": "^27.0.6",
"jest-get-type": "^27.0.6",
"pretty-format": "^27.2.5"
}
},
"jest-get-type": {
"version": "27.0.6",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz",
"integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==",
"dev": true
},
"pretty-format": {
"version": "27.2.5",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz",
"integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==",
"dev": true,
"requires": {
"@jest/types": "^27.2.5",
"ansi-regex": "^5.0.1",
"ansi-styles": "^5.0.0",
"react-is": "^17.0.1"
}
}
} }
}, },
"@types/node": { "@types/node": {
@ -6128,9 +5949,9 @@
"dev": true "dev": true
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001265", "version": "1.0.30001382",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz",
"integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", "integrity": "sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==",
"dev": true "dev": true
}, },
"chalk": { "chalk": {
@ -6473,9 +6294,12 @@
"dev": true "dev": true
}, },
"fast-xml-parser": { "fast-xml-parser": {
"version": "3.17.4", "version": "4.0.10",
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.17.4.tgz", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.0.10.tgz",
"integrity": "sha512-qudnQuyYBgnvzf5Lj/yxMcf4L9NcVWihXJg7CiU1L+oUCq8MUnFEfH2/nXR/W5uq+yvUN1h7z6s7vs2v1WkL1A==" "integrity": "sha512-mYMMIk7Ho1QOiedyvafdyPamn1Vlda+5n95lcn0g79UiCQoLQ2xfPQ8m3pcxBMpVaftYXtoIE2wrNTjmLQnnkg==",
"requires": {
"strnum": "^1.0.5"
}
}, },
"fb-watchman": { "fb-watchman": {
"version": "2.0.1", "version": "2.0.1",
@ -7410,29 +7234,6 @@
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"is-ci": "^3.0.0", "is-ci": "^3.0.0",
"picomatch": "^2.2.3" "picomatch": "^2.2.3"
},
"dependencies": {
"ci-info": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz",
"integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==",
"dev": true
},
"is-ci": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz",
"integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==",
"dev": true,
"requires": {
"ci-info": "^3.1.1"
}
},
"picomatch": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
"integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
"dev": true
}
} }
}, },
"jest-validate": { "jest-validate": {
@ -7926,9 +7727,9 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "1.19.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true "dev": true
}, },
"pretty-format": { "pretty-format": {
@ -8170,6 +7971,11 @@
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true "dev": true
}, },
"strnum": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
},
"supports-color": { "supports-color": {
"version": "7.1.0", "version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
@ -8287,12 +8093,6 @@
"requires": { "requires": {
"lru-cache": "^6.0.0" "lru-cache": "^6.0.0"
} }
},
"yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"dev": true
} }
} }
}, },
@ -8332,9 +8132,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.9.7", "version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true "dev": true
}, },
"universal-user-agent": { "universal-user-agent": {
@ -8351,6 +8151,11 @@
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"dev": true "dev": true
}, },
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"v8-to-istanbul": { "v8-to-istanbul": {
"version": "8.1.0", "version": "8.1.0",
"resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz",
@ -8502,11 +8307,6 @@
"integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
"dev": true "dev": true
}, },
"xmlbuilder": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-13.0.2.tgz",
"integrity": "sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ=="
},
"xmlchars": { "xmlchars": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "2.1.0", "version": "3.0.2",
"private": true, "private": true,
"description": "setup dotnet action", "description": "setup dotnet action",
"main": "lib/setup-dotnet.js", "main": "lib/setup-dotnet.js",
@ -9,7 +9,7 @@
"format": "prettier --write **/*.ts", "format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts", "format-check": "prettier --check **/*.ts",
"prepare": "husky install", "prepare": "husky install",
"test": "jest", "test": "jest --coverage --config ./jest.config.js",
"update-installers": "nwget https://dot.net/v1/dotnet-install.ps1 -O externals/install-dotnet.ps1 && nwget https://dot.net/v1/dotnet-install.sh -O externals/install-dotnet.sh" "update-installers": "nwget https://dot.net/v1/dotnet-install.ps1 -O externals/install-dotnet.ps1 && nwget https://dot.net/v1/dotnet-install.sh -O externals/install-dotnet.sh"
}, },
"repository": { "repository": {
@ -24,14 +24,13 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.6.0", "@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4", "@actions/exec": "^1.0.4",
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/http-client": "^1.0.8", "@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.2", "@actions/io": "^1.0.2",
"fast-xml-parser": "^3.15.1", "fast-xml-parser": "^4.0.10",
"semver": "^6.3.0", "semver": "^6.3.0"
"xmlbuilder": "^13.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^27.0.2", "@types/jest": "^27.0.2",
@ -41,9 +40,9 @@
"husky": "^8.0.1", "husky": "^8.0.1",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^2.7.1",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "^3.9.7", "typescript": "^4.8.4",
"wget-improved": "^3.2.1" "wget-improved": "^3.2.1"
}, },
"jest": { "jest": {

View File

@ -2,9 +2,7 @@ import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as github from '@actions/github'; import * as github from '@actions/github';
import * as xmlbuilder from 'xmlbuilder'; import {XMLParser, XMLBuilder} from 'fast-xml-parser';
import * as xmlParser from 'fast-xml-parser';
import {ProcessEnvOptions} from 'child_process';
export function configAuthentication( export function configAuthentication(
feedUrl: string, feedUrl: string,
@ -47,10 +45,9 @@ function writeFeedToFile(
existingFileLocation: string, existingFileLocation: string,
tempFileLocation: string tempFileLocation: string
) { ) {
console.log( core.info(
`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}` `dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`
); );
let xml: xmlbuilder.XMLElement;
let sourceKeys: string[] = []; let sourceKeys: string[] = [];
let owner: string = core.getInput('owner'); let owner: string = core.getInput('owner');
let sourceUrl: string = feedUrl; let sourceUrl: string = feedUrl;
@ -58,7 +55,7 @@ function writeFeedToFile(
owner = github.context.repo.owner; owner = github.context.repo.owner;
} }
if (!process.env.NUGET_AUTH_TOKEN || process.env.NUGET_AUTH_TOKEN == '') { if (!process.env.NUGET_AUTH_TOKEN) {
throw new Error( throw new Error(
'The NUGET_AUTH_TOKEN environment variable was not provided. In this step, add the following: \r\nenv:\r\n NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}' 'The NUGET_AUTH_TOKEN environment variable was not provided. In this step, add the following: \r\nenv:\r\n NUGET_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}'
); );
@ -67,64 +64,90 @@ function writeFeedToFile(
if (fs.existsSync(existingFileLocation)) { if (fs.existsSync(existingFileLocation)) {
// get key from existing NuGet.config so NuGet/dotnet can match credentials // get key from existing NuGet.config so NuGet/dotnet can match credentials
const curContents: string = fs.readFileSync(existingFileLocation, 'utf8'); const curContents: string = fs.readFileSync(existingFileLocation, 'utf8');
var json = xmlParser.parse(curContents, {ignoreAttributes: false});
if (typeof json.configuration == 'undefined') { const parserOptions = {
ignoreAttributes: false
};
const parser = new XMLParser(parserOptions);
const json = parser.parse(curContents);
if (typeof json.configuration === 'undefined') {
throw new Error(`The provided NuGet.config seems invalid.`); throw new Error(`The provided NuGet.config seems invalid.`);
} }
if (typeof json.configuration.packageSources != 'undefined') { if (json.configuration?.packageSources?.add) {
if (typeof json.configuration.packageSources.add != 'undefined') { const packageSources = json.configuration.packageSources.add;
// file has at least one <add>
if (typeof json.configuration.packageSources.add[0] == 'undefined') { if (Array.isArray(packageSources)) {
// file has only one <add> packageSources.forEach(source => {
if ( const value = source['@_value'];
json.configuration.packageSources.add['@_value'] core.debug(`source '${value}'`);
.toLowerCase() if (value.toLowerCase().includes(feedUrl.toLowerCase())) {
.includes(feedUrl.toLowerCase()) const key = source['@_key'];
) {
let key = json.configuration.packageSources.add['@_key'];
sourceKeys.push(key); sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`); core.debug(`Found a URL with key ${key}`);
} }
} else { });
// file has 2+ <add> } else {
for ( if (
let i = 0; packageSources['@_value']
i < json.configuration.packageSources.add.length; .toLowerCase()
i++ .includes(feedUrl.toLowerCase())
) { ) {
const source = json.configuration.packageSources.add[i]; const key = packageSources['@_key'];
const value = source['@_value']; sourceKeys.push(key);
core.debug(`source '${value}'`); core.debug(`Found a URL with key ${key}`);
if (value.toLowerCase().includes(feedUrl.toLowerCase())) {
let key = source['@_key'];
sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`);
}
}
} }
} }
} }
} }
xml = xmlbuilder const xmlSource: any[] = [
.create('configuration') {
.ele('config') '?xml': [
.ele('add', {key: 'defaultPushSource', value: sourceUrl}) {
.up() '#text': ''
.up(); }
],
':@': {
'@_version': '1.0'
}
},
{
configuration: [
{
config: [
{
add: [],
':@': {
'@_key': 'defaultPushSource',
'@_value': sourceUrl
}
}
]
}
]
}
];
if (sourceKeys.length == 0) { if (!sourceKeys.length) {
let keystring = 'Source'; let keystring = 'Source';
xml = xml
.ele('packageSources') xmlSource[1].configuration.push({
.ele('add', {key: keystring, value: sourceUrl}) packageSources: [
.up() {
.up(); add: [],
':@': {
'@_key': keystring,
'@_value': sourceUrl
}
}
]
});
sourceKeys.push(keystring); sourceKeys.push(keystring);
} }
xml = xml.ele('packageSourceCredentials');
const packageSourceCredentials: any[] = [];
sourceKeys.forEach(key => { sourceKeys.forEach(key => {
if (!isValidKey(key)) { if (!isValidKey(key)) {
throw new Error( throw new Error(
@ -132,24 +155,42 @@ function writeFeedToFile(
); );
} }
xml = xml packageSourceCredentials.push({
.ele(key) [key]: [
.ele('add', {key: 'Username', value: owner}) {
.up() add: [],
.ele('add', { ':@': {
key: 'ClearTextPassword', '@_key': 'Username',
value: process.env.NUGET_AUTH_TOKEN '@_value': owner
}) }
.up() },
.up(); {
add: [],
':@': {
'@_key': 'ClearTextPassword',
'@_value': process.env.NUGET_AUTH_TOKEN
}
}
]
});
}); });
// If NuGet fixes itself such that on Linux it can look for environment variables in the config file (it doesn't seem to work today), xmlSource[1].configuration.push({
// use this for the value above packageSourceCredentials
// process.platform == 'win32' });
// ? '%NUGET_AUTH_TOKEN%'
// : '$NUGET_AUTH_TOKEN' const xmlBuilderOptions = {
format: true,
ignoreAttributes: false,
preserveOrder: true,
allowBooleanAttributes: true,
suppressBooleanAttributes: true,
suppressEmptyNode: true
};
const builder = new XMLBuilder(xmlBuilderOptions);
const output = builder.build(xmlSource).trim();
var output = xml.end({pretty: true});
fs.writeFileSync(tempFileLocation, output); fs.writeFileSync(tempFileLocation, output);
} }

View File

@ -2,303 +2,262 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as exec from '@actions/exec'; import * as exec from '@actions/exec';
import * as io from '@actions/io'; import * as io from '@actions/io';
import hc = require('@actions/http-client'); import * as hc from '@actions/http-client';
import {chmodSync} from 'fs'; import {chmodSync} from 'fs';
import * as path from 'path'; import {readdir} from 'fs/promises';
import {ExecOptions} from '@actions/exec/lib/interfaces'; import path from 'path';
import * as semver from 'semver'; import os from 'os';
import semver from 'semver';
import {IS_LINUX, IS_WINDOWS} from './utils';
import {QualityOptions} from './setup-dotnet';
const IS_WINDOWS = process.platform === 'win32'; export interface DotnetVersion {
type: string;
/** value: string;
* Represents the inputted version information qualityFlag: boolean;
*/
export class DotNetVersionInfo {
public inputVersion: string;
private fullversion: string;
private isExactVersionSet: boolean = false;
constructor(version: string) {
this.inputVersion = version;
// Check for exact match
if (semver.valid(semver.clean(version) || '') != null) {
this.fullversion = semver.clean(version) as string;
this.isExactVersionSet = true;
return;
}
const parts: string[] = version.split('.');
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
if (parts.length == 3 && parts[2] !== 'x' && parts[2] !== '*') {
this.throwInvalidVersionFormat();
}
const major = this.getVersionNumberOrThrow(parts[0]);
const minor = ['x', '*'].includes(parts[1])
? parts[1]
: this.getVersionNumberOrThrow(parts[1]);
this.fullversion = major + '.' + minor;
}
private getVersionNumberOrThrow(input: string): number {
try {
if (!input || input.trim() === '') this.throwInvalidVersionFormat();
let number = Number(input);
if (Number.isNaN(number) || number < 0) this.throwInvalidVersionFormat();
return number;
} catch {
this.throwInvalidVersionFormat();
return -1;
}
}
private throwInvalidVersionFormat() {
throw new Error(
'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*'
);
}
/**
* If true exacatly one version should be resolved
*/
public isExactVersion(): boolean {
return this.isExactVersionSet;
}
public version(): string {
return this.fullversion;
}
} }
export class DotnetCoreInstaller { export class DotnetVersionResolver {
constructor(version: string, includePrerelease: boolean = false) { private inputVersion: string;
this.version = version; private resolvedArgument: DotnetVersion;
this.includePrerelease = includePrerelease;
constructor(version: string) {
this.inputVersion = version.trim();
this.resolvedArgument = {type: '', value: '', qualityFlag: false};
} }
public async installDotnet() { private async resolveVersionInput(): Promise<void> {
let output = ''; if (!semver.validRange(this.inputVersion)) {
let resultCode = 0; throw new Error(
`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x`
);
}
if (semver.valid(this.inputVersion)) {
this.resolvedArgument.type = 'version';
this.resolvedArgument.value = this.inputVersion;
} else {
const [major, minor] = this.inputVersion.split('.');
let calculatedVersion = await this.resolveVersion( if (this.isNumericTag(major)) {
new DotNetVersionInfo(this.version) this.resolvedArgument.type = 'channel';
); if (this.isNumericTag(minor)) {
this.resolvedArgument.value = `${major}.${minor}`;
var envVariables: {[key: string]: string} = {}; } else {
for (let key in process.env) { const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
if (process.env[key]) { allowRetries: true,
let value: any = process.env[key]; maxRetries: 3
envVariables[key] = value; });
this.resolvedArgument.value = await this.getLatestVersion(
httpClient,
[major, minor]
);
}
} }
this.resolvedArgument.qualityFlag = +major >= 6 ? true : false;
}
}
private isNumericTag(versionTag): boolean {
return /^\d+$/.test(versionTag);
}
public async createDotNetVersion(): Promise<{
type: string;
value: string;
qualityFlag: boolean;
}> {
await this.resolveVersionInput();
if (!this.resolvedArgument.type) {
return this.resolvedArgument;
} }
if (IS_WINDOWS) { if (IS_WINDOWS) {
let escapedScript = path this.resolvedArgument.type =
.join(__dirname, '..', 'externals', 'install-dotnet.ps1') this.resolvedArgument.type === 'channel' ? '-Channel' : '-Version';
.replace(/'/g, "''");
let command = `& '${escapedScript}'`;
if (calculatedVersion) {
command += ` -Version ${calculatedVersion}`;
}
if (process.env['https_proxy'] != null) {
command += ` -ProxyAddress ${process.env['https_proxy']}`;
}
// This is not currently an option
if (process.env['no_proxy'] != null) {
command += ` -ProxyBypassList ${process.env['no_proxy']}`;
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
const powershellPath =
(await io.which('pwsh', false)) || (await io.which('powershell', true));
var options: ExecOptions = {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
},
env: envVariables
};
resultCode = await exec.exec(
`"${powershellPath}"`,
[
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command',
command
],
options
);
} else { } else {
let escapedScript = path this.resolvedArgument.type =
.join(__dirname, '..', 'externals', 'install-dotnet.sh') this.resolvedArgument.type === 'channel' ? '--channel' : '--version';
.replace(/'/g, "''");
chmodSync(escapedScript, '777');
const scriptPath = await io.which(escapedScript, true);
let scriptArguments: string[] = [];
if (calculatedVersion) {
scriptArguments.push('--version', calculatedVersion);
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
resultCode = await exec.exec(`"${scriptPath}"`, scriptArguments, {
listeners: {
stdout: (data: Buffer) => {
output += data.toString();
}
},
env: envVariables
});
}
if (resultCode != 0) {
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
} }
return this.resolvedArgument;
} }
static addToPath() { private async getLatestVersion(
if (process.env['DOTNET_INSTALL_DIR']) {
core.addPath(process.env['DOTNET_INSTALL_DIR']);
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
} else {
if (IS_WINDOWS) {
// This is the default set in install-dotnet.ps1
core.addPath(
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
);
core.exportVariable(
'DOTNET_ROOT',
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
);
} else {
// This is the default set in install-dotnet.sh
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
core.exportVariable(
'DOTNET_ROOT',
path.join(process.env['HOME'] + '', '.dotnet')
);
}
}
console.log(process.env['PATH']);
}
// versionInfo - versionInfo of the SDK/Runtime
async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
if (versionInfo.isExactVersion()) {
return versionInfo.version();
}
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
allowRetries: true,
maxRetries: 3
});
const releasesJsonUrl: string = await this.getReleasesJsonUrl(
httpClient,
versionInfo.version().split('.')
);
const releasesResponse = await httpClient.getJson<any>(releasesJsonUrl);
const releasesResult = releasesResponse.result || {};
let releasesInfo: any[] = releasesResult['releases'];
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
return (
semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version(), {
includePrerelease: this.includePrerelease
}) ||
semver.satisfies(
releaseInfo['sdk']['version-display'],
versionInfo.version(),
{
includePrerelease: this.includePrerelease
}
)
);
});
// Exclude versions that are newer than the latest if using not exact
let latestSdk: string = releasesResult['latest-sdk'];
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
semver.lte(releaseInfo['sdk']['version'], latestSdk, {
includePrerelease: this.includePrerelease
})
);
// Sort for latest version
releasesInfo = releasesInfo.sort((a, b) =>
semver.rcompare(a['sdk']['version'], b['sdk']['version'], {
includePrerelease: this.includePrerelease
})
);
if (releasesInfo.length == 0) {
throw new Error(
`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`
);
}
let release = releasesInfo[0];
return release['sdk']['version'];
}
private async getReleasesJsonUrl(
httpClient: hc.HttpClient, httpClient: hc.HttpClient,
versionParts: string[] versionParts: string[]
): Promise<string> { ): Promise<string> {
const response = await httpClient.getJson<any>(DotNetCoreIndexUrl); const response = await httpClient.getJson<any>(
DotnetVersionResolver.DotNetCoreIndexUrl
);
const result = response.result || {}; const result = response.result || {};
let releasesInfo: any[] = result['releases-index']; let releasesInfo: any[] = result['releases-index'];
releasesInfo = releasesInfo.filter((info: any) => { let releaseInfo = releasesInfo.find(info => {
// channel-version is the first 2 elements of the version (e.g. 2.1), filter out versions that don't match 2.1.x. let sdkParts: string[] = info['channel-version'].split('.');
const sdkParts: string[] = info['channel-version'].split('.'); return sdkParts[0] === versionParts[0];
if (
versionParts.length >= 2 &&
!(versionParts[1] == 'x' || versionParts[1] == '*')
) {
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
}
return versionParts[0] == sdkParts[0];
}); });
if (releasesInfo.length === 0) { if (!releaseInfo) {
throw new Error( throw new Error(
`Could not find info for version ${versionParts.join( `Could not find info for version ${versionParts.join('.')} at ${
'.' DotnetVersionResolver.DotNetCoreIndexUrl
)} at ${DotNetCoreIndexUrl}` }`
); );
} }
const releaseInfo = releasesInfo[0]; return releaseInfo['channel-version'];
if (releaseInfo['support-phase'] === 'eol') {
core.warning(
`${releaseInfo['product']} ${releaseInfo['channel-version']} is no longer supported and will not receive security updates in the future. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy.`
);
}
return releaseInfo['releases.json'];
} }
private version: string; static DotNetCoreIndexUrl: string =
private includePrerelease: boolean; 'https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json';
} }
const DotNetCoreIndexUrl: string = export class DotnetCoreInstaller {
'https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json'; private version: string;
private quality: QualityOptions;
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;
}
}
}
constructor(version: string, quality: QualityOptions) {
this.version = version;
this.quality = quality;
}
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(
`'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A and A.x formats where the major tag is higher than 5. You specified: ${this.version}. 'dotnet-quality' input is ignored.`
);
}
}
public async installDotnet(): Promise<string> {
const windowsDefaultOptions = [
'-NoLogo',
'-Sta',
'-NoProfile',
'-NonInteractive',
'-ExecutionPolicy',
'Unrestricted',
'-Command'
];
const scriptName = IS_WINDOWS ? 'install-dotnet.ps1' : 'install-dotnet.sh';
const escapedScript = path
.join(__dirname, '..', 'externals', scriptName)
.replace(/'/g, "''");
let scriptArguments: string[];
let scriptPath = '';
const versionResolver = new DotnetVersionResolver(this.version);
const dotnetVersion = await versionResolver.createDotNetVersion();
if (IS_WINDOWS) {
scriptArguments = ['&', `'${escapedScript}'`];
if (dotnetVersion.type) {
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
}
if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments);
}
if (process.env['https_proxy'] != null) {
scriptArguments.push(`-ProxyAddress ${process.env['https_proxy']}`);
}
// This is not currently an option
if (process.env['no_proxy'] != null) {
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
}
scriptPath =
(await io.which('pwsh', false)) || (await io.which('powershell', true));
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
} else {
chmodSync(escapedScript, '777');
scriptPath = await io.which(escapedScript, true);
scriptArguments = [];
if (dotnetVersion.type) {
scriptArguments.push(dotnetVersion.type, dotnetVersion.value);
}
if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments);
}
}
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
const getExecOutputOptions = {
ignoreReturnCode: true,
env: process.env as {string: string}
};
const {exitCode, stdout} = await exec.getExecOutput(
`"${scriptPath}"`,
scriptArguments,
getExecOutputOptions
);
if (exitCode) {
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
}
return this.outputDotnetVersion(dotnetVersion.value);
}
private async outputDotnetVersion(version): Promise<string> {
const installationPath = process.env['DOTNET_INSTALL_DIR']!;
let versionsOnRunner: string[] = await readdir(
path.join(installationPath.replace(/'/g, ''), 'sdk')
);
let installedVersion = semver.maxSatisfying(versionsOnRunner, version, {
includePrerelease: true
})!;
return installedVersion;
}
}

View File

@ -1,9 +1,20 @@
import * as core from '@actions/core'; import * as core from '@actions/core';
import * as installer from './installer'; import {DotnetCoreInstaller} from './installer';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import path from 'path';
import semver from 'semver';
import * as auth from './authutil'; import * as auth from './authutil';
const qualityOptions = [
'daily',
'signed',
'validated',
'preview',
'ga'
] as const;
export type QualityOptions = typeof qualityOptions[number];
export async function run() { export async function run() {
try { try {
// //
@ -15,7 +26,8 @@ export async function run() {
// If a valid version still can't be identified, nothing will be installed. // If a valid version still can't be identified, nothing will be installed.
// Proxy, auth, (etc) are still set up, even if no version is identified // Proxy, auth, (etc) are still set up, even if no version is identified
// //
let versions = core.getMultilineInput('dotnet-version'); const versions = core.getMultilineInput('dotnet-version');
const installedDotnetVersions: string[] = [];
const globalJsonFileInput = core.getInput('global-json-file'); const globalJsonFileInput = core.getInput('global-json-file');
if (globalJsonFileInput) { if (globalJsonFileInput) {
@ -38,18 +50,22 @@ export async function run() {
} }
if (versions.length) { if (versions.length) {
const includePrerelease: boolean = core.getBooleanInput( const quality = core.getInput('dotnet-quality') as QualityOptions;
'include-prerelease'
); if (quality && !qualityOptions.includes(quality)) {
let dotnetInstaller!: installer.DotnetCoreInstaller; throw new Error(
for (const version of new Set<string>(versions)) { `${quality} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`
dotnetInstaller = new installer.DotnetCoreInstaller(
version,
includePrerelease
); );
await dotnetInstaller.installDotnet();
} }
installer.DotnetCoreInstaller.addToPath();
let dotnetInstaller: DotnetCoreInstaller;
const uniqueVersions = new Set<string>(versions);
for (const version of uniqueVersions) {
dotnetInstaller = new DotnetCoreInstaller(version, quality);
const installedVersion = await dotnetInstaller.installDotnet();
installedDotnetVersions.push(installedVersion);
}
DotnetCoreInstaller.addToPath();
} }
const sourceUrl: string = core.getInput('source-url'); const sourceUrl: string = core.getInput('source-url');
@ -58,8 +74,22 @@ export async function run() {
auth.configAuthentication(sourceUrl, configFile); auth.configAuthentication(sourceUrl, configFile);
} }
const comparisonRange: string = globalJsonFileInput
? versions[versions.length - 1]!
: '*';
const versionToOutput = semver.maxSatisfying(
installedDotnetVersions,
comparisonRange,
{
includePrerelease: true
}
);
core.setOutput('dotnet-version', versionToOutput);
const matchersPath = path.join(__dirname, '..', '.github'); const matchersPath = path.join(__dirname, '..', '.github');
console.log(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`); core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`);
} catch (error) { } catch (error) {
core.setFailed(error.message); core.setFailed(error.message);
} }

2
src/utils.ts Normal file
View File

@ -0,0 +1,2 @@
export const IS_WINDOWS = process.platform === 'win32';
export const IS_LINUX = process.platform === 'linux';

View File

@ -35,6 +35,7 @@
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */ /* Additional Checks */
"useUnknownInCatchVariables": false, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */