You've already forked setup-dotnet
mirror of
https://github.com/actions/setup-dotnet.git
synced 2025-07-13 10:30:32 +07:00
Compare commits
344 Commits
Author | SHA1 | Date | |
---|---|---|---|
aa983c550d | |||
b891376106 | |||
b05a3f26b3 | |||
5fdecd2063 | |||
38b49fb717 | |||
3cf3e230c1 | |||
83a1653fa3 | |||
898aa0ce4d | |||
2f028bc044 | |||
21cf89aa73 | |||
fefaa59d2e | |||
e8501859aa | |||
426d75d071 | |||
0f534f5829 | |||
fbdbede901 | |||
0bc43909e0 | |||
c5a57b219c | |||
6adeb768ce | |||
f425be78f5 | |||
fc8786b149 | |||
7d08dc7593 | |||
e0a32d6459 | |||
255362be61 | |||
50b46b3b1d | |||
e8ac21d503 | |||
a79ce57e6b | |||
180a15970f | |||
b72f430d36 | |||
559e47b01b | |||
7358a44590 | |||
34c30d0e81 | |||
5f570676c2 | |||
aa34a3ceaa | |||
12f70884d7 | |||
0318091611 | |||
f199d27aa1 | |||
660c25a321 | |||
4f6b2f576a | |||
920b830bd1 | |||
abdd14ee80 | |||
1d9f0dad5b | |||
2699274f6e | |||
ca579e0fb2 | |||
c82240598b | |||
926f442022 | |||
c41fd15071 | |||
0c8652569e | |||
3cf27f13bb | |||
ae8edb8fff | |||
82b2b40816 | |||
fe74f1cb7d | |||
e94d154672 | |||
fe67d2f8db | |||
023f7252a0 | |||
3f3ad54c0c | |||
e1d35446fe | |||
11aaa65761 | |||
13abe4777e | |||
aefe5b483f | |||
047f06d086 | |||
014f8c8384 | |||
80c862dc38 | |||
e21107efbd | |||
d8f1ab14a7 | |||
f05a62b1cc | |||
338d4e3bbf | |||
228eec3014 | |||
c483e03222 | |||
a35f420124 | |||
4214866121 | |||
0681939502 | |||
ba8a1f9c02 | |||
09d024bd02 | |||
8ae4c080ce | |||
c5d2f92cae | |||
069c35efca | |||
6a2cd88ae8 | |||
9984a6fa87 | |||
607fce577a | |||
501b34e8f6 | |||
b827fcce4d | |||
239baf3c5b | |||
4d4a70f4a5 | |||
70c3f4d098 | |||
9260643816 | |||
45c9f236cf | |||
6d6c7c9313 | |||
e753bbf2ff | |||
629365b26e | |||
942a0bea39 | |||
26db2473e9 | |||
467621733d | |||
bdd38d13dc | |||
1d2f8f9eaf | |||
354d280fa3 | |||
0ff311b0d0 | |||
bc65ba63d3 | |||
90642fa8c5 | |||
c7e7147fd3 | |||
cf081e76a2 | |||
4ca3c96b49 | |||
0705ef0281 | |||
a351d9ea84 | |||
cc76dfab99 | |||
857c316a9d | |||
1f2c90bb99 | |||
251997c37d | |||
bba8299c35 | |||
fd4e15fa44 | |||
95e7de77d1 | |||
52c3199a78 | |||
2d9def7067 | |||
df51eabf53 | |||
e4b2fcaa19 | |||
d45c10e6f7 | |||
4d1b6c2c63 | |||
5d7bc0454b | |||
792e988dae | |||
e5034212c9 | |||
0997db20d4 | |||
4cb4764ae2 | |||
d33e605efe | |||
f7747565a1 | |||
2f75d1de25 | |||
e6a9a96293 | |||
025aba53b2 | |||
37b00c4fc5 | |||
c2dac7f367 | |||
c5267f5e54 | |||
ba5e53c61d | |||
043fb8900f | |||
cb04ff8cb3 | |||
bac4044d91 | |||
d26ead4cf0 | |||
e81cd4d454 | |||
ee11c4faa4 | |||
8bf1fb6084 | |||
c0d4ad69d8 | |||
afe2daba1f | |||
fb09b12527 | |||
5cc895510b | |||
158737d5b1 | |||
fcf565ec50 | |||
f078482971 | |||
0fb87b12d2 | |||
4fe7a196b5 | |||
9283a8cf7a | |||
53d632b5c0 | |||
9211491ffb | |||
edfd7b3266 | |||
9744af7b74 | |||
7016f85f93 | |||
d292011f5d | |||
608ee757cf | |||
e54e706650 | |||
c20f59e04a | |||
13b852df87 | |||
f85bcda870 | |||
499789684c | |||
76ddd67c90 | |||
550702114f | |||
e3ce4164b3 | |||
463326422f | |||
547d075822 | |||
fc9265379f | |||
32c76e2669 | |||
8ca0cf75a1 | |||
7f88dbf08f | |||
af0ed6536b | |||
9dd9d27e57 | |||
44530e8569 | |||
5a3fa01c67 | |||
f2da928c08 | |||
fb9fd97b03 | |||
f0b9e4cf3f | |||
b66058b059 | |||
7323c4e7cb | |||
6eab455d72 | |||
b2cf6c7cd4 | |||
ff5b78971e | |||
e26fc623bc | |||
e974974b42 | |||
9969bca445 | |||
deee0f6246 | |||
33fad1d142 | |||
2c3efd1f04 | |||
f3822c3b02 | |||
5e45b4b591 | |||
b7b99f337e | |||
f92687c910 | |||
0067f023d2 | |||
9480036ff9 | |||
6b8ad2e725 | |||
078f7c4a73 | |||
13fd5bf191 | |||
26be14c4e1 | |||
8309d4ee7e | |||
bab14f40fd | |||
4b337272b7 | |||
d62c876481 | |||
5306333434 | |||
5070486392 | |||
9647326bcf | |||
f720d14d91 | |||
7f3ad75595 | |||
634914df32 | |||
4fc55d8fdb | |||
c98cd238db | |||
b25fa305a3 | |||
181f10df92 | |||
c65a26fe6d | |||
dd9ada314c | |||
12194cb2cd | |||
b8ab602c41 | |||
95f03216f8 | |||
5529ce4143 | |||
5b0ff19756 | |||
bf3c3eb1fd | |||
450b569534 | |||
e1cf912aaf | |||
03d6eb5402 | |||
effa3e26d2 | |||
a71d1eb2c8 | |||
b50d70502b | |||
d8cff32ae5 | |||
7b2009794e | |||
53d6483af8 | |||
34c59b7d0b | |||
bd485b6bd1 | |||
0cfae9b3a5 | |||
23fa2c1473 | |||
291588df6a | |||
87189a16c7 | |||
cde58ab948 | |||
20e68089c2 | |||
7790315509 | |||
c47e26f841 | |||
3edf2e9363 | |||
a8c97016ef | |||
07b4a80293 | |||
d08d2193f9 | |||
632ccbdfb9 | |||
b81836a248 | |||
3b539379a8 | |||
596753d72c | |||
f9d7f16c00 | |||
56d96e897e | |||
5a201f5e82 | |||
13ccc115f4 | |||
f2eb44dadd | |||
8dcf1ee9bc | |||
3707a44789 | |||
385512c5e5 | |||
083d63a2ff | |||
6930747f7f | |||
20afff9c90 | |||
36fa9877a9 | |||
77a48bbb85 | |||
4f71fcfa81 | |||
768b4eb7db | |||
ba7e1e2155 | |||
6803d4b94d | |||
3c80e97cbd | |||
8d30c127da | |||
2d101adc9f | |||
c8b60fb6bf | |||
bea420f2fd | |||
3a3dbe976e | |||
ce38f90a9a | |||
c32ed2108b | |||
d99c06115d | |||
f311b6d978 | |||
9427b17c42 | |||
f39691d155 | |||
19e6ad3fe0 | |||
efeb86e5ce | |||
8e5c71c8f8 | |||
c0d7255256 | |||
c1ca14bb7b | |||
e1655545c1 | |||
2a58294d0c | |||
92ffa484b1 | |||
3698118d95 | |||
cfb7e25be1 | |||
5865234247 | |||
0cb99b2a12 | |||
4a01d86a5b | |||
1c7be1087d | |||
ac1baccba4 | |||
92451e3d46 | |||
a841c568fd | |||
5d1a72cb19 | |||
8889c6748f | |||
f4159a6d20 | |||
7164f75e01 | |||
44b8627225 | |||
054db1cac2 | |||
1317beb53a | |||
fabe7d52fe | |||
993f819e3d | |||
831e0d4070 | |||
bb2233aaa5 | |||
24ed2d0102 | |||
059f1aa99b | |||
5c5ac76dc6 | |||
a0f70ab98c | |||
5dcd27b0bc | |||
79735df611 | |||
a1105722ad | |||
131ac602dc | |||
c8cb48ba8b | |||
7bbfec324f | |||
6b7d951977 | |||
c7eaa2ec00 | |||
8807004b20 | |||
2d640ec739 | |||
53b5bae1f6 | |||
45c0959fcd | |||
d33a835564 | |||
347456b934 | |||
76a91b1af8 | |||
9d49fb8e98 | |||
10ad86dc12 | |||
71f0d4bd07 | |||
7669e56997 | |||
c8cf369c29 | |||
6ade6c061b | |||
843b5197ce | |||
a3d47e556c | |||
7261940ea5 | |||
8ada5b5558 | |||
62230c5409 | |||
51b6fb2610 | |||
c47b497cff | |||
975b958e4c | |||
13bccd131e | |||
daad66578a | |||
29c0c6cee8 | |||
5551aab1c3 | |||
9a46dbb681 | |||
9fdd50a4bb | |||
8336fd394b | |||
51f68377c1 | |||
8aad93f856 |
6
.eslintignore
Normal file
6
.eslintignore
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!src/
|
50
.eslintrc.js
Normal file
50
.eslintrc.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:eslint-plugin-jest/recommended',
|
||||||
|
'eslint-config-prettier'
|
||||||
|
],
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
plugins: ['@typescript-eslint', 'eslint-plugin-jest'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-require-imports': 'error',
|
||||||
|
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'@typescript-eslint/no-empty-function': 'off',
|
||||||
|
'@typescript-eslint/ban-ts-comment': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
'ts-ignore': 'allow-with-description'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-console': 'error',
|
||||||
|
'yoda': 'error',
|
||||||
|
'prefer-const': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
destructuring: 'all'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'no-control-regex': 'off',
|
||||||
|
'no-constant-condition': ['error', {checkLoops: false}]
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: ['**/*{test,spec}.ts'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
|
'jest/no-standalone-expect': 'off',
|
||||||
|
'jest/no-conditional-expect': 'off',
|
||||||
|
'no-console': 'off',
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
'jest/globals': true
|
||||||
|
}
|
||||||
|
};
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +1,2 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
.licenses/** -diff linguist-generated=true
|
.licenses/** -diff linguist-generated=true
|
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @actions/setup-actions-team
|
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
33
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -2,22 +2,31 @@
|
|||||||
name: Bug report
|
name: Bug report
|
||||||
about: Create a bug report
|
about: Create a bug report
|
||||||
title: ''
|
title: ''
|
||||||
labels: ''
|
labels: bug, needs triage
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Description
|
**Description:**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
<!--
|
**Task version:**
|
||||||
* Please share short description of the problem
|
Specify the task version
|
||||||
-->
|
|
||||||
|
|
||||||
### Details
|
**Platform:**
|
||||||
|
- [ ] Ubuntu
|
||||||
|
- [ ] macOS
|
||||||
|
- [ ] Windows
|
||||||
|
|
||||||
<!--
|
**Runner type:**
|
||||||
* Include the relevant yaml, platform, and dotnet versions in use
|
- [ ] Hosted
|
||||||
* If an error occurred on a public action, please share a link
|
- [ ] Self-hosted
|
||||||
* Include any error messages received in text (search does not work for images)
|
|
||||||
* Was this a regression from previous behavior?
|
**Repro steps:**
|
||||||
-->
|
A description with steps to reproduce the issue. If your have a public example or repo to share, please provide the link.
|
||||||
|
|
||||||
|
**Expected behavior:**
|
||||||
|
A description of what you expected to happen.
|
||||||
|
|
||||||
|
**Actual behavior:**
|
||||||
|
A description of what is actually happening.
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
blank_issues_enabled: true
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: .NET issues
|
- name: .NET issues
|
||||||
url: https://github.com/dotnet/runtime#filing-issues
|
url: https://github.com/dotnet/runtime#filing-issues
|
||||||
|
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
16
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
title: ''
|
||||||
|
labels: feature request, needs triage
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
**Description:**
|
||||||
|
Describe your proposal.
|
||||||
|
|
||||||
|
**Justification:**
|
||||||
|
Justification or a use case for your proposal.
|
||||||
|
|
||||||
|
**Are you willing to submit a PR?**
|
||||||
|
<!--- We accept contributions! -->
|
9
.github/pull_request_template.md
vendored
Normal file
9
.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
**Description:**
|
||||||
|
Describe your changes.
|
||||||
|
|
||||||
|
**Related issue:**
|
||||||
|
Add link to the related issue.
|
||||||
|
|
||||||
|
**Check list:**
|
||||||
|
- [ ] Mark if documentation changes are required.
|
||||||
|
- [ ] Mark if tests were added or updated to cover the changes.
|
17
.github/workflows/basic-validation.yml
vendored
Normal file
17
.github/workflows/basic-validation.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Basic validation
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/*
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-basic-validation:
|
||||||
|
name: Basic validation
|
||||||
|
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
|
17
.github/workflows/check-dist.yml
vendored
Normal file
17
.github/workflows/check-dist.yml
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
name: Check dist/
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-check-dist:
|
||||||
|
name: Check dist/
|
||||||
|
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
|
14
.github/workflows/codeql-analysis.yml
vendored
Normal file
14
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
name: CodeQL analysis
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
branches: [main]
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * 0'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-codeQL-analysis:
|
||||||
|
name: CodeQL analysis
|
||||||
|
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
|
368
.github/workflows/e2e-tests.yml
vendored
Normal file
368
.github/workflows/e2e-tests.yml
vendored
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
name: e2e tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/*
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-setup-multiple-versions:
|
||||||
|
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.402, 3.1.404 and 3.0.x
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
2.2.402
|
||||||
|
3.1.404
|
||||||
|
3.0.x
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2.402$", "^3.1.404$", "^3.0"
|
||||||
|
|
||||||
|
test-setup-full-version:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
# Side-by-side install of 2.2 and 3.1 used for the test project
|
||||||
|
- name: Setup dotnet 2.2.402
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.402
|
||||||
|
- name: Setup dotnet 3.1.201
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.201
|
||||||
|
# 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
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$", "^2.2.402$" -CheckNugetConfig
|
||||||
|
|
||||||
|
test-setup-without-patch-version:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
# 2.0, 3.0, 5.0 needs to be in single quotes to interpret as a string instead of as an integer
|
||||||
|
- name: Setup dotnet '3.1'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '3.1'
|
||||||
|
- name: Setup dotnet '2.2'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '2.2'
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^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 '3.1.100-preview1-014459'
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '3.1.100-preview1-014459'
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "3.1.100-preview1-014459"
|
||||||
|
|
||||||
|
test-setup-latest-patch-version:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet 3.1.x
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.x
|
||||||
|
- name: Setup dotnet 2.2.X
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.X
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"
|
||||||
|
|
||||||
|
test-ABCxx-syntax:
|
||||||
|
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.4xx
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: '6.0.4xx'
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^6\.0\.4\d{2}"
|
||||||
|
|
||||||
|
test-setup-with-wildcard:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet 3.1.*
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.*
|
||||||
|
- name: Setup dotnet 2.2.*
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 2.2.*
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1", "^2.2"
|
||||||
|
|
||||||
|
test-setup-global-json-specified-and-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: Write global.json
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir subdirectory
|
||||||
|
echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1
|
||||||
|
global-json-file: ./subdirectory/global.json
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"
|
||||||
|
|
||||||
|
test-setup-global-json-only:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Write global.json
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
mkdir subdirectory
|
||||||
|
echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
global-json-file: ./subdirectory/global.json
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2"
|
||||||
|
|
||||||
|
test-setup-with-dotnet-quality:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
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 dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-"
|
||||||
|
|
||||||
|
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:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ubuntu:latest
|
||||||
|
options: --dns 127.0.0.1
|
||||||
|
services:
|
||||||
|
squid-proxy:
|
||||||
|
image: ubuntu/squid:latest
|
||||||
|
ports:
|
||||||
|
- 3128:3128
|
||||||
|
env:
|
||||||
|
https_proxy: http://squid-proxy:3128
|
||||||
|
http_proxy: http://squid-proxy:3128
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Install Powershell
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y wget apt-transport-https software-properties-common
|
||||||
|
wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb"
|
||||||
|
dpkg -i packages-microsoft-prod.deb
|
||||||
|
rm packages-microsoft-prod.deb
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y powershell
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet 6.0
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 6.0
|
||||||
|
source-url: https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
__tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig
|
||||||
|
|
||||||
|
test-bypass-proxy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
https_proxy: http://no-such-proxy:3128
|
||||||
|
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet 3.1.201
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.201
|
||||||
|
source-url: https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$" -CheckNugetConfig
|
25
.github/workflows/licensed.yml
vendored
25
.github/workflows/licensed.yml
vendored
@ -1,20 +1,15 @@
|
|||||||
name: Licensed
|
name: Licensed
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push: {branches: main}
|
push:
|
||||||
pull_request: {branches: main}
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
call-licensed:
|
||||||
runs-on: ubuntu-latest
|
name: Licensed
|
||||||
name: Check licenses
|
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- run: npm ci
|
|
||||||
- name: Install licensed
|
|
||||||
run: |
|
|
||||||
cd $RUNNER_TEMP
|
|
||||||
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/2.12.2/licensed-2.12.2-linux-x64.tar.gz
|
|
||||||
sudo tar -xzf licensed.tar.gz
|
|
||||||
sudo mv licensed /usr/local/bin/licensed
|
|
||||||
- run: licensed status
|
|
||||||
|
29
.github/workflows/release-new-action-version.yml
vendored
Normal file
29
.github/workflows/release-new-action-version.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: Release new action version
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
TAG_NAME:
|
||||||
|
description: 'Tag name that the major tag will point to'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_tag:
|
||||||
|
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||||
|
environment:
|
||||||
|
name: releaseNewActionVersion
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
|
id: update-major-tag
|
||||||
|
uses: actions/publish-action@v0.2.2
|
||||||
|
with:
|
||||||
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
35
.github/workflows/test-dotnet.yml
vendored
Normal file
35
.github/workflows/test-dotnet.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: Validate dotnet
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- releases/*
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
setup-version:
|
||||||
|
runs-on: ${{ matrix.operating-system }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
|
dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0']
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Clear toolcache
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet ${{ matrix.dotnet-version }}
|
||||||
|
uses: ./
|
||||||
|
with:
|
||||||
|
dotnet-version: ${{ matrix.dotnet-version }}
|
||||||
|
- name: Verify installed version
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
__tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.dotnet-version }}"
|
11
.github/workflows/update-config-files.yml
vendored
Normal file
11
.github/workflows/update-config-files.yml
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
name: Update configuration files
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 3 * * 0'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
call-update-configuration-files:
|
||||||
|
name: Update configuration files
|
||||||
|
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main
|
185
.github/workflows/workflow.yml
vendored
185
.github/workflows/workflow.yml
vendored
@ -1,185 +0,0 @@
|
|||||||
name: Main workflow
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- releases/*
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ${{ matrix.operating-system }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Set Node.js 12
|
|
||||||
uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 12.x
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run build
|
|
||||||
- run: npm run format-check
|
|
||||||
- run: npm test
|
|
||||||
- name: Verify no unstaged changes
|
|
||||||
if: runner.os != 'windows'
|
|
||||||
run: __tests__/verify-no-unstaged-changes.sh
|
|
||||||
|
|
||||||
test:
|
|
||||||
runs-on: ${{ matrix.operating-system }}
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Clear tool cache (macOS)
|
|
||||||
if: runner.os == 'macos'
|
|
||||||
run: |
|
|
||||||
echo $PATH
|
|
||||||
dotnet --info
|
|
||||||
rm -rf "/Users/runner/.dotnet"
|
|
||||||
- name: Clear tool cache (Ubuntu)
|
|
||||||
if: runner.os == 'linux'
|
|
||||||
run: |
|
|
||||||
echo $PATH
|
|
||||||
dotnet --info
|
|
||||||
rm -rf "/usr/share/dotnet"
|
|
||||||
- name: Clear tool cache (Windows)
|
|
||||||
if: runner.os == 'windows'
|
|
||||||
run: |
|
|
||||||
echo $env:PATH
|
|
||||||
dotnet --info
|
|
||||||
Remove-Item $env:LocalAppData\Microsoft\dotnet/* -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
Remove-Item "$env:ProgramFiles\dotnet/*" -Recurse -Force -ErrorAction SilentlyContinue
|
|
||||||
# Side-by-side install of 2.2 and 3.1 used for the test project
|
|
||||||
- name: Setup dotnet 2.2.402
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.2.402
|
|
||||||
- name: Setup dotnet 3.1.201
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.201
|
|
||||||
# We are including this veriable to force the generation of the nuget config file to verify that it is created in the correct place
|
|
||||||
source-url: https://api.nuget.org/v3/index.json
|
|
||||||
env:
|
|
||||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
|
||||||
- name: Verify dotnet
|
|
||||||
if: runner.os != 'windows'
|
|
||||||
run: __tests__/verify-dotnet.sh 3.1.201 2.2.402
|
|
||||||
- name: Verify dotnet (Windows)
|
|
||||||
if: runner.os == 'windows'
|
|
||||||
run: __tests__/verify-dotnet.ps1 3.1.201 2.2.402
|
|
||||||
|
|
||||||
# Set new cache before 2 digit install
|
|
||||||
- name: Set new tool cache (macOS)
|
|
||||||
if: runner.os == 'macos'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/Users/runner/.dotnet2"
|
|
||||||
- name: Set new tool cache (Ubuntu)
|
|
||||||
if: runner.os == 'linux'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/home/runner/.dotnet2"
|
|
||||||
- name: Set new tool cache (Windows)
|
|
||||||
if: runner.os == 'windows'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::$env:LocalAppData\Microsoft\dotnet2"
|
|
||||||
# 2.0, 3.0, 5.0 needs to be in single quotes to interpret as a string instead of as an integer
|
|
||||||
- name: Setup dotnet '2.0'
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: '2.0'
|
|
||||||
|
|
||||||
# Clear cache before .x version install
|
|
||||||
- name: Set new tool cache (macOS)
|
|
||||||
if: runner.os == 'macos'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/Users/runner/.dotnet3"
|
|
||||||
- name: Set new tool cache (Ubuntu)
|
|
||||||
if: runner.os == 'linux'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/home/runner/.dotnet3"
|
|
||||||
- name: Set new tool cache (Windows)
|
|
||||||
if: runner.os == 'windows'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::$env:LocalAppData\Microsoft\dotnet3"
|
|
||||||
- name: Setup dotnet 2.0.x
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.0.x
|
|
||||||
|
|
||||||
# Clear cache before .* version install
|
|
||||||
- name: Set new tool cache (macOS)
|
|
||||||
if: runner.os == 'macos'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/Users/runner/.dotnet4"
|
|
||||||
- name: Set new tool cache (Ubuntu)
|
|
||||||
if: runner.os == 'linux'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::/home/runner/.dotnet4"
|
|
||||||
- name: Set new tool cache (Windows)
|
|
||||||
if: runner.os == 'windows'
|
|
||||||
run: |
|
|
||||||
echo "::set-env name=DOTNET_INSTALL_DIR::$env:LocalAppData\Microsoft\dotnet4"
|
|
||||||
- name: Setup dotnet 2.0.*
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 2.0.*
|
|
||||||
|
|
||||||
test-proxy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: mcr.microsoft.com/dotnet/core/runtime-deps:3.0-bionic
|
|
||||||
options: --dns 127.0.0.1
|
|
||||||
services:
|
|
||||||
squid-proxy:
|
|
||||||
image: datadog/squid:latest
|
|
||||||
ports:
|
|
||||||
- 3128:3128
|
|
||||||
env:
|
|
||||||
https_proxy: http://squid-proxy:3128
|
|
||||||
http_proxy: http://squid-proxy:3128
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Clear tool cache
|
|
||||||
run: rm -rf "/usr/share/dotnet"
|
|
||||||
- name: Install curl
|
|
||||||
run: |
|
|
||||||
apt update
|
|
||||||
apt -y install curl
|
|
||||||
- name: Setup dotnet 3.1.201
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.201
|
|
||||||
source-url: https://api.nuget.org/v3/index.json
|
|
||||||
env:
|
|
||||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
|
||||||
- name: Verify dotnet
|
|
||||||
run: __tests__/verify-dotnet.sh 3.1.201
|
|
||||||
|
|
||||||
test-bypass-proxy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
https_proxy: http://no-such-proxy:3128
|
|
||||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
- name: Clear tool cache
|
|
||||||
run: rm -rf "/usr/share/dotnet"
|
|
||||||
- name: Setup dotnet 3.1.201
|
|
||||||
uses: ./
|
|
||||||
with:
|
|
||||||
dotnet-version: 3.1.201
|
|
||||||
source-url: https://api.nuget.org/v3/index.json
|
|
||||||
env:
|
|
||||||
NUGET_AUTH_TOKEN: NOTATOKEN
|
|
||||||
- name: Verify dotnet
|
|
||||||
run: __tests__/verify-dotnet.sh 3.1.201
|
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -3,8 +3,8 @@ global.json
|
|||||||
lib/
|
lib/
|
||||||
node_modules/
|
node_modules/
|
||||||
__tests__/runner/*
|
__tests__/runner/*
|
||||||
__tests__/sample-csproj/bin/
|
__tests__/e2e-test-csproj/bin/
|
||||||
__tests__/sample-csproj/obj/
|
__tests__/e2e-test-csproj/obj/
|
||||||
|
|
||||||
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
# Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
|
||||||
# Logs
|
# Logs
|
||||||
|
5
.husky/pre-commit
Executable file
5
.husky/pre-commit
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npm run format
|
||||||
|
npm run lint:fix
|
6
.husky/pre-push
Executable file
6
.husky/pre-push
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
# Tests are not run at push time since they can take 2-4 minutes to complete
|
||||||
|
npm run format-check
|
||||||
|
npm run lint
|
2
.licenses/npm/@actions/core.dep.yml
generated
2
.licenses/npm/@actions/core.dep.yml
generated
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/core"
|
name: "@actions/core"
|
||||||
version: 1.2.5
|
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
|
||||||
|
30
.licenses/npm/@actions/exec.dep.yml
generated
30
.licenses/npm/@actions/exec.dep.yml
generated
@ -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: []
|
||||||
|
4
.licenses/npm/@actions/http-client.dep.yml
generated
4
.licenses/npm/@actions/http-client.dep.yml
generated
@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
name: "@actions/http-client"
|
name: "@actions/http-client"
|
||||||
version: 1.0.8
|
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
|
||||||
|
30
.licenses/npm/@actions/io.dep.yml
generated
30
.licenses/npm/@actions/io.dep.yml
generated
@ -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: []
|
||||||
|
22
.licenses/npm/fast-xml-parser.dep.yml
generated
22
.licenses/npm/fast-xml-parser.dep.yml
generated
@ -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: []
|
||||||
|
2
.licenses/npm/node-fetch.dep.yml
generated
2
.licenses/npm/node-fetch.dep.yml
generated
@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: node-fetch
|
name: node-fetch
|
||||||
version: 2.6.1
|
version: 2.6.7
|
||||||
type: npm
|
type: npm
|
||||||
summary: A light-weight module that brings window.fetch to node.js
|
summary: A light-weight module that brings window.fetch to node.js
|
||||||
homepage: https://github.com/bitinn/node-fetch
|
homepage: https://github.com/bitinn/node-fetch
|
||||||
|
11
.licenses/npm/strnum.dep.yml
generated
Normal file
11
.licenses/npm/strnum.dep.yml
generated
Normal 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: []
|
30
.licenses/npm/tr46.dep.yml
generated
Normal file
30
.licenses/npm/tr46.dep.yml
generated
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
name: tr46
|
||||||
|
version: 0.0.3
|
||||||
|
type: npm
|
||||||
|
summary: An implementation of the Unicode TR46 spec
|
||||||
|
homepage: https://github.com/Sebmaster/tr46.js#readme
|
||||||
|
license: mit
|
||||||
|
licenses:
|
||||||
|
- sources: Auto-generated MIT license text
|
||||||
|
text: |
|
||||||
|
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: []
|
20
.licenses/npm/uuid.dep.yml
generated
Normal file
20
.licenses/npm/uuid.dep.yml
generated
Normal 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: []
|
23
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
23
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: webidl-conversions
|
||||||
|
version: 3.0.1
|
||||||
|
type: npm
|
||||||
|
summary: Implements the WebIDL algorithms for converting to and from JavaScript values
|
||||||
|
homepage:
|
||||||
|
license: bsd-2-clause
|
||||||
|
licenses:
|
||||||
|
- sources: LICENSE.md
|
||||||
|
text: |
|
||||||
|
# The BSD 2-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2014, Domenic Denicola
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
notices: []
|
32
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
32
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
name: whatwg-url
|
||||||
|
version: 5.0.0
|
||||||
|
type: npm
|
||||||
|
summary: An implementation of the WHATWG URL Standard's URL API and parsing machinery
|
||||||
|
homepage:
|
||||||
|
license: mit
|
||||||
|
licenses:
|
||||||
|
- sources: LICENSE.txt
|
||||||
|
text: |
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015–2016 Sebastian Mayr
|
||||||
|
|
||||||
|
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: []
|
24
.licenses/npm/xmlbuilder.dep.yml
generated
24
.licenses/npm/xmlbuilder.dep.yml
generated
@ -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: []
|
|
7
.prettierignore
Normal file
7
.prettierignore
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Ignore list
|
||||||
|
/*
|
||||||
|
|
||||||
|
# Do not ignore these folders:
|
||||||
|
!__tests__/
|
||||||
|
!.github/
|
||||||
|
!src/
|
11
.prettierrc.js
Normal file
11
.prettierrc.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 80,
|
||||||
|
tabWidth: 2,
|
||||||
|
useTabs: false,
|
||||||
|
semi: true,
|
||||||
|
singleQuote: true,
|
||||||
|
trailingComma: 'none',
|
||||||
|
bracketSpacing: false,
|
||||||
|
arrowParens: 'avoid'
|
||||||
|
};
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"printWidth": 80,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"trailingComma": "none",
|
|
||||||
"bracketSpacing": false,
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"parser": "typescript"
|
|
||||||
}
|
|
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to make participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all project spaces, and it also applies when
|
||||||
|
an individual is representing the project or its community in public spaces.
|
||||||
|
Examples of representing a project or community include using an official
|
||||||
|
project e-mail address, posting via an official social media account, or acting
|
||||||
|
as an appointed representative at an online or offline event. Representation of
|
||||||
|
a project may be further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at opensource+actions/setup-dotnet@github.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
233
README.md
233
README.md
@ -1,92 +1,151 @@
|
|||||||
# setup-dotnet
|
# setup-dotnet
|
||||||
|
|
||||||
<p align="left">
|
[](https://github.com/actions/setup-dotnet/actions/workflows/basic-validation.yml)
|
||||||
<a href="https://github.com/actions/setup-dotnet"><img alt="GitHub Actions status" src="https://github.com/actions/setup-dotnet/workflows/Main%20workflow/badge.svg"></a>
|
[](https://github.com/actions/setup-dotnet/actions/workflows/e2e-tests.yml)
|
||||||
</p>
|
|
||||||
|
|
||||||
This action sets up a [dotnet core cli](https://github.com/dotnet/cli) environment for use in actions by:
|
This action sets up a [.NET CLI](https://github.com/dotnet/sdk) environment for use in actions by:
|
||||||
|
|
||||||
- optionally downloading and caching a version of dotnet by SDK version and adding to PATH
|
- optionally downloading and caching a version(s) of dotnet by SDK version(s) and adding to PATH
|
||||||
- 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://help.github.com/en/actions/reference/software-installed-on-github-hosted-runners)
|
[Software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software)
|
||||||
for .NET SDK versions that are currently available.
|
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@main
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v1
|
- 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>
|
||||||
|
```
|
||||||
|
> **Warning**: Unless a concrete version is specified in the [`global.json`](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) file, **_the latest .NET version installed on the runner (including preinstalled versions) will be used [by default](https://learn.microsoft.com/en-us/dotnet/core/versions/selection#the-sdk-uses-the-latest-installed-version)_**. Please refer to the [documentation](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software) for the currently preinstalled .NET SDK versions.
|
||||||
|
|
||||||
|
**Multiple version installation**:
|
||||||
|
```yml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
3.1.x
|
||||||
|
5.0.x
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
```
|
||||||
|
## Supported version syntax
|
||||||
|
|
||||||
|
The `dotnet-version` input supports following syntax:
|
||||||
|
|
||||||
|
- **A.B.C** (e.g 6.0.400, 7.0.100-preview.7.22377.5) - installs exact version of .NET SDK
|
||||||
|
- **A.B** or **A.B.x** (e.g. 3.1, 3.1.x) - installs the latest patch version of .NET SDK on the channel `3.1`, including prerelease versions (preview, rc)
|
||||||
|
- **A** or **A.x** (e.g. 3, 3.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
|
||||||
|
- **A.B.Cxx** (e.g. 6.0.4xx) - available since `.NET 5.0` release. Installs the latest version of the specific SDK release, including prerelease versions (preview, rc).
|
||||||
|
|
||||||
|
|
||||||
|
## 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', 'A.x' and 'A.B.Cxx' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: '6.0.x'
|
||||||
|
dotnet-quality: 'preview'
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
|
|
||||||
Matrix Testing:
|
## Using the `global-json-file` input
|
||||||
```yaml
|
`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
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
global-json-file: csharp/global.json
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
working-directory: csharp
|
||||||
|
```
|
||||||
|
|
||||||
|
## Matrix Testing
|
||||||
|
Using `setup-dotnet` it's possible to use [matrix syntax](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) to install several versions of .NET SDK:
|
||||||
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
dotnet: [ '2.2.103', '3.0', '3.1.x' ]
|
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
|
||||||
name: Dotnet ${{ matrix.dotnet }} sample
|
name: Dotnet ${{ matrix.dotnet }} sample
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet }}
|
dotnet-version: ${{ matrix.dotnet }}
|
||||||
- run: dotnet build <my project>
|
- name: Execute dotnet
|
||||||
|
run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
|
>**Note**: Unless a concrete version is specified in the [`global.json`](https://learn.microsoft.com/en-us/dotnet/core/tools/global-json) file, the latest .NET version installed on the runner (including preinstalled versions) will be used [by default](https://learn.microsoft.com/en-us/dotnet/core/versions/selection#the-sdk-uses-the-latest-installed-version). To control this behavior you may want to use temporary `global.json` files:
|
||||||
|
|
||||||
Side by Side Testing:
|
**Matrix testing with temporary global.json creation**
|
||||||
```yaml
|
```yml
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Dotnet Side by Side testing sample
|
strategy:
|
||||||
|
matrix:
|
||||||
|
dotnet: [ '2.1.x', '3.1.x', '5.0.x' ]
|
||||||
|
name: Dotnet ${{ matrix.dotnet }} sample
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
|
id: stepid
|
||||||
with:
|
with:
|
||||||
dotnet-version: '2.2.103'
|
dotnet-version: ${{ matrix.dotnet }}
|
||||||
- name: Setup dotnet
|
- name: Create temporary global.json
|
||||||
uses: actions/setup-dotnet@v1
|
run: echo '{"sdk":{"version": "${{ steps.stepid.outputs.dotnet-version }}"}}' > ./global.json
|
||||||
with:
|
- name: Execute dotnet
|
||||||
dotnet-version: '3.1.x'
|
run: dotnet build <my project>
|
||||||
- run: dotnet build <my project>
|
|
||||||
- run: dotnet test <my project>
|
|
||||||
```
|
```
|
||||||
|
## Setting up authentication for nuget feeds
|
||||||
|
|
||||||
Authentication for nuget feeds:
|
### Github Package Registry (GPR)
|
||||||
```yaml
|
```yml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
# Authenticates packages to push to GPR
|
- uses: actions/setup-dotnet@v3
|
||||||
- uses: actions/setup-dotnet@v1
|
|
||||||
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}}
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
- name: Create the package
|
- name: Create the package
|
||||||
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
|
||||||
|
```
|
||||||
|
|
||||||
# Authticates packages to push to Azure Artifacts
|
### Azure Artifacts
|
||||||
- uses: actions/setup-dotnet@v1
|
```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:
|
||||||
@ -95,31 +154,101 @@ steps:
|
|||||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variables to use with dotnet
|
### nuget.org
|
||||||
|
```yml
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.x
|
||||||
|
- name: Publish the package to nuget.org
|
||||||
|
run: dotnet nuget push */bin/Release/*.nupkg -k $NUGET_AUTH_TOKEN -s https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
||||||
|
```
|
||||||
|
> **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.
|
||||||
|
|
||||||
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
|
# Outputs and environment variables
|
||||||
|
|
||||||
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false)
|
## Outputs
|
||||||
- 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-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.
|
||||||
|
|
||||||
Example usage:
|
|
||||||
```yaml
|
```yaml
|
||||||
|
- uses: actions/setup-dotnet@v3
|
||||||
|
id: stepid
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.422
|
||||||
|
- run: echo '${{ steps.stepid.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: stepid
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
3.1.422
|
||||||
|
5.0.408
|
||||||
|
- run: echo '${{ steps.stepid.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: stepid
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
3.1.422
|
||||||
|
5.0.408
|
||||||
|
global-json-file: "./global.json" # contains version 2.2.207
|
||||||
|
- run: echo '${{ steps.stepid.outputs.dotnet-version }}' # outputs 2.2.207
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
| **Env.variable** | **Description** | **Default value** |
|
||||||
|
| ----------- | ----------- | ----------- |
|
||||||
|
| 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*|
|
||||||
|
|
||||||
|
The default value of the `DOTNET_INSTALL_DIR` environment variable depends on the operation system which is used on a runner:
|
||||||
|
| **Operation system** | **Default value** |
|
||||||
|
| ----------- | ----------- |
|
||||||
|
| **Windows** | `C:\Program Files\dotnet` |
|
||||||
|
| **Ubuntu** | `/usr/share/dotnet` |
|
||||||
|
| **macOS** | `/Users/runner/.dotnet` |
|
||||||
|
|
||||||
|
**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@v1
|
- uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.100' # 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)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`authutil tests Existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -15,7 +15,7 @@ exports[`authutil tests Existing config not in repo root, sets up a partial NuGe
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -30,7 +30,7 @@ exports[`authutil tests Existing config w/ Azure Artifacts source and NuGet.org,
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -45,7 +45,7 @@ exports[`authutil tests Existing config w/ GPR source and NuGet.org, sets up a p
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -63,7 +63,7 @@ exports[`authutil tests Existing config w/ no GPR sources, sets up a full NuGet.
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -81,7 +81,7 @@ exports[`authutil tests Existing config w/ no sources, sets up a full NuGet.conf
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -96,7 +96,7 @@ exports[`authutil tests Existing config w/ only Azure Artifacts source, sets up
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -111,7 +111,7 @@ exports[`authutil tests Existing config w/ only GPR source, sets up a partial Nu
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests Existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
exports[`authutil tests existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -130,7 +130,7 @@ exports[`authutil tests Existing config w/ two GPR sources, sets up a partial Nu
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR 1`] = `
|
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -148,7 +148,7 @@ exports[`authutil tests No existing config, sets up a full NuGet.config with URL
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and token for other source 1`] = `
|
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and token for other source 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
@ -166,7 +166,7 @@ exports[`authutil tests No existing config, sets up a full NuGet.config with URL
|
|||||||
</configuration>"
|
</configuration>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`authutil tests No existing config, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
exports[`authutil tests no existing config, sets up a full NuGet.config with URL and user/PAT for GPR 1`] = `
|
||||||
"<?xml version=\\"1.0\\"?>
|
"<?xml version=\\"1.0\\"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<config>
|
<config>
|
||||||
|
@ -1,32 +1,28 @@
|
|||||||
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'
|
||||||
);
|
);
|
||||||
|
|
||||||
const invalidNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>`;
|
const invalidNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>`;
|
||||||
|
|
||||||
const emptyNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const emptyNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const nugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const nugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const gprnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const gprnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
@ -34,14 +30,14 @@ const gprnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
|||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const gprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const gprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
<add key="GPR" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const twogprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const twogprNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="GPR-GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
<add key="GPR-GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
@ -49,21 +45,21 @@ const twogprNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
|||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const spaceNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const spaceNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
<add key="GPR GitHub" value="https://nuget.pkg.github.com/OwnerName/index.json" protocolVersion="3" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const azureartifactsNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const azureartifactsNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||||
</packageSources>
|
</packageSources>
|
||||||
</configuration>`;
|
</configuration>`;
|
||||||
|
|
||||||
const azureartifactsnugetorgNuGetConfig: string = `<?xml version="1.0" encoding="utf-8"?>
|
const azureartifactsnugetorgNuGetConfig = `<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<packageSources>
|
<packageSources>
|
||||||
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
<add key="AzureArtifacts" value="https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json" protocolVersion="3" />
|
||||||
@ -95,9 +91,9 @@ describe('authutil tests', () => {
|
|||||||
process.env['NUGET_AUTH_TOKEN'] = '';
|
process.env['NUGET_AUTH_TOKEN'] = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
it('no existing config, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -108,10 +104,10 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No existing config, auth token environment variable not provided, throws', async () => {
|
it('no existing config, auth token environment variable not provided, throws', async () => {
|
||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -122,10 +118,10 @@ describe('authutil tests', () => {
|
|||||||
expect(thrown).toBe(true);
|
expect(thrown).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR', async () => {
|
it('no existing config, sets up a full NuGet.config with URL and other owner/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
process.env['INPUT_OWNER'] = 'otherorg';
|
process.env['INPUT_OWNER'] = 'otherorg';
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/otherorg/index.json',
|
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -136,7 +132,7 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
it('existing config (invalid), tries to parse an invalid NuGet.config and throws', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
@ -145,7 +141,7 @@ describe('authutil tests', () => {
|
|||||||
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, invalidNuGetConfig);
|
||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -156,14 +152,14 @@ describe('authutil tests', () => {
|
|||||||
expect(thrown).toBe(true);
|
expect(thrown).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
it('existing config w/ no sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -174,14 +170,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
it('existing config w/ no GPR sources, sets up a full NuGet.config with URL and user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -192,14 +188,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config w/ only GPR source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -210,14 +206,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config w/ GPR source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -228,14 +224,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config w/ two GPR sources, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com',
|
'https://nuget.pkg.github.com',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -246,7 +242,7 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ spaces in key, throws for now', async () => {
|
it('existing config w/ spaces in key, throws for now', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
@ -255,7 +251,7 @@ describe('authutil tests', () => {
|
|||||||
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, spaceNuGetConfig);
|
||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -266,7 +262,7 @@ describe('authutil tests', () => {
|
|||||||
expect(thrown).toBe(true);
|
expect(thrown).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config not in repo root, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigDirectory: string = path.join(
|
const inputNuGetConfigDirectory: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
@ -278,7 +274,7 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
fs.mkdirSync(inputNuGetConfigDirectory, {recursive: true});
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json',
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
'subfolder/nuget.config',
|
'subfolder/nuget.config',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -289,14 +285,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config w/ only Azure Artifacts source, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -307,14 +303,14 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
it('existing config w/ Azure Artifacts source and NuGet.org, sets up a partial NuGet.config user/PAT for GPR', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
const inputNuGetConfigPath: string = path.join(
|
const inputNuGetConfigPath: string = path.join(
|
||||||
fakeSourcesDirForTesting,
|
fakeSourcesDirForTesting,
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
@ -325,9 +321,9 @@ describe('authutil tests', () => {
|
|||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
it('no existing config, sets up a full NuGet.config with URL and token for other source', async () => {
|
||||||
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
process.env['NUGET_AUTH_TOKEN'] = 'TEST_FAKE_AUTH_TOKEN';
|
||||||
await auth.configAuthentication(
|
auth.configAuthentication(
|
||||||
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
'https://pkgs.dev.azure.com/amullans/_packaging/GitHubBuilds/nuget/v3/index.json',
|
||||||
'',
|
'',
|
||||||
fakeSourcesDirForTesting
|
fakeSourcesDirForTesting
|
||||||
|
13
__tests__/clear-toolcache.ps1
Normal file
13
__tests__/clear-toolcache.ps1
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
$dotnetPaths = @{
|
||||||
|
Linux = "/usr/share/dotnet"
|
||||||
|
macOS = "$env:HOME/.dotnet"
|
||||||
|
Windows = "$env:ProgramFiles\dotnet", "$env:LocalAppData\Microsoft\dotnet"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($srcPath in $dotnetPaths[$args[0]]) {
|
||||||
|
if (Test-Path $srcPath) {
|
||||||
|
Write-Host "Move $srcPath path"
|
||||||
|
$dstPath = Join-Path ([IO.Path]::GetTempPath()) ([IO.Path]::GetRandomFileName())
|
||||||
|
Move-Item -Path $srcPath -Destination $dstPath
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +1,45 @@
|
|||||||
import fs = require('fs');
|
import cscFile from '../.github/csc.json';
|
||||||
|
|
||||||
describe('csc tests', () => {
|
describe('csc tests', () => {
|
||||||
it('Valid regular expression', async () => {
|
test('regular expression in csc.json is valid', async () => {
|
||||||
var cscFile = require('../.github/csc.json');
|
const regexPattern = cscFile['problemMatcher'][0]['pattern'][0]['regexp'];
|
||||||
var regex = cscFile['problemMatcher'][0]['pattern'][0]['regexp'];
|
const regexResultsMap = cscFile['problemMatcher'][0]['pattern'][0];
|
||||||
|
|
||||||
console.log(regex);
|
const regex = new RegExp(regexPattern);
|
||||||
var re = new RegExp(regex);
|
|
||||||
|
|
||||||
// Ideally we would verify that this
|
const stringsToMatch = [
|
||||||
var stringsToMatch = [
|
|
||||||
'Program.cs(10,79): error CS1002: ; expected [/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj]',
|
'Program.cs(10,79): error CS1002: ; expected [/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj]',
|
||||||
"S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs(33,7): error CS1003: Syntax error, ',' expected [S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop]"
|
"S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs(33,7): error CS1003: Syntax error, ',' expected [S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop]"
|
||||||
];
|
];
|
||||||
|
// Expected results are calculated according to the csc matcher located in csc.json file
|
||||||
|
const expectedResults = [
|
||||||
|
{
|
||||||
|
file: 'Program.cs',
|
||||||
|
line: '10',
|
||||||
|
severity: 'error',
|
||||||
|
code: 'CS1002',
|
||||||
|
message: '; expected',
|
||||||
|
fromPath:
|
||||||
|
'/Users/zacharyeisinger/Documents/repo/setup-dotnet/__tests__/sample-broken-csproj/sample.csproj'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'S:\\Msbuild\\src\\Build\\Evaluation\\ExpressionShredder.cs',
|
||||||
|
line: '33',
|
||||||
|
severity: 'error',
|
||||||
|
code: 'CS1003',
|
||||||
|
message: "Syntax error, ',' expected",
|
||||||
|
fromPath:
|
||||||
|
'S:\\msbuild\\src\\Build\\Microsoft.Build.csproj > Properties:prop'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
stringsToMatch.forEach(string => {
|
stringsToMatch.map((string, index) => {
|
||||||
var matchStr = string.match(re);
|
const matchedResultsArray = string.match(regex);
|
||||||
console.log(matchStr);
|
for (const propName in expectedResults[index]) {
|
||||||
expect(matchStr).toEqual(expect.anything());
|
const propertyIndex = regexResultsMap[propName];
|
||||||
|
const expectedPropValue = expectedResults[index][propName];
|
||||||
|
const matchedPropValue = matchedResultsArray![propertyIndex];
|
||||||
|
expect(matchedPropValue).toEqual(expectedPropValue);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}, 10000);
|
}, 10000);
|
||||||
});
|
});
|
||||||
|
18
__tests__/e2e-test-csproj/Test.cs
Normal file
18
__tests__/e2e-test-csproj/Test.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace test_csproj
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Test
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void TestMethod()
|
||||||
|
{
|
||||||
|
Console.WriteLine("TestMethod");
|
||||||
|
int calculatedResult = 1000 / 25;
|
||||||
|
int expectedResult = 40;
|
||||||
|
Assert.AreEqual(calculatedResult, expectedResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
__tests__/e2e-test-csproj/test.csproj
Normal file
15
__tests__/e2e-test-csproj/test.csproj
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>$(TEST_TARGET_FRAMEWORK)</TargetFramework>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<!-- These packages will be downloaded over the network for testing proxy settings -->
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0-preview-20170810-02" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" Version="1.1.18" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" Version="1.1.18" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
65
__tests__/installation-scripts.test.ts
Normal file
65
__tests__/installation-scripts.test.ts
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
import * as hc from '@actions/http-client';
|
||||||
|
|
||||||
|
const HTTP_CLIENT_OPTIONS = {allowRetries: true, maxRetries: 10} as const;
|
||||||
|
const TEST_TIMEOUT = 30000;
|
||||||
|
|
||||||
|
describe('Dotnet installation scripts tests', () => {
|
||||||
|
it(
|
||||||
|
'Uses an up to date bash download script',
|
||||||
|
async () => {
|
||||||
|
const httpCallbackClient = new hc.HttpClient(
|
||||||
|
'setup-dotnet-test',
|
||||||
|
[],
|
||||||
|
HTTP_CLIENT_OPTIONS
|
||||||
|
);
|
||||||
|
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||||
|
'https://dot.net/v1/dotnet-install.sh'
|
||||||
|
);
|
||||||
|
expect(response.message.statusCode).toBe(200);
|
||||||
|
const upToDateContents: string = await response.readBody();
|
||||||
|
const currentContents: string = fs
|
||||||
|
.readFileSync(
|
||||||
|
path.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
expect(normalizeFileContents(currentContents)).toBe(
|
||||||
|
normalizeFileContents(upToDateContents)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
TEST_TIMEOUT
|
||||||
|
);
|
||||||
|
|
||||||
|
it(
|
||||||
|
'Uses an up to date powershell download script',
|
||||||
|
async () => {
|
||||||
|
const httpCallbackClient = new hc.HttpClient(
|
||||||
|
'setup-dotnet-test',
|
||||||
|
[],
|
||||||
|
HTTP_CLIENT_OPTIONS
|
||||||
|
);
|
||||||
|
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
||||||
|
'https://dot.net/v1/dotnet-install.ps1'
|
||||||
|
);
|
||||||
|
expect(response.message.statusCode).toBe(200);
|
||||||
|
const upToDateContents: string = await response.readBody();
|
||||||
|
const currentContents: string = fs
|
||||||
|
.readFileSync(
|
||||||
|
path.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||||
|
)
|
||||||
|
.toString();
|
||||||
|
expect(normalizeFileContents(currentContents)).toBe(
|
||||||
|
normalizeFileContents(upToDateContents)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
TEST_TIMEOUT
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
function normalizeFileContents(contents: string): string {
|
||||||
|
return contents
|
||||||
|
.trim()
|
||||||
|
.replace(new RegExp('\r\n', 'g'), '\n')
|
||||||
|
.replace(new RegExp('\r', 'g'), '\n');
|
||||||
|
}
|
@ -1,129 +1,443 @@
|
|||||||
import io = require('@actions/io');
|
import each from 'jest-each';
|
||||||
import fs = require('fs');
|
import semver from 'semver';
|
||||||
import os = require('os');
|
import * as exec from '@actions/exec';
|
||||||
import path = require('path');
|
import * as core from '@actions/core';
|
||||||
import hc = require('@actions/http-client');
|
import * as io from '@actions/io';
|
||||||
|
|
||||||
const toolDir = path.join(__dirname, 'runner', 'tools');
|
|
||||||
const tempDir = path.join(__dirname, 'runner', 'temp');
|
|
||||||
|
|
||||||
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
|
||||||
process.env['RUNNER_TEMP'] = tempDir;
|
|
||||||
import * as installer from '../src/installer';
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
import {IS_WINDOWS} from '../src/utils';
|
||||||
|
import {QualityOptions} from '../src/setup-dotnet';
|
||||||
|
|
||||||
describe('installer tests', () => {
|
describe('installer tests', () => {
|
||||||
beforeAll(async () => {
|
const env = process.env;
|
||||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
|
||||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
beforeEach(() => {
|
||||||
process.env.RUNNER_TEMP = tempDir;
|
jest.resetModules();
|
||||||
process.env.DOTNET_ROOT = '';
|
process.env = {...env};
|
||||||
await io.rmRF(toolDir);
|
|
||||||
await io.rmRF(tempDir);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
describe('DotnetCoreInstaller tests', () => {
|
||||||
try {
|
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||||
await io.rmRF(toolDir);
|
const warningSpy = jest.spyOn(core, 'warning');
|
||||||
await io.rmRF(tempDir);
|
const whichSpy = jest.spyOn(io, 'which');
|
||||||
} catch {
|
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
||||||
console.log('Failed to remove test directories');
|
|
||||||
}
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
describe('installDotnet() tests', () => {
|
||||||
await getDotnet('3.1.201');
|
whichSpy.mockImplementation(() => Promise.resolve('PathToShell'));
|
||||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
|
||||||
} else {
|
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
it('should throw the error in case of non-zero exit code of the installation script. The error message should contain logs.', async () => {
|
||||||
expect(process.env.PATH).toBeDefined;
|
const inputVersion = '3.1.100';
|
||||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
const inputQuality = '' as QualityOptions;
|
||||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
const errorMessage = 'fictitious error message!';
|
||||||
}, 600000); //This needs some time to download on "slower" internet connections
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 1,
|
||||||
|
stdout: '',
|
||||||
|
stderr: errorMessage
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
await expect(dotnetInstaller.installDotnet()).rejects.toThrow(
|
||||||
|
`Failed to install dotnet, exit code: 1. ${errorMessage}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Acquires generic version of dotnet if no matching version is installed', async () => {
|
it('should return version of .NET SDK after installation complete', async () => {
|
||||||
await getDotnet('3.1');
|
const inputVersion = '3.1.100';
|
||||||
var directory = fs
|
const inputQuality = '' as QualityOptions;
|
||||||
.readdirSync(path.join(toolDir, 'sdk'))
|
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||||
.filter(fn => fn.startsWith('3.1.'));
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
expect(directory.length > 0).toBe(true);
|
return Promise.resolve({
|
||||||
if (IS_WINDOWS) {
|
exitCode: 0,
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
stdout: `${stdout}`,
|
||||||
} else {
|
stderr: ''
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
});
|
||||||
}
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
expect(process.env.DOTNET_ROOT).toBeDefined;
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
expect(process.env.PATH).toBeDefined;
|
inputVersion,
|
||||||
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
inputQuality
|
||||||
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
);
|
||||||
}, 600000); //This needs some time to download on "slower" internet connections
|
const installedVersion = await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
it('Throws if no location contains correct dotnet version', async () => {
|
expect(installedVersion).toBe(inputVersion);
|
||||||
let thrown = false;
|
});
|
||||||
try {
|
|
||||||
await getDotnet('1000.0.0');
|
|
||||||
} catch {
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
expect(thrown).toBe(true);
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
it('Uses an up to date bash download script', async () => {
|
it(`should supply 'version' argument to the installation script if supplied version is in A.B.C syntax`, async () => {
|
||||||
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
const inputVersion = '6.0.300';
|
||||||
allowRetries: true,
|
const inputQuality = '' as QualityOptions;
|
||||||
maxRetries: 3
|
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||||
|
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 0,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
const scriptArguments = (
|
||||||
|
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||||
|
).join(' ');
|
||||||
|
const expectedArgument = IS_WINDOWS
|
||||||
|
? `-Version ${inputVersion}`
|
||||||
|
: `--version ${inputVersion}`;
|
||||||
|
|
||||||
|
expect(scriptArguments).toContain(expectedArgument);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should warn if the 'quality' input is set and the supplied version is in A.B.C syntax`, async () => {
|
||||||
|
const inputVersion = '6.0.300';
|
||||||
|
const inputQuality = 'ga' as QualityOptions;
|
||||||
|
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 0,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
expect(warningSpy).toHaveBeenCalledWith(
|
||||||
|
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should warn if the 'quality' input is set and version isn't in A.B.C syntax but major tag is lower then 6`, async () => {
|
||||||
|
const inputVersion = '3.1';
|
||||||
|
const inputQuality = 'ga' as QualityOptions;
|
||||||
|
const stdout = `Fictitious dotnet version 3.1.100 is installed`;
|
||||||
|
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 0,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
expect(warningSpy).toHaveBeenCalledWith(
|
||||||
|
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
|
||||||
|
`should supply 'quality' argument to the installation script if quality input is set and version (%s) is not in A.B.C syntax`,
|
||||||
|
async inputVersion => {
|
||||||
|
const inputQuality = 'ga' as QualityOptions;
|
||||||
|
const exitCode = 0;
|
||||||
|
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: exitCode,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
const scriptArguments = (
|
||||||
|
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||||
|
).join(' ');
|
||||||
|
const expectedArgument = IS_WINDOWS
|
||||||
|
? `-Quality ${inputQuality}`
|
||||||
|
: `--quality ${inputQuality}`;
|
||||||
|
|
||||||
|
expect(scriptArguments).toContain(expectedArgument);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
|
||||||
|
`should supply 'channel' argument to the installation script if version (%s) isn't in A.B.C syntax`,
|
||||||
|
async inputVersion => {
|
||||||
|
const inputQuality = '' as QualityOptions;
|
||||||
|
const exitCode = 0;
|
||||||
|
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: exitCode,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
const scriptArguments = (
|
||||||
|
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||||
|
).join(' ');
|
||||||
|
const expectedArgument = IS_WINDOWS
|
||||||
|
? `-Channel 6.0`
|
||||||
|
: `--channel 6.0`;
|
||||||
|
|
||||||
|
expect(scriptArguments).toContain(expectedArgument);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
it(`should supply '-ProxyAddress' argument to the installation script if env.variable 'https_proxy' is set`, async () => {
|
||||||
|
process.env['https_proxy'] = 'https://proxy.com';
|
||||||
|
const inputVersion = '6.0.100';
|
||||||
|
const inputQuality = '' as QualityOptions;
|
||||||
|
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
|
||||||
|
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 0,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
const scriptArguments = (
|
||||||
|
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||||
|
).join(' ');
|
||||||
|
|
||||||
|
expect(scriptArguments).toContain(
|
||||||
|
`-ProxyAddress ${process.env['https_proxy']}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should supply '-ProxyBypassList' argument to the installation script if env.variable 'no_proxy' is set`, async () => {
|
||||||
|
process.env['no_proxy'] = 'first.url,second.url';
|
||||||
|
const inputVersion = '6.0.100';
|
||||||
|
const inputQuality = '' as QualityOptions;
|
||||||
|
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
|
||||||
|
|
||||||
|
getExecOutputSpy.mockImplementation(() => {
|
||||||
|
return Promise.resolve({
|
||||||
|
exitCode: 0,
|
||||||
|
stdout: `${stdout}`,
|
||||||
|
stderr: ''
|
||||||
|
});
|
||||||
|
});
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => inputVersion);
|
||||||
|
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
inputVersion,
|
||||||
|
inputQuality
|
||||||
|
);
|
||||||
|
|
||||||
|
await dotnetInstaller.installDotnet();
|
||||||
|
|
||||||
|
const scriptArguments = (
|
||||||
|
getExecOutputSpy.mock.calls[0][1] as string[]
|
||||||
|
).join(' ');
|
||||||
|
|
||||||
|
expect(scriptArguments).toContain(
|
||||||
|
`-ProxyBypassList ${process.env['no_proxy']}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
|
||||||
'https://dot.net/v1/dotnet-install.sh'
|
|
||||||
);
|
|
||||||
expect(response.message.statusCode).toBe(200);
|
|
||||||
const upToDateContents: string = await response.readBody();
|
|
||||||
const currentContents: string = fs
|
|
||||||
.readFileSync(
|
|
||||||
path.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
|
||||||
)
|
|
||||||
.toString();
|
|
||||||
expect(normalizeFileContents(currentContents)).toBe(
|
|
||||||
normalizeFileContents(upToDateContents)
|
|
||||||
);
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
it('Uses an up to date powershell download script', async () => {
|
describe('addToPath() tests', () => {
|
||||||
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
it(`should export DOTNET_ROOT env.var with value from DOTNET_INSTALL_DIR env.var`, async () => {
|
||||||
allowRetries: true,
|
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
|
||||||
maxRetries: 3
|
installer.DotnetCoreInstaller.addToPath();
|
||||||
|
const dotnet_root = process.env['DOTNET_ROOT'];
|
||||||
|
expect(dotnet_root).toBe(process.env['DOTNET_INSTALL_DIR']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should export value from DOTNET_INSTALL_DIR env.var to the PATH`, async () => {
|
||||||
|
process.env['DOTNET_INSTALL_DIR'] = 'fictitious/dotnet/install/dir';
|
||||||
|
installer.DotnetCoreInstaller.addToPath();
|
||||||
|
const path = process.env['PATH'];
|
||||||
|
expect(path).toContain(process.env['DOTNET_INSTALL_DIR']);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
const response: hc.HttpClientResponse = await httpCallbackClient.get(
|
});
|
||||||
'https://dot.net/v1/dotnet-install.ps1'
|
|
||||||
);
|
describe('DotnetVersionResolver tests', () => {
|
||||||
expect(response.message.statusCode).toBe(200);
|
describe('createDotNetVersion() tests', () => {
|
||||||
const upToDateContents: string = await response.readBody();
|
each([
|
||||||
const currentContents: string = fs
|
'3.1',
|
||||||
.readFileSync(
|
'3.x',
|
||||||
path.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
'3.1.x',
|
||||||
)
|
'3.1.*',
|
||||||
.toString();
|
'3.1.X',
|
||||||
expect(normalizeFileContents(currentContents)).toBe(
|
'3.1.2',
|
||||||
normalizeFileContents(upToDateContents)
|
'3.1.0-preview1',
|
||||||
);
|
'6.0.2xx'
|
||||||
}, 30000);
|
]).test(
|
||||||
|
'if valid version is supplied (%s), it should return version object with some value',
|
||||||
|
async version => {
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
const versionObject =
|
||||||
|
await dotnetVersionResolver.createDotNetVersion();
|
||||||
|
|
||||||
|
expect(!!versionObject.value).toBe(true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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 is supplied (%s), it should throw',
|
||||||
|
async version => {
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||||
|
).rejects.toThrow();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each(['3', '3.1', '3.1.x', '3.1.*', '3.1.X', '6.0.2xx']).test(
|
||||||
|
"if version that can be resolved to 'channel' option is supplied (%s), it should set type to 'channel' in version object",
|
||||||
|
async version => {
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
const versionObject =
|
||||||
|
await dotnetVersionResolver.createDotNetVersion();
|
||||||
|
|
||||||
|
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.2xx']).test(
|
||||||
|
"if version that can be resolved to 'channel' option is supplied and its major tag is >= 6 (%s), it should set type to 'channel' and qualityFlag to 'true' in version object",
|
||||||
|
async version => {
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
const versionObject =
|
||||||
|
await dotnetVersionResolver.createDotNetVersion();
|
||||||
|
|
||||||
|
expect(versionObject.type.toLowerCase().includes('channel')).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(versionObject.qualityFlag).toBe(true);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each(['3.1.2', '3.1.0-preview1']).test(
|
||||||
|
"if version that can be resolved to 'version' option is supplied (%s), it should set quality flag to 'false' and type to 'version' in version object",
|
||||||
|
async version => {
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
const versionObject =
|
||||||
|
await dotnetVersionResolver.createDotNetVersion();
|
||||||
|
|
||||||
|
expect(versionObject.type.toLowerCase().includes('version')).toBe(
|
||||||
|
true
|
||||||
|
);
|
||||||
|
expect(versionObject.qualityFlag).toBe(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
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(/^-(Version|Channel)/);
|
||||||
|
const nonWindowsRegEx = new RegExp(/^--(version|channel)/);
|
||||||
|
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(windowsRegEx.test(versionObject.type)).toBe(true);
|
||||||
|
expect(nonWindowsRegEx.test(versionObject.type)).toBe(false);
|
||||||
|
} else {
|
||||||
|
expect(nonWindowsRegEx.test(versionObject.type)).toBe(true);
|
||||||
|
expect(windowsRegEx.test(versionObject.type)).toBe(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it(`should throw if dotnet-version is supplied in A.B.Cxx syntax with major tag lower that 5`, async () => {
|
||||||
|
const version = '3.0.1xx';
|
||||||
|
const dotnetVersionResolver = new installer.DotnetVersionResolver(
|
||||||
|
version
|
||||||
|
);
|
||||||
|
await expect(
|
||||||
|
async () => await dotnetVersionResolver.createDotNetVersion()
|
||||||
|
).rejects.toThrow(
|
||||||
|
`'dotnet-version' was supplied in invalid format: ${version}! The A.B.Cxx syntax is available since the .NET 5.0 release.`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function normalizeFileContents(contents: string): string {
|
|
||||||
return contents
|
|
||||||
.trim()
|
|
||||||
.replace(new RegExp('\r\n', 'g'), '\n')
|
|
||||||
.replace(new RegExp('\r', 'g'), '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getDotnet(version: string): Promise<void> {
|
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
|
||||||
await dotnetInstaller.installDotnet();
|
|
||||||
}
|
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace sample_csproj
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class Program
|
|
||||||
{
|
|
||||||
[TestMethod]
|
|
||||||
public void TestMethod1()
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello, World!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFrameworks>netcoreapp3.1;netcoreapp2.2</TargetFrameworks>
|
|
||||||
<RootNamespace>sample_csproj</RootNamespace>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- These packages will be downloaded over the network for testing proxy settings -->
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
|
||||||
<PackageReference Include="MSTest.TestAdapter" Version="2.1.0" />
|
|
||||||
<PackageReference Include="MSTest.TestFramework" Version="2.1.0" />
|
|
||||||
<PackageReference Include="coverlet.collector" Version="1.2.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,47 +1,173 @@
|
|||||||
import io = require('@actions/io');
|
import * as core from '@actions/core';
|
||||||
import fs = require('fs');
|
import fs from 'fs';
|
||||||
import os = require('os');
|
import semver from 'semver';
|
||||||
import path = require('path');
|
import * as auth from '../src/authutil';
|
||||||
|
|
||||||
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 {DotnetCoreInstaller} from '../src/installer';
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
|
||||||
|
|
||||||
describe('setup-dotnet tests', () => {
|
describe('setup-dotnet tests', () => {
|
||||||
beforeAll(async () => {
|
const inputs = {} as any;
|
||||||
process.env.RUNNER_TOOL_CACHE = toolDir;
|
|
||||||
process.env.DOTNET_INSTALL_DIR = toolDir;
|
const getInputSpy = jest.spyOn(core, 'getInput');
|
||||||
process.env.RUNNER_TEMP = tempDir;
|
const getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
|
||||||
await io.rmRF(toolDir);
|
const setFailedSpy = jest.spyOn(core, 'setFailed');
|
||||||
await io.rmRF(tempDir);
|
const warningSpy = jest.spyOn(core, 'warning');
|
||||||
|
const debugSpy = jest.spyOn(core, 'debug');
|
||||||
|
const infoSpy = jest.spyOn(core, 'info');
|
||||||
|
const setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||||
|
|
||||||
|
const existsSyncSpy = jest.spyOn(fs, 'existsSync');
|
||||||
|
|
||||||
|
const maxSatisfyingSpy = jest.spyOn(semver, 'maxSatisfying');
|
||||||
|
|
||||||
|
const installDotnetSpy = jest.spyOn(
|
||||||
|
DotnetCoreInstaller.prototype,
|
||||||
|
'installDotnet'
|
||||||
|
);
|
||||||
|
const addToPathSpy = jest.spyOn(DotnetCoreInstaller, 'addToPath');
|
||||||
|
|
||||||
|
const configAuthenticationSpy = jest.spyOn(auth, 'configAuthentication');
|
||||||
|
|
||||||
|
describe('run() tests', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
getMultilineInputSpy.mockImplementation(input => inputs[input as string]);
|
||||||
|
getInputSpy.mockImplementation(input => inputs[input as string]);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail the action if global-json-file input is present, but the file does not exist in the file system', async () => {
|
||||||
|
inputs['global-json-file'] = 'fictitious.json';
|
||||||
|
inputs['dotnet-version'] = [];
|
||||||
|
|
||||||
|
const expectedErrorMessage = `The specified global.json file '${inputs['global-json-file']}' does not exist`;
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(`if 'dotnet-version' and 'global-json-file' inputs aren't present, should log into debug output, try to find global.json in the repo root, fail and log message into info output`, async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = [];
|
||||||
|
|
||||||
|
maxSatisfyingSpy.mockImplementation(() => null);
|
||||||
|
setOutputSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
const expectedDebugMessage =
|
||||||
|
'No version found, trying to find version from global.json';
|
||||||
|
const expectedInfoMessage = `The global.json wasn't found in the root directory. No .NET version will be installed.`;
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
|
||||||
|
expect(debugSpy).toHaveBeenCalledWith(expectedDebugMessage);
|
||||||
|
expect(existsSyncSpy).toHaveBeenCalled();
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(expectedInfoMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should fail the action if quality is supplied but its value is not supported', async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = ['6.0'];
|
||||||
|
inputs['dotnet-quality'] = 'fictitiousQuality';
|
||||||
|
|
||||||
|
const expectedErrorMessage = `Value '${inputs['dotnet-quality']}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`;
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call installDotnet() multiple times if dotnet-version multiline input is provided', async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = ['6.0', '7.0'];
|
||||||
|
inputs['dotnet-quality'] = '';
|
||||||
|
|
||||||
|
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(installDotnetSpy).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call addToPath() after installation complete', async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = ['6.0', '7.0'];
|
||||||
|
inputs['dotnet-quality'] = '';
|
||||||
|
|
||||||
|
installDotnetSpy.mockImplementation(() => Promise.resolve(''));
|
||||||
|
addToPathSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(addToPathSpy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call auth.configAuthentication() if source-url input is provided', async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = [];
|
||||||
|
inputs['dotnet-quality'] = '';
|
||||||
|
inputs['source-url'] = 'fictitious.source.url';
|
||||||
|
|
||||||
|
configAuthenticationSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(configAuthenticationSpy).toHaveBeenCalledWith(
|
||||||
|
inputs['source-url'],
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call auth.configAuthentication() with proper parameters if source-url and config-file inputs are provided', async () => {
|
||||||
|
inputs['global-json-file'] = '';
|
||||||
|
inputs['dotnet-version'] = [];
|
||||||
|
inputs['dotnet-quality'] = '';
|
||||||
|
inputs['source-url'] = 'fictitious.source.url';
|
||||||
|
inputs['config-file'] = 'fictitious.path';
|
||||||
|
|
||||||
|
configAuthenticationSpy.mockImplementation(() => {});
|
||||||
|
setOutputSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(configAuthenticationSpy).toHaveBeenCalledWith(
|
||||||
|
inputs['source-url'],
|
||||||
|
inputs['config-file']
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call setOutput() after installation complete successfully', async () => {
|
||||||
|
inputs['dotnet-version'] = ['6.0.300'];
|
||||||
|
|
||||||
|
installDotnetSpy.mockImplementation(() =>
|
||||||
|
Promise.resolve(`${inputs['dotnet-version']}`)
|
||||||
|
);
|
||||||
|
addToPathSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(setOutputSpy).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`shouldn't call setOutput() if parsing dotnet-installer logs failed`, async () => {
|
||||||
|
inputs['dotnet-version'] = ['6.0.300'];
|
||||||
|
const warningMessage = `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`;
|
||||||
|
|
||||||
|
installDotnetSpy.mockImplementation(() => Promise.resolve(null));
|
||||||
|
addToPathSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
|
||||||
|
expect(setOutputSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`shouldn't call setOutput() if actions didn't install .NET`, async () => {
|
||||||
|
inputs['dotnet-version'] = [];
|
||||||
|
const warningMessage = `The 'dotnet-version' output will not be set.`;
|
||||||
|
|
||||||
|
addToPathSpy.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await setup.run();
|
||||||
|
|
||||||
|
expect(infoSpy).toHaveBeenCalledWith(warningMessage);
|
||||||
|
expect(setOutputSpy).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
try {
|
|
||||||
await io.rmRF(path.join(process.cwd(), 'global.json'));
|
|
||||||
await io.rmRF(toolDir);
|
|
||||||
await io.rmRF(tempDir);
|
|
||||||
} catch {
|
|
||||||
console.log('Failed to remove test directories');
|
|
||||||
}
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
it('Acquires version of dotnet from global.json if no matching version is installed', async () => {
|
|
||||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
|
||||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.1.201"${os.EOL}}${os.EOL}}`;
|
|
||||||
if (!fs.existsSync(globalJsonPath)) {
|
|
||||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
|
||||||
}
|
|
||||||
await setup.run();
|
|
||||||
|
|
||||||
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
|
||||||
} else {
|
|
||||||
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
|
||||||
}
|
|
||||||
}, 400000);
|
|
||||||
});
|
});
|
||||||
|
@ -1,58 +1,117 @@
|
|||||||
if (!$args[0])
|
<#
|
||||||
{
|
.DESCRIPTION
|
||||||
throw "Must supply dotnet version argument"
|
Verifies that installed on the machine .NET SDK versions match the input patterns.
|
||||||
}
|
Optionally checks that the nuget.config file is generated correctly.
|
||||||
|
|
||||||
if (-Not (Test-Path "../nuget.config"))
|
.PARAMETER Patterns
|
||||||
{
|
Specifies the regular expression patterns that should be matched with the installed
|
||||||
throw "nuget file not generated correctly"
|
on the machine .NET SDK versions. The number of patterns should be equal to the number
|
||||||
|
of installed .NET versions.
|
||||||
|
|
||||||
|
.PARAMETER CheckNugetConfig
|
||||||
|
Switches the check for the existence of the nuget.config file.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
PS> .\verify-dotnet.ps1 -Paterns "^3.1.200$", "^6.0" -CheckNugetConfig
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string[]]$Patterns,
|
||||||
|
[switch]$CheckNugetConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
$PatternsList = [System.Collections.ArrayList]($Patterns)
|
||||||
|
|
||||||
|
if ($CheckNugetConfig.IsPresent -and !(Test-Path "../nuget.config")) {
|
||||||
|
throw "The nuget.config file is not generated correctly."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Write-Host "These patterns were supplied to the script: $($PatternsList -join ', ')."
|
||||||
$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path }
|
$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path }
|
||||||
Write-Host "Found '$dotnet'"
|
Write-Host "Found: '$dotnet'"
|
||||||
|
|
||||||
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
|
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
||||||
Write-Host "Version $version"
|
$Versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
||||||
if ($version -ne $args[0])
|
Write-Host "Found installed versions: $($Versions -join ', ')."
|
||||||
{
|
$InstalledVersionCount = $Versions.Count
|
||||||
Write-Host "PATH='$env:path'"
|
|
||||||
throw "Unexpected version"
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($args[1])
|
foreach($version in $Versions)
|
||||||
{
|
{
|
||||||
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
foreach($pattern in $PatternsList)
|
||||||
$version = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
|
||||||
Write-Host "Version $version"
|
|
||||||
if (-not ($version -contains $args[1]))
|
|
||||||
{
|
{
|
||||||
Write-Host "PATH='$env:path'"
|
if ($version -match $pattern)
|
||||||
throw "Unexpected version"
|
{
|
||||||
|
$PatternsList.Remove($pattern)
|
||||||
|
$InstalledVersionCount--
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Building sample csproj"
|
if ( $InstalledVersionCount -ne 0)
|
||||||
& $dotnet build __tests__/sample-csproj/ --no-cache
|
|
||||||
if ($LASTEXITCODE -ne 0)
|
|
||||||
{
|
{
|
||||||
throw "Unexpected exit code $LASTEXITCODE"
|
throw "An unexpected version of Dotnet is found on the machine, please check the correctness of the -Patterns input."
|
||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Testing compiled app"
|
$workingDir = Get-Location
|
||||||
$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
|
$testProjectDir = "./__tests__/e2e-test-csproj"
|
||||||
Write-Host "Sample output: $sample_output"
|
Write-Host "Changing directory to the $testProjectDir"
|
||||||
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
Set-Location $testProjectDir
|
||||||
if ($args[1])
|
|
||||||
|
$targetFrameworkVersionMap = @{
|
||||||
|
"1.0" = "netcoreapp1.0";
|
||||||
|
"1.1" = "netcoreapp1.1";
|
||||||
|
"2.0" = "netcoreapp2.0";
|
||||||
|
"2.1" = "netcoreapp2.1";
|
||||||
|
"2.2" = "netcoreapp2.2";
|
||||||
|
"3.0" = "netcoreapp3.0";
|
||||||
|
"3.1" = "netcoreapp3.1";
|
||||||
|
"5.0" = "net5.0";
|
||||||
|
"6.0" = "net6.0";
|
||||||
|
"7.0" = "net7.0";
|
||||||
|
"8.0" = "net8.0";
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($version in $Versions)
|
||||||
{
|
{
|
||||||
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
|
# Creating temporary global.json file inside e2e-test-csproj dir and setting exact version of .NET inside allows to override default behavior of .NET and run build and tests on that exact version.
|
||||||
|
Write-Host "Creating temporary global.json file for $version .NET version."
|
||||||
|
& $dotnet new globaljson --sdk-version $version --force | Out-Null
|
||||||
|
if (!(Test-Path "./global.json"))
|
||||||
{
|
{
|
||||||
throw "Unexpected output"
|
throw "An error occured while creating the global.json file. Exit code: $LASTEXITCODE"
|
||||||
}
|
}
|
||||||
}
|
Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)."
|
||||||
else
|
|
||||||
{
|
# Environment variable TEST_TARGET_FRAMEWORK is used inside the test.csproj file to target required framework version
|
||||||
if ($sample_output -notlike "*Test Run Successful.*")
|
$version -match "^(?<key>\d+\.\d+)" | Out-Null
|
||||||
|
if (!($targetFrameworkVersionMap.ContainsKey($Matches.key)))
|
||||||
{
|
{
|
||||||
throw "Unexpected output"
|
throw "The map with the framework targets doesn't contain a target name for the version $version."
|
||||||
}
|
}
|
||||||
|
Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMap[$Matches.key])"
|
||||||
|
[Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMap[$Matches.key]))
|
||||||
|
|
||||||
|
Write-Host "Building test C# project with $version .NET version."
|
||||||
|
& $dotnet build --no-cache
|
||||||
|
if ($LASTEXITCODE -ne 0)
|
||||||
|
{
|
||||||
|
throw "Building process is not successful, exit code: $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Testing compiled C# project with $version .NET version."
|
||||||
|
& $dotnet test --no-build
|
||||||
|
if ($LASTEXITCODE -ne 0)
|
||||||
|
{
|
||||||
|
throw "Testing process is not successful, exit code: $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Tests are completed successfully!"
|
||||||
|
|
||||||
|
Write-Host "Removing temporary global.json file."
|
||||||
|
Remove-Item ./global.json
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Set-Location $workingDir
|
@ -1,44 +0,0 @@
|
|||||||
if [ -z "$1" ]; then
|
|
||||||
echo "Must supply dotnet version argument"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f "../nuget.config" ]; then
|
|
||||||
echo "nuget file not generated correctly"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
dotnet_version="$(dotnet --version)"
|
|
||||||
echo "Found dotnet version '$dotnet_version'"
|
|
||||||
if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
|
||||||
echo "Unexpected version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$2" ]; then
|
|
||||||
dotnet_version="$(dotnet --list-sdks)"
|
|
||||||
echo "Found dotnet version '$dotnet_version'"
|
|
||||||
if [ -z "$(echo $dotnet_version | grep $2)" ]; then
|
|
||||||
echo "Unexpected version"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Building sample csproj"
|
|
||||||
dotnet build __tests__/sample-csproj/ --no-cache || exit 1
|
|
||||||
|
|
||||||
echo "Testing compiled app"
|
|
||||||
sample_output=$(dotnet test __tests__/sample-csproj/ --no-build)
|
|
||||||
echo "Sample output: $sample_output"
|
|
||||||
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
|
||||||
if [ -n "$2" ]; then
|
|
||||||
if [ -z "$(echo $sample_output | grep "Test Run Successful.*Test Run Successful.")" ]; then
|
|
||||||
echo "Unexpected output"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then
|
|
||||||
echo "Unexpected output"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
if [[ "$(git status --porcelain)" != "" ]]; then
|
|
||||||
echo ----------------------------------------
|
|
||||||
echo git status
|
|
||||||
echo ----------------------------------------
|
|
||||||
git status
|
|
||||||
echo ----------------------------------------
|
|
||||||
echo git diff
|
|
||||||
echo ----------------------------------------
|
|
||||||
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
|
|
||||||
fi
|
|
@ -1,90 +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.1.x', '3.1'],
|
|
||||||
['1.1.*', '1.1'],
|
|
||||||
['2.0', '2.0']
|
|
||||||
]).test("Generic version '%s' should be '%s'", (vers, resVers) => {
|
|
||||||
let versInfo = new installer.DotNetVersionInfo(vers);
|
|
||||||
|
|
||||||
expect(versInfo.isExactVersion()).toBe(false);
|
|
||||||
expect(versInfo.version()).toBe(resVers);
|
|
||||||
});
|
|
||||||
|
|
||||||
each([
|
|
||||||
'',
|
|
||||||
'.',
|
|
||||||
'..',
|
|
||||||
' . ',
|
|
||||||
'. ',
|
|
||||||
' .',
|
|
||||||
' . . ',
|
|
||||||
' .. ',
|
|
||||||
' . ',
|
|
||||||
'-1.-1',
|
|
||||||
'-1',
|
|
||||||
'-1.-1.-1',
|
|
||||||
'..3',
|
|
||||||
'1..3',
|
|
||||||
'1..',
|
|
||||||
'.2.3',
|
|
||||||
'.2.x',
|
|
||||||
'1',
|
|
||||||
'2.x',
|
|
||||||
'*.*.1',
|
|
||||||
'*.1',
|
|
||||||
'*.',
|
|
||||||
'1.2.',
|
|
||||||
'1.2.-abc',
|
|
||||||
'a.b',
|
|
||||||
'a.b.c',
|
|
||||||
'a.b.c-preview',
|
|
||||||
' 0 . 1 . 2 '
|
|
||||||
]).test("Malformed version '%s' should throw", vers => {
|
|
||||||
expect(() => new installer.DotNetVersionInfo(vers)).toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
13
action.yml
13
action.yml
@ -1,18 +1,25 @@
|
|||||||
name: 'Setup .NET Core SDK'
|
name: 'Setup .NET Core SDK'
|
||||||
description: 'Set up a specific version of the .NET Core CLI in the PATH and set up authentication to a private NuGet repository'
|
description: 'Used to build and publish .NET source. Set up a specific version of the .NET and authentication to private NuGet repository'
|
||||||
author: 'GitHub'
|
author: 'GitHub'
|
||||||
branding:
|
branding:
|
||||||
icon: play
|
icon: play
|
||||||
color: green
|
color: green
|
||||||
inputs:
|
inputs:
|
||||||
dotnet-version:
|
dotnet-version:
|
||||||
description: 'SDK version to use. 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, 6.0.2xx'
|
||||||
|
dotnet-quality:
|
||||||
|
description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.'
|
||||||
|
global-json-file:
|
||||||
|
description: 'Optional global.json location, if your global.json isn''t located in the root of the repo.'
|
||||||
source-url:
|
source-url:
|
||||||
description: 'Optional package source for which to set up authentication. Will consult any existing NuGet.config in the root of the repo and provide a temporary NuGet.config using the NUGET_AUTH_TOKEN environment variable as a ClearTextPassword'
|
description: 'Optional package source for which to set up authentication. Will consult any existing NuGet.config in the root of the repo and provide a temporary NuGet.config using the NUGET_AUTH_TOKEN environment variable as a ClearTextPassword'
|
||||||
owner:
|
owner:
|
||||||
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
|
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.'
|
||||||
|
outputs:
|
||||||
|
dotnet-version:
|
||||||
|
description: 'Contains the installed by action .NET SDK version for reuse.'
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node16'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
32427
dist/index.js
vendored
32427
dist/index.js
vendored
File diff suppressed because one or more lines are too long
57
docs/adrs/v3-setup-dotnet.md
Normal file
57
docs/adrs/v3-setup-dotnet.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# v3 setup-dotnet
|
||||||
|
|
||||||
|
Date: 2022-08-25
|
||||||
|
Status: Accepted
|
||||||
|
|
||||||
|
# Context
|
||||||
|
- GitHub-hosted Ubuntu and Windows runners have .NET versions pre-installed in system directories
|
||||||
|
- Ubuntu:`/usr/share/dotnet`
|
||||||
|
- Windows:`C:\Program Files\dotnet`
|
||||||
|
- V1 version of Action installs .NET to the user's directory
|
||||||
|
- Ubuntu:`/home/runner/.dotnet`
|
||||||
|
- Windows: `C:\Users\runneradmin\AppData\Local\Microsoft\dotnet`
|
||||||
|
- It means that action always downloads and installs .NET version even if it is pre-installed. Also after using the action all pre-installed .NET versions are unavailable because `DOTNET_ROOT` is overridden to the user's directory.
|
||||||
|
The behavior is different for macOS runners because the pre-installation directory matches the one that is used by action. It means action can use pre-installed versions if they exist, which speeds up the customer's workflow.
|
||||||
|
|
||||||
|
- The different behavior of the setup task on Ubuntu, Windows and macOS runners is unclear and confusing for customers.
|
||||||
|
|
||||||
|
- .NET supports installing and using multiple versions of .NET SDK and .NET runtime side-by-side. .NET CLI will use the latest installed .NET SDK and .NET runtime versions if there is no global.json file containing a different version. This behavior is defined by .NET design (https://docs.microsoft.com/en-us/dotnet/core/versions/selection).
|
||||||
|
|
||||||
|
- The action contains logic to handle inputs with wildcards, for example `5.0.x`, `5.0.*`, `5.x` or `5.*`. This logic uses metadata from `https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/releases-index.json` to retrieve the list of available releases and get the latest release version for the specified major and/or minor version from the input. After that, installer script (`dotnet-install.ps1` for Windows or `dotnet-install.sh` for Linux and macOS) installs the required SDK using exact version as a parameter.
|
||||||
|
|
||||||
|
# Proposal
|
||||||
|
|
||||||
|
- Change .NET installation path for Windows and Ubuntu images to match the location of pre-installed versions by using `-InstallDir` (Windows) and `--install-dir` (Ubuntu) properties for installer scripts:
|
||||||
|
https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script
|
||||||
|
|
||||||
|
- Simplify and in some cases fully get rid of logic for resolving wildcard versions and start relying on [official installer scripts provided by .NET Core team](https://github.com/dotnet/install-scripts).
|
||||||
|
The execution `dotnet-install.ps1 -Channel 5.0` installs the latest patch version for 5.0 SDK. If SDK is in the prerelease phase, the latest prerelease version (preview or rc) will be installed.
|
||||||
|
|
||||||
|
Inputs with wildcards in the patch tag (`5.0.x` or `5.0.*`) can be handled by passing major and minor versions to the installer script directly as a `channel` parameter. This parameter supports two-part version in `X.Y` format as input value ([see installer scripts documentation](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script)).
|
||||||
|
|
||||||
|
Inputs with wildcards in the minor tag (`3.x` or `3.*`) can be handled like that:
|
||||||
|
1. The request is sent to MS dist and the `releases.json` file is got
|
||||||
|
2. The action gets the latest possible channel version out of retrieved `releases.json` that satisfies input major tag (e.g. for `3.x` nowadays it's `3.1`)
|
||||||
|
3. Retrieved channel version is passed to installer script directly as `channel` parameter.
|
||||||
|
|
||||||
|
> **Note:** Using the `channel` parameter of the MS .NET installer scripts will allow us to use the `quality` parameter as well. This functionality is also asked for by our customers.
|
||||||
|
|
||||||
|
# Breaking changes
|
||||||
|
- The presence of pre-installed .NET versions that are higher than the version that the users specify in the setup task can be breaking for some customers, who expect only one installed .NET version on the runner after using the setup task. If a user doesn't have .NET version specified in project file, the `dotnet` will use the latest installed version instead of provided in the setup task.
|
||||||
|
> **Note:** It is the biggest deal in this ADR.
|
||||||
|
|
||||||
|
Previously, when a user would specify a .NET version, this exact version was used by the `dotnet` command by default (because it was installed in a separate folder and there were no other.NET versions in that folder)
|
||||||
|
In the proposal, the specified version will be installed on the machine but the latest version will be used by the `dotnet` command by default (because specified version will be installed alongside with pre-installed .NET versions).
|
||||||
|
Based on [official .NET documentation](https://docs.microsoft.com/en-us/dotnet/core/versions/selection), it is expected behavior and how it works on user's local machine with multiple installed .NET versions but some customer's workflows could be broken because they already rely on current behavior.
|
||||||
|
|
||||||
|
To avoid breaking customers, we will need to release a new major task version (v3).
|
||||||
|
|
||||||
|
# v3-preview
|
||||||
|
There will be a v3-preview branch that will be created for development and testing. Any changes will first be merged into the v3-preview branch. After a period of testing & verification, the v3-preview branch will be merged into the main branch and a v3 tag will be created. Any GitHub public documentation and starter workflows that mention setup-dotnet will then be updated to use v3 instead of v2:
|
||||||
|
- [README.md](https://github.com/actions/setup-dotnet/blob/main/README.md)
|
||||||
|
- [action.yml](https://github.com/actions/setup-dotnet/blob/main/action.yml)
|
||||||
|
- [GitHub docs](https://docs.github.com/en/actions/guides/building-and-testing-net#using-a-specific-net-version)
|
||||||
|
- Starter-workflow yamls: [#1](https://github.com/actions/starter-workflows/blob/main/ci/dotnet.yml#L17), [#2](https://github.com/actions/starter-workflows/blob/main/ci/dotnet-desktop.yml#L72)
|
||||||
|
|
||||||
|
# Consequences
|
||||||
|
- Customers will be able to use pre-installed .NET versions with setup-dotnet action on Windows and Ubuntu
|
@ -1,24 +1,114 @@
|
|||||||
# Contributors
|
# Contributors
|
||||||
|
|
||||||
Thank you for contributing! This action is targetted around setting up the dotnet cli and related sdks for GitHub actions. As part of that we use proxy settings (for self-hosted runners) and set-up nuget authentication for private feeds.
|
Thank you for contributing!
|
||||||
|
|
||||||
If you would like to contribute there are a few things to consider:
|
We have prepared a short guide so that the process of making your contribution is as simple and clear as possible. Please check it out before you contribute!
|
||||||
|
|
||||||
## Commands to use
|
## How can I contribute...
|
||||||
|
|
||||||
- npm run build - Compiles the action into a single js file at dist/index.js (Please check in the changes made by this command)
|
* [Contribute Documentation:green_book:](#contribute-documentation)
|
||||||
- npm run test - Runs all tests under __tests__
|
|
||||||
- npm run format - Runs formatting required to pass the lint test (Please check in the changes made by this command)
|
|
||||||
- npm run update-installers - Updates the install-dotnet scripts in externals (Please check in the changes made by this command)
|
|
||||||
|
|
||||||
## To check in or not to check in
|
* [Contribute Code :computer:](#contribute-code)
|
||||||
|
|
||||||
- Do check in source (src)
|
* [Provide Support on Issues:pencil:](#provide-support-on-issues)
|
||||||
- Do check in index file (dist)
|
|
||||||
- Do check in updates to install-dotnet scripts (externals)
|
|
||||||
- Do not check in build output (lib)
|
|
||||||
- Do not check in runtime (node_modules)
|
|
||||||
|
|
||||||
## Writing tests
|
* [Review Pull Requests:mag:](#review-pull-requests)
|
||||||
|
|
||||||
With any contribution please take time to consider how this can be tested to maintain high quality. Current tests can be found in the folder __tests__ for examples.
|
## Contribute documentation
|
||||||
|
|
||||||
|
Documentation is a super important, critical part of this project. Docs are how we keep track of what we're doing, how, and why. It's how we stay on the same page about our policies and how we tell others everything they need to be able to use this project or contribute to it.
|
||||||
|
|
||||||
|
Documentation contributions of any size are welcome! Feel free to contribute even if you're just rewording a sentence to be more clear, or fixing a spelling mistake!
|
||||||
|
|
||||||
|
**How to contribute:**
|
||||||
|
|
||||||
|
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a convenient way of commenting and amending the proposed changes.
|
||||||
|
|
||||||
|
- Please check that no one else has already created a pull request with these or similar changes
|
||||||
|
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
||||||
|
- Make sure your changes are formatted properly and consistently with the rest of the documentation
|
||||||
|
- Re-read what you wrote, and run a spellchecker on it to make sure you didn't miss anything
|
||||||
|
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
||||||
|
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
||||||
|
|
||||||
|
**Once you've filed the pull request:**
|
||||||
|
|
||||||
|
- Maintainers will review your pull request
|
||||||
|
- If a maintainer requests changes, first of all, try to think about this request critically and only after that implement and request another review
|
||||||
|
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action and updating the major tag
|
||||||
|
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
||||||
|
|
||||||
|
## Contribute code
|
||||||
|
|
||||||
|
We like code commits a lot! They're super handy, and they keep the project going and doing the work it needs to do to be useful to others.
|
||||||
|
|
||||||
|
Code contributions of just about any size are acceptable!
|
||||||
|
|
||||||
|
The main difference between code contributions and documentation contributions is that contributing code requires the inclusion of relevant tests for the code being added or changed. Contributions without accompanying tests will be held off until a test is added unless the maintainers consider the specific tests to be either impossible or way too much of a burden for such a contribution.
|
||||||
|
|
||||||
|
**How to contribute:**
|
||||||
|
|
||||||
|
Pull requests are the easiest way to contribute changes to git repos at GitHub. They are the preferred contribution method, as they offer a convenient way of commenting and amending the proposed changes.
|
||||||
|
|
||||||
|
- Please check that no one else has already created a pull request with these or similar changes
|
||||||
|
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
|
||||||
|
- Format, build and test changes
|
||||||
|
- Make sure your changes are well formatted and that all tests are passing
|
||||||
|
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
|
||||||
|
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
|
||||||
|
|
||||||
|
**Learn more about how to work with the repository:**
|
||||||
|
|
||||||
|
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
|
||||||
|
- To comply with the code style, **you need to run the `format` script**
|
||||||
|
- To lint the code, **you need to run the `lint:fix` script**
|
||||||
|
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
|
||||||
|
|
||||||
|
**Learn more about how to implement tests:**
|
||||||
|
|
||||||
|
Adding or changing tests is an integral part of making a change to the code.
|
||||||
|
Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [e2e-tests.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/e2e-tests.yml).
|
||||||
|
|
||||||
|
- The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality
|
||||||
|
- Tests should cover a successful execution, as well as some edge cases and possible errors
|
||||||
|
- As already mentioned, pull requests without tests will be considered more carefully by maintainers. If you are sure that in this situation the tests are not needed or cannot be implemented with a commensurate effort - please add this clarification message to your pull request
|
||||||
|
|
||||||
|
**Once you've filed the pull request:**
|
||||||
|
|
||||||
|
- CI will start automatically with some checks. Wait until the end of the execution and make sure that all checks passed successfully. If some checks fail, you can open them one by one, try to find the reason for failing and make changes to your code to resolve the problem
|
||||||
|
> Sometimes you may need to update the installers you can do this with the `npm run update-installers` command
|
||||||
|
- Maintainers will review your pull request
|
||||||
|
- If a maintainer requests changes, first of all, try to think about his request critically and only after that implement and request another review
|
||||||
|
- If your PR gets accepted, it will soon be merged into the main branch. But your contribution will take effect only after the release of a new version of the action and updating the major tag
|
||||||
|
> Sometimes maintainers reject pull requests and that's ok! Usually, along with rejection, we supply the reason for it. Nonetheless, we still really appreciate you taking the time to do it, and we don't take that lightly :heart:
|
||||||
|
|
||||||
|
## Provide support on issues
|
||||||
|
|
||||||
|
Helping out other users with their questions is an awesome way of contributing to any community. It's not uncommon for most of the issues on open source projects to be support-related questions by users trying to understand something they ran into or find their way around a known bug.
|
||||||
|
|
||||||
|
**To help other folks out with their questions:**
|
||||||
|
|
||||||
|
- Go to the [issue tracker](https://github.com/actions/setup-dotnet/issues)
|
||||||
|
- Read through the list until you find something that you're familiar enough with to answer to
|
||||||
|
- Respond to the issue with whatever details are needed to clarify the question, or get more details about what's going on
|
||||||
|
- Once the discussion wraps up and things are clarified, ask the original issue filer (or a maintainer) to close it for you
|
||||||
|
|
||||||
|
*Some notes on picking up support issues:*
|
||||||
|
|
||||||
|
- Avoid responding to issues you don't know you can answer accurately
|
||||||
|
- Try to refer to past issues with accepted answers as much as possible. Link to them from your replies
|
||||||
|
- Be kind and patient with users. Often, folks who have run into confusing things might be upset or impatient. This is natural. If you feel uncomfortable in conversation with them, it's better to stay away or withdraw from the issue.
|
||||||
|
|
||||||
|
> If some user is violating our code of conduct [standards](https://github.com/actions/setup-dotnet/blob/main/CODE_OF_CONDUCT.md#our-standards), refer to the [Enforcement](https://github.com/actions/setup-dotnet/blob/main/CODE_OF_CONDUCT.md#enforcement) section of the Code of Conduct to resolve the conflict
|
||||||
|
|
||||||
|
## Review pull requests
|
||||||
|
|
||||||
|
Another great way to contribute is to review pull request. Please, be extra kind: people who submit code/doc contributions are putting themselves in a pretty vulnerable position, and have put time and care into what they've done (even if that's not obvious to you!) Please, always respond with respect, and be understanding, but don't feel like you need to sacrifice your standards for their sake, either.
|
||||||
|
|
||||||
|
**How to review:**
|
||||||
|
|
||||||
|
- Go to the [pull requests](https://github.com/actions/setup-dotnet/pulls)
|
||||||
|
- Make sure you're familiar with the code or documentation is updated, unless it's a minor change (spellchecking, minor formatting, etc.)
|
||||||
|
- Review changes using the GitHub functionality. You can ask a clarifying question, point out an error or suggest an alternative.
|
||||||
|
> Note: You may ask for minor changes - "nitpicks", but consider whether they are real blockers to merging or not
|
||||||
|
- Submit your review, which may include comments, an approval, or a changes request
|
1353
externals/install-dotnet.ps1
vendored
1353
externals/install-dotnet.ps1
vendored
File diff suppressed because it is too large
Load Diff
1131
externals/install-dotnet.sh
vendored
1131
externals/install-dotnet.sh
vendored
File diff suppressed because it is too large
Load Diff
10771
package-lock.json
generated
10771
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
50
package.json
50
package.json
@ -1,23 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "setup-dotnet",
|
"name": "setup-dotnet",
|
||||||
"version": "1.0.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",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc && ncc build",
|
"build": "tsc && ncc build",
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"",
|
||||||
"test": "jest",
|
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"",
|
||||||
|
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix",
|
||||||
|
"prepare": "husky install",
|
||||||
|
"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"
|
||||||
},
|
},
|
||||||
"husky": {
|
|
||||||
"hooks": {
|
|
||||||
"//": "Tests are not run at push time since they can take 2-4 minutes to complete",
|
|
||||||
"pre-commit": "npm run format",
|
|
||||||
"pre-push": "npm run format-check"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/actions/setup-dotnet.git"
|
"url": "git+https://github.com/actions/setup-dotnet.git"
|
||||||
@ -30,26 +26,30 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.2.5",
|
"@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": "^25.2.3",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/node": "^12.12.62",
|
"@types/node": "^16.11.25",
|
||||||
"@types/semver": "^6.2.2",
|
"@types/semver": "^6.2.2",
|
||||||
"@zeit/ncc": "^0.21.1",
|
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||||
"husky": "^4.3.0",
|
"@typescript-eslint/parser": "^5.54.0",
|
||||||
"jest": "^26.4.2",
|
"@vercel/ncc": "^0.33.4",
|
||||||
"jest-circus": "^26.4.2",
|
"eslint": "^8.35.0",
|
||||||
"prettier": "^1.19.1",
|
"eslint-config-prettier": "^8.6.0",
|
||||||
"ts-jest": "^26.4.0",
|
"eslint-plugin-jest": "^27.2.1",
|
||||||
"typescript": "^3.9.7",
|
"husky": "^8.0.1",
|
||||||
|
"jest": "^27.2.5",
|
||||||
|
"jest-circus": "^27.2.5",
|
||||||
|
"prettier": "^2.8.4",
|
||||||
|
"ts-jest": "^27.0.5",
|
||||||
|
"typescript": "^4.8.4",
|
||||||
"wget-improved": "^3.2.1"
|
"wget-improved": "^3.2.1"
|
||||||
},
|
},
|
||||||
"jest": {
|
"jest": {
|
||||||
|
200
src/authutil.ts
200
src/authutil.ts
@ -2,18 +2,18 @@ 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,
|
||||||
existingFileLocation: string = '',
|
existingFileLocation = '',
|
||||||
processRoot: string = process.cwd()
|
processRoot: string = process.cwd()
|
||||||
) {
|
) {
|
||||||
const existingNuGetConfig: string = path.resolve(
|
const existingNuGetConfig: string = path.resolve(
|
||||||
processRoot,
|
processRoot,
|
||||||
existingFileLocation == '' ? 'nuget.config' : existingFileLocation
|
existingFileLocation === ''
|
||||||
|
? getExistingNugetConfig(processRoot)
|
||||||
|
: existingFileLocation
|
||||||
);
|
);
|
||||||
|
|
||||||
const tempNuGetConfig: string = path.resolve(
|
const tempNuGetConfig: string = path.resolve(
|
||||||
@ -25,23 +25,37 @@ export function configAuthentication(
|
|||||||
writeFeedToFile(feedUrl, existingNuGetConfig, tempNuGetConfig);
|
writeFeedToFile(feedUrl, existingNuGetConfig, tempNuGetConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isValidKey(key: string): boolean {
|
||||||
|
return /^[\w\-.]+$/i.test(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExistingNugetConfig(processRoot: string) {
|
||||||
|
const defaultConfigName = 'nuget.config';
|
||||||
|
const configFileNames = fs
|
||||||
|
.readdirSync(processRoot)
|
||||||
|
.filter(filename => filename.toLowerCase() === defaultConfigName);
|
||||||
|
if (configFileNames.length) {
|
||||||
|
return configFileNames[0];
|
||||||
|
}
|
||||||
|
return defaultConfigName;
|
||||||
|
}
|
||||||
|
|
||||||
function writeFeedToFile(
|
function writeFeedToFile(
|
||||||
feedUrl: string,
|
feedUrl: string,
|
||||||
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;
|
const sourceKeys: string[] = [];
|
||||||
let sourceKeys: string[] = [];
|
|
||||||
let owner: string = core.getInput('owner');
|
let owner: string = core.getInput('owner');
|
||||||
let sourceUrl: string = feedUrl;
|
const sourceUrl: string = feedUrl;
|
||||||
if (!owner) {
|
if (!owner) {
|
||||||
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}}'
|
||||||
);
|
);
|
||||||
@ -50,89 +64,133 @@ 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) {
|
||||||
|
const keystring = 'Source';
|
||||||
|
|
||||||
|
xmlSource[1].configuration.push({
|
||||||
|
packageSources: [
|
||||||
|
{
|
||||||
|
add: [],
|
||||||
|
':@': {
|
||||||
|
'@_key': keystring,
|
||||||
|
'@_value': sourceUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
if (sourceKeys.length == 0) {
|
|
||||||
let keystring = 'Source';
|
|
||||||
xml = xml
|
|
||||||
.ele('packageSources')
|
|
||||||
.ele('add', {key: keystring, value: sourceUrl})
|
|
||||||
.up()
|
|
||||||
.up();
|
|
||||||
sourceKeys.push(keystring);
|
sourceKeys.push(keystring);
|
||||||
}
|
}
|
||||||
xml = xml.ele('packageSourceCredentials');
|
|
||||||
|
|
||||||
|
const packageSourceCredentials: any[] = [];
|
||||||
sourceKeys.forEach(key => {
|
sourceKeys.forEach(key => {
|
||||||
if (key.indexOf(' ') > -1) {
|
if (!isValidKey(key)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"This action currently can't handle source names with spaces. Remove the space from your repo's NuGet.config and try again."
|
"Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
487
src/installer.ts
487
src/installer.ts
@ -2,278 +2,277 @@
|
|||||||
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 path from 'path';
|
||||||
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
import os from 'os';
|
||||||
import * as semver from 'semver';
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Note: No support for previews when using generic
|
|
||||||
let parts: string[] = version.split('.');
|
|
||||||
|
|
||||||
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
|
|
||||||
|
|
||||||
if (parts.length == 3 && parts[2] !== 'x' && parts[2] !== '*') {
|
|
||||||
this.throwInvalidVersionFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
let major = this.getVersionNumberOrThrow(parts[0]);
|
|
||||||
let minor = this.getVersionNumberOrThrow(parts[1]);
|
|
||||||
|
|
||||||
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 '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 {
|
const QUALITY_INPUT_MINIMAL_MAJOR_TAG = 6;
|
||||||
|
const LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG = 5;
|
||||||
|
export class DotnetVersionResolver {
|
||||||
|
private inputVersion: string;
|
||||||
|
private resolvedArgument: DotnetVersion;
|
||||||
|
|
||||||
constructor(version: string) {
|
constructor(version: string) {
|
||||||
this.version = version;
|
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) && !this.isLatestPatchSyntax()) {
|
||||||
let resultCode = 0;
|
throw new Error(
|
||||||
|
`The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (semver.valid(this.inputVersion)) {
|
||||||
|
this.createVersionArgument();
|
||||||
|
} else {
|
||||||
|
await this.createChannelArgument();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let calculatedVersion = await this.resolveVersion(
|
private isNumericTag(versionTag): boolean {
|
||||||
new DotNetVersionInfo(this.version)
|
return /^\d+$/.test(versionTag);
|
||||||
);
|
}
|
||||||
|
|
||||||
var envVariables: {[key: string]: string} = {};
|
private isLatestPatchSyntax() {
|
||||||
for (let key in process.env) {
|
const majorTag = this.inputVersion.match(
|
||||||
if (process.env[key]) {
|
/^(?<majorTag>\d+)\.\d+\.\d{1}x{2}$/
|
||||||
let value: any = process.env[key];
|
)?.groups?.majorTag;
|
||||||
envVariables[key] = value;
|
if (
|
||||||
}
|
majorTag &&
|
||||||
|
parseInt(majorTag) < LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return majorTag ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private createVersionArgument() {
|
||||||
|
this.resolvedArgument.type = 'version';
|
||||||
|
this.resolvedArgument.value = this.inputVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createChannelArgument() {
|
||||||
|
this.resolvedArgument.type = 'channel';
|
||||||
|
const [major, minor] = this.inputVersion.split('.');
|
||||||
|
if (this.isLatestPatchSyntax()) {
|
||||||
|
this.resolvedArgument.value = this.inputVersion;
|
||||||
|
} else if (this.isNumericTag(major) && this.isNumericTag(minor)) {
|
||||||
|
this.resolvedArgument.value = `${major}.${minor}`;
|
||||||
|
} else if (this.isNumericTag(major)) {
|
||||||
|
this.resolvedArgument.value = await this.getLatestByMajorTag(major);
|
||||||
|
} else {
|
||||||
|
// If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will default to "latest" by install-dotnet script.
|
||||||
|
this.resolvedArgument.value = 'LTS';
|
||||||
|
}
|
||||||
|
this.resolvedArgument.qualityFlag =
|
||||||
|
parseInt(major) >= QUALITY_INPUT_MINIMAL_MAJOR_TAG ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async createDotNetVersion(): Promise<DotnetVersion> {
|
||||||
|
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('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 (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']);
|
|
||||||
|
|
||||||
if (resultCode != 0) {
|
|
||||||
throw `Failed to install dotnet ${resultCode}. ${output}`;
|
|
||||||
}
|
}
|
||||||
|
return this.resolvedArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
// versionInfo - versionInfo of the SDK/Runtime
|
private async getLatestByMajorTag(majorTag: string): Promise<string> {
|
||||||
async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
|
|
||||||
if (versionInfo.isExactVersion()) {
|
|
||||||
return versionInfo.version();
|
|
||||||
}
|
|
||||||
|
|
||||||
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
||||||
allowRetries: true,
|
allowRetries: true,
|
||||||
maxRetries: 3
|
maxRetries: 3
|
||||||
});
|
});
|
||||||
|
const response = await httpClient.getJson<any>(
|
||||||
const releasesJsonUrl: string = await this.getReleasesJsonUrl(
|
DotnetVersionResolver.DotNetCoreIndexUrl
|
||||||
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()
|
|
||||||
) ||
|
|
||||||
semver.satisfies(
|
|
||||||
releaseInfo['sdk']['version-display'],
|
|
||||||
versionInfo.version()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Sort for latest version
|
|
||||||
releasesInfo = releasesInfo.sort((a, b) =>
|
|
||||||
semver.rcompare(a['sdk']['version'], b['sdk']['version'])
|
|
||||||
);
|
|
||||||
|
|
||||||
if (releasesInfo.length == 0) {
|
|
||||||
throw `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,
|
|
||||||
versionParts: string[]
|
|
||||||
): Promise<string> {
|
|
||||||
const response = await httpClient.getJson<any>(DotNetCoreIndexUrl);
|
|
||||||
const result = response.result || {};
|
const result = response.result || {};
|
||||||
let releasesInfo: any[] = result['releases-index'];
|
const releasesInfo: any[] = result['releases-index'];
|
||||||
|
|
||||||
releasesInfo = releasesInfo.filter((info: any) => {
|
const 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.
|
|
||||||
const sdkParts: string[] = info['channel-version'].split('.');
|
const sdkParts: string[] = info['channel-version'].split('.');
|
||||||
if (
|
return sdkParts[0] === majorTag;
|
||||||
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 `Could not find info for version ${versionParts.join(
|
throw new Error(
|
||||||
'.'
|
`Could not find info for version with major tag: "${majorTag}" at ${DotnetVersionResolver.DotNetCoreIndexUrl}`
|
||||||
)} at ${DotNetCoreIndexUrl}`;
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return releasesInfo[0]['releases.json'];
|
return releaseInfo['channel-version'];
|
||||||
}
|
}
|
||||||
|
|
||||||
private version: string;
|
static DotNetCoreIndexUrl =
|
||||||
|
'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(
|
||||||
|
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${this.version}. 'dotnet-quality' input is ignored.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async installDotnet(): Promise<string | null> {
|
||||||
|
const windowsDefaultOptions = [
|
||||||
|
'-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, stderr} = await exec.getExecOutput(
|
||||||
|
`"${scriptPath}"`,
|
||||||
|
scriptArguments,
|
||||||
|
getExecOutputOptions
|
||||||
|
);
|
||||||
|
if (exitCode) {
|
||||||
|
throw new Error(
|
||||||
|
`Failed to install dotnet, exit code: ${exitCode}. ${stderr}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.parseInstalledVersion(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseInstalledVersion(stdout: string): string | null {
|
||||||
|
const regex = /(?<version>\d+\.\d+\.\d+[a-z0-9._-]*)/gm;
|
||||||
|
const matchedResult = regex.exec(stdout);
|
||||||
|
|
||||||
|
if (!matchedResult) {
|
||||||
|
core.warning(`Failed to parse installed by the script version of .NET`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return matchedResult.groups!.version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,36 +1,75 @@
|
|||||||
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 {
|
||||||
//
|
//
|
||||||
// dotnet-version is optional, but needs to be provided for most use cases.
|
// dotnet-version is optional, but needs to be provided for most use cases.
|
||||||
// If supplied, install / use from the tool cache.
|
// If supplied, install / use from the tool cache.
|
||||||
|
// global-version-file may be specified to point to a specific global.json
|
||||||
|
// and will be used to install an additional version.
|
||||||
// If not supplied, look for version in ./global.json.
|
// If not supplied, look for version in ./global.json.
|
||||||
// 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 version = core.getInput('dotnet-version');
|
const versions = core.getMultilineInput('dotnet-version');
|
||||||
if (!version) {
|
const installedDotnetVersions: (string | null)[] = [];
|
||||||
|
|
||||||
|
const globalJsonFileInput = core.getInput('global-json-file');
|
||||||
|
if (globalJsonFileInput) {
|
||||||
|
const globalJsonPath = path.resolve(process.cwd(), globalJsonFileInput);
|
||||||
|
if (!fs.existsSync(globalJsonPath)) {
|
||||||
|
throw new Error(
|
||||||
|
`The specified global.json file '${globalJsonFileInput}' does not exist`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
versions.push(getVersionFromGlobalJson(globalJsonPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!versions.length) {
|
||||||
// Try to fall back to global.json
|
// Try to fall back to global.json
|
||||||
core.debug('No version found, trying to find version from global.json');
|
core.debug('No version found, trying to find version from global.json');
|
||||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||||
if (fs.existsSync(globalJsonPath)) {
|
if (fs.existsSync(globalJsonPath)) {
|
||||||
const globalJson = JSON.parse(
|
versions.push(getVersionFromGlobalJson(globalJsonPath));
|
||||||
fs.readFileSync(globalJsonPath, {encoding: 'utf8'})
|
} else {
|
||||||
|
core.info(
|
||||||
|
`The global.json wasn't found in the root directory. No .NET version will be installed.`
|
||||||
);
|
);
|
||||||
if (globalJson.sdk && globalJson.sdk.version) {
|
|
||||||
version = globalJson.sdk.version;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version) {
|
if (versions.length) {
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
const quality = core.getInput('dotnet-quality') as QualityOptions;
|
||||||
await dotnetInstaller.installDotnet();
|
|
||||||
|
if (quality && !qualityOptions.includes(quality)) {
|
||||||
|
throw new Error(
|
||||||
|
`Value '${quality}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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');
|
||||||
@ -39,11 +78,63 @@ export async function run() {
|
|||||||
auth.configAuthentication(sourceUrl, configFile);
|
auth.configAuthentication(sourceUrl, configFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outputInstalledVersion(installedDotnetVersions, globalJsonFileInput);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getVersionFromGlobalJson(globalJsonPath: string): string {
|
||||||
|
let version = '';
|
||||||
|
const globalJson = JSON.parse(
|
||||||
|
// .trim() is necessary to strip BOM https://github.com/nodejs/node/issues/20649
|
||||||
|
fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim()
|
||||||
|
);
|
||||||
|
if (globalJson.sdk && globalJson.sdk.version) {
|
||||||
|
version = globalJson.sdk.version;
|
||||||
|
const rollForward = globalJson.sdk.rollForward;
|
||||||
|
if (rollForward && rollForward === 'latestFeature') {
|
||||||
|
const [major, minor] = version.split('.');
|
||||||
|
version = `${major}.${minor}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
function outputInstalledVersion(
|
||||||
|
installedVersions: (string | null)[],
|
||||||
|
globalJsonFileInput: string
|
||||||
|
): void {
|
||||||
|
if (!installedVersions.length) {
|
||||||
|
core.info(`The 'dotnet-version' output will not be set.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (installedVersions.includes(null)) {
|
||||||
|
core.warning(
|
||||||
|
`Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalJsonFileInput) {
|
||||||
|
const versionToOutput = installedVersions.at(-1); // .NET SDK version parsed from the global.json file is installed last
|
||||||
|
core.setOutput('dotnet-version', versionToOutput);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionToOutput = semver.maxSatisfying(
|
||||||
|
installedVersions as string[],
|
||||||
|
'*',
|
||||||
|
{
|
||||||
|
includePrerelease: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
core.setOutput('dotnet-version', versionToOutput);
|
||||||
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
2
src/utils.ts
Normal file
2
src/utils.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
export const IS_LINUX = process.platform === 'linux';
|
@ -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. */
|
||||||
@ -48,7 +49,8 @@
|
|||||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||||
// "types": [], /* Type declaration files to be included in compilation. */
|
// "types": [], /* Type declaration files to be included in compilation. */
|
||||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||||
|
"resolveJsonModule": true, /* Allows importing modules with a '.json' extension, which is a common practice in node projects. */
|
||||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user