mirror of
https://github.com/actions/setup-dotnet.git
synced 2024-11-22 19:41:08 +07:00
J (#1)
* YAML Formatting at a example workflow YAML Format of the code at 'Example usage' with Environment Variables * Ignore Generated Files in Git PR's * Use v1 tag for setup-dotnet * Update install scripts * Package updates * Update index file * Fix generated index * Honor specified nuget file location (#109) * Honor specified nuget file location * Generate and verify nuget.config * Install sxs with the install-dotnet scripts (#124) * Use dotnet-install scripts for proper sxs * Update dotnet version in testing * Error message cleanup * SxS testing in the dotnet project * Update package lock * Test fixes * Use proper environment variable * Set dotnet root for windows * Add example for SxS testing to Readme * Bump node-fetch from 2.6.0 to 2.6.1 (#127) * Bump node-fetch from 2.6.0 to 2.6.1 Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] <support@github.com> * Package and index update * Formatting on installer.test * Updated licenses Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Zachary Eisinger <zeisinger@github.com> * Action input text update * DOTNET_ROOT and short generic versions (#131) * Update `@actions/core` Version and move towards uses environment files to talk to runner (#135) * update toolkit version * update licensed * fix typo * Update contributors.md * Bump node-notifier from 8.0.0 to 8.0.1 Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) from 8.0.0 to 8.0.1. - [Release notes](https://github.com/mikaelbr/node-notifier/releases) - [Changelog](https://github.com/mikaelbr/node-notifier/blob/v8.0.1/CHANGELOG.md) - [Commits](https://github.com/mikaelbr/node-notifier/compare/v8.0.0...v8.0.1) Signed-off-by: dependabot[bot] <support@github.com> * Add issue and pr templates * Update installer scripts * Resolve comments * Debug * Minor fix * Rework feature request template * Move toolcache cleanup to separated script * Debug * Debug * Debug * Debug * Minor fix * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Minor fix * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Add nuget config file * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Debug * Minor fixes * Remove workflow dispatch event * Minor fix * Debug * Debug * Debug * Minor fix * Minor fix * Minor fix * Minor fix * Minor fix * Minor fix * Rename stages * Rework cleanup script * Set ubuntu-latest * Minor fixes * Add tests * Debug * Minor fix * Debug * Debug * Debug * Update installer scripts * restrict blank issues * Update Linux installer * Include include-prerelease input in action.yml * Implement passing includePrerelase to semver * Add @actions/virtual-environments-owners to CODEOWNERS file * try fixing 5.x issue * work on fixing test * create release * add yesy cases * fix test * Remove unsupported versions of .NET from README. .NET Core 2.2 and 3.0 are no longer supported and should not be in the examples. All versions were changed to pull in the latest revision as people might copy this without checking all accepted version formats and getting the latest revision is good security practice. * Bump y18n from 4.0.0 to 4.0.1 Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/commits) Signed-off-by: dependabot[bot] <support@github.com> * Update link to pre-installed runner Software * Improve key names validation for keys from user nuget config * Improve key names validation for keys from user nuget config * Minor fix * Minor fix * Fix index.js * Support nuget.config name formats * Prettier * Build index.js * Minor fix * Minor fix * Rerun build * Automate releasing new versions of the setup-dotnet action * Add workaround to fix BOM-related error during parsing global.json * build dist/index.js * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Bump hosted-git-info from 2.8.8 to 2.8.9 Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9. - [Release notes](https://github.com/npm/hosted-git-info/releases) - [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) - [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9) Signed-off-by: dependabot[bot] <support@github.com> * Use the "publish-action" action * Use permissions as a top-level key * Update installers scripts * Update description for action Fixes #209 by adding a few more terms for search discoverability * Bump ws from 7.3.1 to 7.5.0 Bumps [ws](https://github.com/websockets/ws) from 7.3.1 to 7.5.0. - [Release notes](https://github.com/websockets/ws/releases) - [Commits](https://github.com/websockets/ws/compare/7.3.1...7.5.0) --- updated-dependencies: - dependency-name: ws dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Bump lodash from 4.17.20 to 4.17.21 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) Signed-off-by: dependabot[bot] <support@github.com> * Move toolcache folder * Rework action description * Update link to dotnet environment variables docs Old: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet#environment-variables New: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables * Bump path-parse from 1.0.6 to 1.0.7 Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7. - [Release notes](https://github.com/jbgutierrez/path-parse/releases) - [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7) --- updated-dependencies: - dependency-name: path-parse dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Support rollForward option from global.json * Format code * Revert exports in index.js * Fix unit test * Fix unstaged changes in index.js * Minor fix * Fix unit test * Remove hardcoded patch version from unit test * Prettier * Improve condition * Format code * Add check-dist.yml * Fix triggers in licensed.yml * Update installers scripts * Update README.md fix docs * Handle only latestFeature option * Build index.js * Update README.md Fix the README.md file to avoid the .NET CLI repo link that is now the .NET SDK repo. * Bump tmpl from 1.0.4 to 1.0.5 Bumps [tmpl](https://github.com/daaku/nodejs-tmpl) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/daaku/nodejs-tmpl/releases) - [Commits](https://github.com/daaku/nodejs-tmpl/commits/v1.0.5) --- updated-dependencies: - dependency-name: tmpl dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> * Update dependencies * Update installer scripts * Update deps with force * Revert jest version * Update jest * Support multiple versions in single invocation (#240) * Fix a space in the documentation (#248) * Warn users when installing EOL .NET versions (#245) * Fix the Licensed workflow (#258) * Moved checkout above setup step to align with the other samples (#256) * Avoiding installing the same version multiple times (#252) * Updated dotnet-install scripts to latest version * Update node version to v16 * Update dependencies * Update licenses * Update docs to v2 (#278) * Update docs to v2 * Bump checkout action to v3 * Update installer scripts * Replace v2 to vX on the docs, minor fixes * Remove extra whitespace * switch side by side testing example to single setup step (#283) * Add code of conduct * add global-json-file input (#276) * support specifying global.json location with global-json-file input * add test workflow jobs for global.json usage * fix typo in global-json-file description Co-authored-by: Brian Cristante <33549821+brcrista@users.noreply.github.com> Co-authored-by: Brian Cristante <33549821+brcrista@users.noreply.github.com> * Update vulnerable packages * Update @zeit/ncc to @vercel/ncc (#290) * update @zeit/ncc to @vercel/ncc * rebuild project * v3 adr * Create codeql-analysis.yml * Don't need C# analysis for CodeQL * updated local installation scripts * updated guide * chore(deps-dev): migrate husky config to v8 Follow: https://github.com/typicode/husky-4-to-8 - npm install husky --save-dev - npx husky-init - npm exec -- github:typicode/husky-4-to-8 --remove-v4-config * ci: add `--ignore-scripts` argument * advice on updating installers * refactor: use core.getBooleanInput() * chore: set include-prerelease to false on default * test: add include-prerelease env on test * rephased docs * Update docs/contributors.md Co-authored-by: Ivan <98037481+IvanZosimov@users.noreply.github.com> * Grammar fixes * Update ADR date * Update actions version in package json * Run update installers * Rework * ADR change (#1) * Update ADR proposal ADR proposal was updated in order to reflect cahnges that will be done more thoroughly. * Fix formatting * Set status accepted * Create generator-generic-ossf-slsa3-publish.yml Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: No Name Pro <noname.pro.nn@gmail.com> Co-authored-by: Zachary Eisinger <zeisinger@github.com> Co-authored-by: Thomas Boop <thboop@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com> Co-authored-by: Vladimir Safonkin <vsafonkin@github.com> Co-authored-by: Maxim Lobanov <maxim-lobanov@github.com> Co-authored-by: Dmitry Shibanov <dmitry-shibanov@github.com> Co-authored-by: GGG KILLER <gggkiller2@gmail.com> Co-authored-by: Andreas Offenhaeuser <anoff@users.noreply.github.com> Co-authored-by: Alena Sviridenko <alenasviridenko@github.com> Co-authored-by: MaksimZhukov <v-mazhuk@microsoft.com> Co-authored-by: Sergey Dolin <v-sedoli@micorosoft.com> Co-authored-by: Maxim Lobanov <v-malob@microsoft.com> Co-authored-by: Darii Nurgaleev <50947177+Darleev@users.noreply.github.com> Co-authored-by: Tim Heuer <tim@timheuer.com> Co-authored-by: Aleksandr Chebotov <v-aleche@microsoft.com> Co-authored-by: George Chakhidze <0xfeeddeadbeef@gmail.com> Co-authored-by: Brian Cristante <33549821+brcrista@users.noreply.github.com> Co-authored-by: Thomas Pisula <12602834+tomp736@users.noreply.github.com> Co-authored-by: MaksimZhukov <46996400+MaksimZhukov@users.noreply.github.com> Co-authored-by: David Pine <david.pine@microsoft.com> Co-authored-by: La'Kaleigh Harris <35268101+Xlient@users.noreply.github.com> Co-authored-by: Pure Krome <github@world-domination.com.au> Co-authored-by: Thomas Ardal <thomasardal@gmail.com> Co-authored-by: Adam Ralph <adam@adamralph.com> Co-authored-by: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> Co-authored-by: Owen Smith <owen@omsmith.ca> Co-authored-by: Dmitry Shibanov <shibanov-1997@inbox.ru> Co-authored-by: Evgenii Korolevskii <e-korolevskii@github.com> Co-authored-by: Marko Zivic <100996310+marko-zivic-93@users.noreply.github.com> Co-authored-by: Nogic <24802730+nogic1008@users.noreply.github.com> Co-authored-by: Evgenii Korolevskii <102794661+e-korolevskii@users.noreply.github.com> Co-authored-by: Ivan <98037481+IvanZosimov@users.noreply.github.com> Co-authored-by: panticmilos <panticmilos@github.com>
This commit is contained in:
parent
7df9f59802
commit
ebb714cfd8
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.licenses/** -diff linguist-generated=true
|
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* @actions/virtual-environments-owners
|
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.
|
52
.github/workflows/check-dist.yml
vendored
Normal file
52
.github/workflows/check-dist.yml
vendored
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# `dist/index.js` is a special file in Actions.
|
||||||
|
# When you reference an action with `uses:` in a workflow,
|
||||||
|
# `index.js` is the code that will run.
|
||||||
|
# For our project, we generate this file through a build process from other source files.
|
||||||
|
# We need to make sure the checked-in `index.js` actually matches what we expect it to be.
|
||||||
|
name: Check dist/
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-dist:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set Node.js 16
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16.x
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci --ignore-scripts
|
||||||
|
|
||||||
|
- name: Rebuild the dist/ directory
|
||||||
|
run: npm run build
|
||||||
|
|
||||||
|
- name: Compare the expected and actual dist/ directories
|
||||||
|
run: |
|
||||||
|
if [ "$(git diff --ignore-space-at-eol dist/ | wc -l)" -gt "0" ]; then
|
||||||
|
echo "Detected uncommitted changes after build. See status below:"
|
||||||
|
git diff
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
id: diff
|
||||||
|
|
||||||
|
# If index.js was different than expected, upload the expected version as an artifact
|
||||||
|
- uses: actions/upload-artifact@v3
|
||||||
|
if: ${{ failure() && steps.diff.conclusion == 'failure' }}
|
||||||
|
with:
|
||||||
|
name: dist
|
||||||
|
path: dist/
|
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
# The branches below must be a subset of the branches above
|
||||||
|
branches: [ main ]
|
||||||
|
schedule:
|
||||||
|
- cron: '23 19 * * 0'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'javascript' ]
|
||||||
|
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||||
|
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v2
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
|
||||||
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||||
|
# and modify them (or add more) to build your code if your project
|
||||||
|
# uses a compiled language
|
||||||
|
|
||||||
|
#- run: |
|
||||||
|
# make bootstrap
|
||||||
|
# make release
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v2
|
68
.github/workflows/generator-generic-ossf-slsa3-publish.yml
vendored
Normal file
68
.github/workflows/generator-generic-ossf-slsa3-publish.yml
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# This workflow uses actions that are not certified by GitHub.
|
||||||
|
# They are provided by a third-party and are governed by
|
||||||
|
# separate terms of service, privacy policy, and support
|
||||||
|
# documentation.
|
||||||
|
|
||||||
|
# This workflow lets you generate SLSA provenance file for your project.
|
||||||
|
# The generation satisfies level 3 for the provenance requirements - see https://slsa.dev/spec/v0.1/requirements
|
||||||
|
# The project is an initiative of the OpenSSF (openssf.org) and is developed at
|
||||||
|
# https://github.com/slsa-framework/slsa-github-generator.
|
||||||
|
# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier.
|
||||||
|
# For more information about SLSA and how it improves the supply-chain, visit slsa.dev.
|
||||||
|
|
||||||
|
name: SLSA generic generator
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [created]
|
||||||
|
|
||||||
|
permissions: read-all
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
digests: ${{ steps.hash.outputs.digests }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
#
|
||||||
|
# Step 1: Build your artifacts.
|
||||||
|
#
|
||||||
|
# ========================================================
|
||||||
|
- name: Build artifacts
|
||||||
|
run: |
|
||||||
|
# These are some amazing artifacts.
|
||||||
|
echo "artifact1" > artifact1
|
||||||
|
echo "artifact2" > artifact2
|
||||||
|
|
||||||
|
# ========================================================
|
||||||
|
#
|
||||||
|
# Step 2: Add a step to generate the provenance subjects
|
||||||
|
# as shown below. Update the sha256 sum arguments
|
||||||
|
# to include all binaries that you generate
|
||||||
|
# provenance for.
|
||||||
|
#
|
||||||
|
# ========================================================
|
||||||
|
- name: Generate subject
|
||||||
|
id: hash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# List the artifacts the provenance will refer to.
|
||||||
|
files=$(ls artifact*)
|
||||||
|
# Generate the subjects (base64 encoded).
|
||||||
|
echo "::set-output name=digests::$(sha256sum $files | base64 -w0)"
|
||||||
|
|
||||||
|
provenance:
|
||||||
|
needs: [build]
|
||||||
|
permissions:
|
||||||
|
actions: read # To read the workflow path.
|
||||||
|
id-token: write # To sign the provenance.
|
||||||
|
contents: write # To add assets to a release.
|
||||||
|
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.2.0
|
||||||
|
with:
|
||||||
|
base64-subjects: "${{ needs.build.outputs.digests }}"
|
||||||
|
upload-assets: true # Optional: Upload to a new release
|
25
.github/workflows/licensed.yml
vendored
Normal file
25
.github/workflows/licensed.yml
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: Licensed
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Check licenses
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: npm ci --ignore-scripts
|
||||||
|
- name: Install licensed
|
||||||
|
run: |
|
||||||
|
cd $RUNNER_TEMP
|
||||||
|
curl -Lfs -o licensed.tar.gz https://github.com/github/licensed/releases/download/3.4.4/licensed-3.4.4-linux-x64.tar.gz
|
||||||
|
sudo tar -xzf licensed.tar.gz
|
||||||
|
sudo mv licensed /usr/local/bin/licensed
|
||||||
|
- run: licensed status
|
28
.github/workflows/release-new-action-version.yml
vendored
Normal file
28
.github/workflows/release-new-action-version.yml
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
name: Release new action version
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [released]
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
TAG_NAME:
|
||||||
|
description: 'Tag name that the major tag will point to'
|
||||||
|
required: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
TAG_NAME: ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }}
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update_tag:
|
||||||
|
name: Update the major tag to include the ${{ github.event.inputs.TAG_NAME || github.event.release.tag_name }} changes
|
||||||
|
environment:
|
||||||
|
name: releaseNewActionVersion
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
|
id: update-major-tag
|
||||||
|
uses: actions/publish-action@v0.1.0
|
||||||
|
with:
|
||||||
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
37
.github/workflows/test-dotnet.yml
vendored
Normal file
37
.github/workflows/test-dotnet.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
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']
|
||||||
|
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: Check installed version
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$version = & dotnet --version
|
||||||
|
Write-Host "Installed version: $version"
|
||||||
|
if (-not $version.StartsWith("${{ matrix.dotnet-version }}")) { throw "Unexpected version" }
|
205
.github/workflows/workflow.yml
vendored
205
.github/workflows/workflow.yml
vendored
@ -2,25 +2,31 @@ name: Main workflow
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- releases/*
|
- releases/*
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- name: Set Node.js 12
|
- name: Set Node.js 16
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
version: 12.x
|
node-version: 16.x
|
||||||
- run: npm ci
|
cache: npm
|
||||||
|
- run: npm ci --ignore-scripts
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
- run: npm run format-check
|
- run: npm run format-check
|
||||||
- run: npm test
|
- run: npm test
|
||||||
@ -28,26 +34,160 @@ jobs:
|
|||||||
if: runner.os != 'windows'
|
if: runner.os != 'windows'
|
||||||
run: __tests__/verify-no-unstaged-changes.sh
|
run: __tests__/verify-no-unstaged-changes.sh
|
||||||
|
|
||||||
test:
|
test-setup-multiple-versions:
|
||||||
runs-on: ${{ matrix.operating-system }}
|
runs-on: ${{ matrix.operating-system }}
|
||||||
strategy:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- name: Clear toolcache
|
- name: Clear toolcache
|
||||||
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
shell: pwsh
|
||||||
- name: Setup dotnet 3.0.100
|
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
|
||||||
|
- name: Setup dotnet 2.2.402 and 3.1.404
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.0.100
|
dotnet-version: |
|
||||||
|
2.2.402
|
||||||
|
3.1.404
|
||||||
|
3.0.x
|
||||||
- name: Verify dotnet
|
- name: Verify dotnet
|
||||||
if: runner.os != 'windows'
|
shell: pwsh
|
||||||
run: __tests__/verify-dotnet.sh 3.0.100
|
run: __tests__/verify-dotnet.ps1 2.2.402 3.1.404 '3.0'
|
||||||
- name: Verify dotnet (Windows)
|
|
||||||
if: runner.os == 'windows'
|
test-setup-full-version:
|
||||||
run: __tests__/verify-dotnet.ps1 3.0.100
|
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 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 nuget config file
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
if (-Not (Test-Path "../nuget.config")) { throw "nuget file not generated correctly" }
|
||||||
|
- name: Verify dotnet
|
||||||
|
shell: pwsh
|
||||||
|
run: __tests__/verify-dotnet.ps1 3.1.201 2.2.402
|
||||||
|
|
||||||
|
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 3.1 2.2
|
||||||
|
|
||||||
|
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 3.1 2.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 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","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 2.2 3.1
|
||||||
|
|
||||||
test-proxy:
|
test-proxy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@ -61,31 +201,42 @@ jobs:
|
|||||||
- 3128:3128
|
- 3128:3128
|
||||||
env:
|
env:
|
||||||
https_proxy: http://squid-proxy:3128
|
https_proxy: http://squid-proxy:3128
|
||||||
|
http_proxy: http://squid-proxy:3128
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- name: Clear tool cache
|
- name: Clear tool cache
|
||||||
run: rm -rf $RUNNER_TOOL_CACHE/*
|
run: rm -rf "/usr/share/dotnet"
|
||||||
- name: Setup dotnet 3.0.100
|
- name: Install curl
|
||||||
|
run: |
|
||||||
|
apt update
|
||||||
|
apt -y install curl
|
||||||
|
- name: Setup dotnet 3.1.201
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.0.100
|
dotnet-version: 3.1.201
|
||||||
|
source-url: https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||||
- name: Verify dotnet
|
- name: Verify dotnet
|
||||||
run: __tests__/verify-dotnet.sh 3.0.100
|
run: __tests__/verify-dotnet.sh 3.1.201
|
||||||
|
|
||||||
test-bypass-proxy:
|
test-bypass-proxy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
https_proxy: http://no-such-proxy:3128
|
https_proxy: http://no-such-proxy:3128
|
||||||
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org
|
no_proxy: github.com,dotnetcli.blob.core.windows.net,download.visualstudio.microsoft.com,api.nuget.org,dotnetcli.azureedge.net
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
- name: Clear tool cache
|
- name: Clear tool cache
|
||||||
run: mv "${{ runner.tool_cache }}" "${{ runner.tool_cache }}.old"
|
run: rm -rf "/usr/share/dotnet"
|
||||||
- name: Setup dotnet 3.0.100
|
- name: Setup dotnet 3.1.201
|
||||||
uses: ./
|
uses: ./
|
||||||
with:
|
with:
|
||||||
dotnet-version: 3.0.100
|
dotnet-version: 3.1.201
|
||||||
|
source-url: https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: NOTATOKEN
|
||||||
- name: Verify dotnet
|
- name: Verify dotnet
|
||||||
run: __tests__/verify-dotnet.sh 3.0.100
|
run: __tests__/verify-dotnet.sh 3.1.201
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -95,4 +95,5 @@ typings/
|
|||||||
# DynamoDB Local files
|
# DynamoDB Local files
|
||||||
.dynamodb/
|
.dynamodb/
|
||||||
|
|
||||||
.vscode/*
|
# Ignore .vscode files
|
||||||
|
.vscode/
|
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
|
npm run format
|
5
.husky/pre-push
Executable file
5
.husky/pre-push
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/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
|
14
.licensed.yml
Normal file
14
.licensed.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
sources:
|
||||||
|
npm: true
|
||||||
|
|
||||||
|
allowed:
|
||||||
|
- apache-2.0
|
||||||
|
- bsd-2-clause
|
||||||
|
- bsd-3-clause
|
||||||
|
- isc
|
||||||
|
- mit
|
||||||
|
- cc0-1.0
|
||||||
|
- unlicense
|
||||||
|
|
||||||
|
reviewed:
|
||||||
|
npm:
|
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/core.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/github.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.11.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.11.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/http-client-1.0.8.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/io.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/endpoint.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/graphql.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request-error.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/request.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
BIN
.licenses/npm/@octokit/rest.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/atob-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
BIN
.licenses/npm/before-after-hook.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
BIN
.licenses/npm/btoa-lite.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
BIN
.licenses/npm/cross-spawn.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
BIN
.licenses/npm/deprecation.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/end-of-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
BIN
.licenses/npm/execa.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
Normal file
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/get-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
BIN
.licenses/npm/is-plain-object.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
BIN
.licenses/npm/is-stream.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
BIN
.licenses/npm/isexe.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
BIN
.licenses/npm/isobject.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.get.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.set.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
BIN
.licenses/npm/lodash.uniq.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
BIN
.licenses/npm/macos-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
BIN
.licenses/npm/nice-try.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
BIN
.licenses/npm/node-fetch.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
BIN
.licenses/npm/npm-run-path.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
BIN
.licenses/npm/octokit-pagination-methods.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/once.dep.yml
generated
Normal file
BIN
.licenses/npm/once.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
BIN
.licenses/npm/os-name.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
BIN
.licenses/npm/p-finally.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
BIN
.licenses/npm/path-key.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
BIN
.licenses/npm/pump.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-5.7.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/semver-6.3.0.dep.yml
generated
Normal file
BIN
.licenses/npm/semver-6.3.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-command.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
BIN
.licenses/npm/shebang-regex.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
BIN
.licenses/npm/signal-exit.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
BIN
.licenses/npm/strip-eof.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/tr46.dep.yml
generated
Normal file
BIN
.licenses/npm/tr46.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
BIN
.licenses/npm/tunnel.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-2.1.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
BIN
.licenses/npm/universal-user-agent-4.0.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
BIN
.licenses/npm/webidl-conversions.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
BIN
.licenses/npm/whatwg-url.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/which.dep.yml
generated
Normal file
BIN
.licenses/npm/which.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
BIN
.licenses/npm/windows-release.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
BIN
.licenses/npm/wrappy.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
Normal file
BIN
.licenses/npm/xmlbuilder.dep.yml
generated
Normal file
Binary file not shown.
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
|
106
README.md
106
README.md
@ -1,15 +1,19 @@
|
|||||||
# setup-dotnet
|
# setup-dotnet
|
||||||
|
|
||||||
<p align="left">
|
[![GitHub Actions Status](https://github.com/actions/setup-dotnet/workflows/Main%20workflow/badge.svg)](https://github.com/actions/setup-dotnet)
|
||||||
<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>
|
|
||||||
</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
|
||||||
|
preinstalled. Installed versions are subject to change. Please refer to the
|
||||||
|
documentation
|
||||||
|
[software installed on github hosted runners](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-software)
|
||||||
|
for .NET SDK versions that are currently available.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
See [action.yml](action.yml)
|
See [action.yml](action.yml)
|
||||||
@ -17,37 +21,89 @@ See [action.yml](action.yml)
|
|||||||
Basic:
|
Basic:
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v2
|
||||||
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' # SDK Version to use; x will use the latest version of the 3.1 channel
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
|
Multiple versions:
|
||||||
|
> Note: In case multiple versions are installed, the latest .NET version will be used by default unless another version is specified in the `global.json` file.
|
||||||
|
|
||||||
|
```yml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
3.1.x
|
||||||
|
5.0.x
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
```
|
||||||
|
Preview version:
|
||||||
|
```yml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: '6.0.x'
|
||||||
|
include-prerelease: true
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
```
|
||||||
|
global.json in a subdirectory:
|
||||||
|
```yml
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
global-json-file: csharp/global.json
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
working-directory: csharp
|
||||||
|
```
|
||||||
|
|
||||||
Matrix Testing:
|
Matrix Testing:
|
||||||
```yaml
|
```yaml
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-16.04
|
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@master
|
- uses: actions/checkout@v3
|
||||||
- name: Setup dotnet
|
- name: Setup dotnet
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ matrix.dotnet }}
|
dotnet-version: ${{ matrix.dotnet }}
|
||||||
- run: dotnet build <my project>
|
- run: dotnet build <my project>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Side by Side Testing:
|
||||||
|
```yaml
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Dotnet Side by Side testing sample
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: |
|
||||||
|
2.1.x
|
||||||
|
3.1.x
|
||||||
|
- run: dotnet build <my project>
|
||||||
|
- run: dotnet test <my project>
|
||||||
|
```
|
||||||
|
|
||||||
Authentication for nuget feeds:
|
Authentication for nuget feeds:
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@v3
|
||||||
# Authenticates packages to push to GPR
|
# Authenticates packages to push to GPR
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.x' # SDK Version to use.
|
dotnet-version: '3.1.x' # SDK Version to use.
|
||||||
source-url: https://nuget.pkg.github.com/<owner>/index.json
|
source-url: https://nuget.pkg.github.com/<owner>/index.json
|
||||||
@ -59,35 +115,45 @@ steps:
|
|||||||
- 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
|
# Authenticates packages to push to Azure Artifacts
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
source-url: https://pkgs.dev.azure.com/<your-organization>/_packaging/<your-feed-name>/nuget/v3/index.json
|
||||||
env:
|
env:
|
||||||
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
NUGET_AUTH_TOKEN: ${{secrets.AZURE_DEVOPS_PAT}} # Note, create a secret with this name in Settings
|
||||||
- name: Publish the package to Azure Artifacts
|
- name: Publish the package to Azure Artifacts
|
||||||
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
run: dotnet nuget push <my project>/bin/Release/*.nupkg
|
||||||
|
|
||||||
|
# Authenticates packages to push to nuget.org.
|
||||||
|
# It's only the way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
|
||||||
|
- uses: actions/setup-dotnet@v2
|
||||||
|
with:
|
||||||
|
dotnet-version: 3.1.x
|
||||||
|
- name: Publish the package to nuget.org
|
||||||
|
run: dotnet nuget push */bin/Release/*.nupkg -k $NUGET_AUTH_TOKEN -s https://api.nuget.org/v3/index.json
|
||||||
|
env:
|
||||||
|
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variables to use with dotnet
|
## Environment Variables to use with dotnet
|
||||||
|
|
||||||
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet#environment-variables
|
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables
|
||||||
|
|
||||||
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false)
|
- DOTNET_NOLOGO - removes logo and telemetry message from first run of dotnet cli (default: false)
|
||||||
- DOTNET_CLI_TELEMETRY_OPTOUT - opt-out of telemetry being sent to Microsoft (default: false)
|
- 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_MULTILEVEL_LOOKUP - configures whether the global install location is used as a fall-back (default: true)
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
```
|
```yaml
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
DOTNET_NOLOGO: true
|
DOTNET_NOLOGO: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@main
|
||||||
- uses: actions/setup-dotnet@v1
|
- uses: actions/setup-dotnet@v2
|
||||||
with:
|
with:
|
||||||
dotnet-version: '3.1.100' # SDK Version to use.
|
dotnet-version: '3.1.x' # SDK Version to use.
|
||||||
```
|
```
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
@ -75,14 +75,17 @@ const azureartifactsnugetorgNuGetConfig: string = `<?xml version="1.0" encoding=
|
|||||||
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
const nugetConfigFile = path.join(fakeSourcesDirForTesting, '../nuget.config');
|
||||||
|
|
||||||
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
process.env['GITHUB_REPOSITORY'] = 'OwnerName/repo';
|
||||||
process.env['RUNNER_TEMP'] = fakeSourcesDirForTesting;
|
|
||||||
import * as auth from '../src/authutil';
|
import * as auth from '../src/authutil';
|
||||||
|
|
||||||
describe('authutil tests', () => {
|
describe('authutil tests', () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await io.rmRF(fakeSourcesDirForTesting);
|
await io.rmRF(fakeSourcesDirForTesting);
|
||||||
await io.mkdirP(fakeSourcesDirForTesting);
|
await io.mkdirP(fakeSourcesDirForTesting);
|
||||||
}, 100000);
|
}, 30000);
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await io.rmRF(fakeSourcesDirForTesting);
|
||||||
|
}, 30000);
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
if (fs.existsSync(nugetConfigFile)) {
|
if (fs.existsSync(nugetConfigFile)) {
|
||||||
@ -95,7 +98,9 @@ describe('authutil tests', () => {
|
|||||||
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(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -107,7 +112,9 @@ describe('authutil tests', () => {
|
|||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
thrown = true;
|
thrown = true;
|
||||||
@ -119,7 +126,9 @@ describe('authutil tests', () => {
|
|||||||
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(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/otherorg/index.json'
|
'https://nuget.pkg.github.com/otherorg/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -137,7 +146,9 @@ describe('authutil tests', () => {
|
|||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
thrown = true;
|
thrown = true;
|
||||||
@ -153,7 +164,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, emptyNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -169,7 +182,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, nugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -185,7 +200,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -201,7 +218,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprnugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -216,7 +235,11 @@ describe('authutil tests', () => {
|
|||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, twogprNuGetConfig);
|
||||||
await auth.configAuthentication('https://nuget.pkg.github.com');
|
await auth.configAuthentication(
|
||||||
|
'https://nuget.pkg.github.com',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
fs.readFileSync(nugetConfigFile, {encoding: 'utf8'})
|
||||||
@ -233,7 +256,9 @@ describe('authutil tests', () => {
|
|||||||
let thrown = false;
|
let thrown = false;
|
||||||
try {
|
try {
|
||||||
await auth.configAuthentication(
|
await auth.configAuthentication(
|
||||||
'https://nuget.pkg.github.com/OwnerName/index.json'
|
'https://nuget.pkg.github.com/OwnerName/index.json',
|
||||||
|
'',
|
||||||
|
fakeSourcesDirForTesting
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
thrown = true;
|
thrown = true;
|
||||||
@ -255,7 +280,8 @@ describe('authutil tests', () => {
|
|||||||
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, gprNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await 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
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -271,7 +297,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await 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
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -287,7 +315,9 @@ describe('authutil tests', () => {
|
|||||||
);
|
);
|
||||||
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
fs.writeFileSync(inputNuGetConfigPath, azureartifactsnugetorgNuGetConfig);
|
||||||
await auth.configAuthentication(
|
await 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
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
@ -298,7 +328,9 @@ describe('authutil tests', () => {
|
|||||||
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(
|
await 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
|
||||||
);
|
);
|
||||||
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
expect(fs.existsSync(nugetConfigFile)).toBe(true);
|
||||||
expect(
|
expect(
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -4,75 +4,21 @@ import os = require('os');
|
|||||||
import path = require('path');
|
import path = require('path');
|
||||||
import hc = require('@actions/http-client');
|
import hc = require('@actions/http-client');
|
||||||
|
|
||||||
import each from 'jest-each';
|
|
||||||
|
|
||||||
const toolDir = path.join(__dirname, 'runner', 'tools');
|
const toolDir = path.join(__dirname, 'runner', 'tools');
|
||||||
const tempDir = path.join(__dirname, 'runner', 'temp');
|
const tempDir = path.join(__dirname, 'runner', 'temp');
|
||||||
|
|
||||||
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
process.env['RUNNER_TOOL_CACHE'] = toolDir;
|
||||||
process.env['RUNNER_TEMP'] = tempDir;
|
process.env['RUNNER_TEMP'] = tempDir;
|
||||||
import * as setup from '../src/setup-dotnet';
|
|
||||||
import * as installer from '../src/installer';
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('installer tests', () => {
|
describe('installer tests', () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
|
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||||
|
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||||
|
process.env.RUNNER_TEMP = tempDir;
|
||||||
|
process.env.DOTNET_ROOT = '';
|
||||||
await io.rmRF(toolDir);
|
await io.rmRF(toolDir);
|
||||||
await io.rmRF(tempDir);
|
await io.rmRF(tempDir);
|
||||||
});
|
});
|
||||||
@ -84,83 +30,61 @@ describe('installer tests', () => {
|
|||||||
} catch {
|
} catch {
|
||||||
console.log('Failed to remove test directories');
|
console.log('Failed to remove test directories');
|
||||||
}
|
}
|
||||||
}, 100000);
|
}, 30000);
|
||||||
|
|
||||||
it('Resolving a normal generic version works', async () => {
|
it('Aquires multiple versions of dotnet', async () => {
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.x');
|
const versions = ['2.2.207', '3.1.120'];
|
||||||
let versInfo = await dotnetInstaller.resolveInfos(
|
|
||||||
['win-x64'],
|
|
||||||
new installer.DotNetVersionInfo('3.1.x')
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(versInfo.resolvedVersion.startsWith('3.1.'));
|
for (const version of versions) {
|
||||||
}, 100000);
|
await getDotnet(version);
|
||||||
|
|
||||||
it('Resolving a nonexistent generic version fails', async () => {
|
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
|
|
||||||
try {
|
|
||||||
await dotnetInstaller.resolveInfos(
|
|
||||||
['win-x64'],
|
|
||||||
new installer.DotNetVersionInfo('999.1.x')
|
|
||||||
);
|
|
||||||
fail();
|
|
||||||
} catch {
|
|
||||||
expect(true);
|
|
||||||
}
|
}
|
||||||
}, 100000);
|
expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true);
|
||||||
|
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true);
|
||||||
|
|
||||||
it('Resolving a exact stable version works', async () => {
|
if (IS_WINDOWS) {
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller('3.1.201');
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
let versInfo = await dotnetInstaller.resolveInfos(
|
} else {
|
||||||
['win-x64'],
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
new installer.DotNetVersionInfo('3.1.201')
|
}
|
||||||
);
|
|
||||||
|
|
||||||
expect(versInfo.resolvedVersion).toBe('3.1.201');
|
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||||
}, 100000);
|
expect(process.env.PATH).toBeDefined;
|
||||||
|
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||||
it('Resolving a exact preview version works', async () => {
|
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(
|
}, 600000);
|
||||||
'5.0.0-preview.4'
|
|
||||||
);
|
|
||||||
let versInfo = await dotnetInstaller.resolveInfos(
|
|
||||||
['win-x64'],
|
|
||||||
new installer.DotNetVersionInfo('5.0.0-preview.4')
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(versInfo.resolvedVersion).toBe('5.0.0-preview.4');
|
|
||||||
}, 100000);
|
|
||||||
|
|
||||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
it('Acquires version of dotnet if no matching version is installed', async () => {
|
||||||
await getDotnet('2.2.205');
|
await getDotnet('3.1.201');
|
||||||
const dotnetDir = path.join(toolDir, 'dncs', '2.2.205', os.arch());
|
expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true);
|
||||||
|
|
||||||
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true);
|
|
||||||
if (IS_WINDOWS) {
|
if (IS_WINDOWS) {
|
||||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true);
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
} else {
|
} else {
|
||||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true);
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
}
|
}
|
||||||
}, 400000); //This needs some time to download on "slower" internet connections
|
|
||||||
|
|
||||||
it('Acquires version of dotnet if no matching version is installed', async () => {
|
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||||
const dotnetDir = path.join(toolDir, 'dncs', '2.2.105', os.arch());
|
expect(process.env.PATH).toBeDefined;
|
||||||
|
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||||
|
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||||
|
}, 600000); //This needs some time to download on "slower" internet connections
|
||||||
|
|
||||||
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
it('Acquires generic version of dotnet if no matching version is installed', async () => {
|
||||||
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "2.2.105"${os.EOL}}${os.EOL}}`;
|
await getDotnet('3.1');
|
||||||
if (!fs.existsSync(globalJsonPath)) {
|
var directory = fs
|
||||||
fs.writeFileSync(globalJsonPath, jsonContents);
|
.readdirSync(path.join(toolDir, 'sdk'))
|
||||||
}
|
.filter(fn => fn.startsWith('3.1.'));
|
||||||
await setup.run();
|
expect(directory.length > 0).toBe(true);
|
||||||
|
|
||||||
expect(fs.existsSync(`${dotnetDir}.complete`)).toBe(true);
|
|
||||||
if (IS_WINDOWS) {
|
if (IS_WINDOWS) {
|
||||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet.exe'))).toBe(true);
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
} else {
|
} else {
|
||||||
expect(fs.existsSync(path.join(dotnetDir, 'dotnet'))).toBe(true);
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
}
|
}
|
||||||
fs.unlinkSync(globalJsonPath);
|
|
||||||
}, 100000);
|
expect(process.env.DOTNET_ROOT).toBeDefined;
|
||||||
|
expect(process.env.PATH).toBeDefined;
|
||||||
|
expect(process.env.DOTNET_ROOT).toBe(toolDir);
|
||||||
|
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
|
||||||
|
}, 600000); //This needs some time to download on "slower" internet connections
|
||||||
|
|
||||||
it('Throws if no location contains correct dotnet version', async () => {
|
it('Throws if no location contains correct dotnet version', async () => {
|
||||||
let thrown = false;
|
let thrown = false;
|
||||||
@ -170,30 +94,7 @@ describe('installer tests', () => {
|
|||||||
thrown = true;
|
thrown = true;
|
||||||
}
|
}
|
||||||
expect(thrown).toBe(true);
|
expect(thrown).toBe(true);
|
||||||
}, 100000);
|
}, 30000);
|
||||||
|
|
||||||
it('Uses version of dotnet installed in cache', async () => {
|
|
||||||
const dotnetDir: string = path.join(toolDir, 'dncs', '250.0.0', os.arch());
|
|
||||||
await io.mkdirP(dotnetDir);
|
|
||||||
fs.writeFileSync(`${dotnetDir}.complete`, 'hello');
|
|
||||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
|
||||||
await getDotnet('250.0.0');
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Doesnt use version of dotnet that was only partially installed in cache', async () => {
|
|
||||||
const dotnetDir: string = path.join(toolDir, 'dncs', '251.0.0', os.arch());
|
|
||||||
await io.mkdirP(dotnetDir);
|
|
||||||
let thrown = false;
|
|
||||||
try {
|
|
||||||
// This will throw if it doesn't find it in the cache (because no such version exists)
|
|
||||||
await getDotnet('251.0.0');
|
|
||||||
} catch {
|
|
||||||
thrown = true;
|
|
||||||
}
|
|
||||||
expect(thrown).toBe(true);
|
|
||||||
return;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Uses an up to date bash download script', async () => {
|
it('Uses an up to date bash download script', async () => {
|
||||||
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||||
@ -213,7 +114,7 @@ describe('installer tests', () => {
|
|||||||
expect(normalizeFileContents(currentContents)).toBe(
|
expect(normalizeFileContents(currentContents)).toBe(
|
||||||
normalizeFileContents(upToDateContents)
|
normalizeFileContents(upToDateContents)
|
||||||
);
|
);
|
||||||
}, 100000);
|
}, 30000);
|
||||||
|
|
||||||
it('Uses an up to date powershell download script', async () => {
|
it('Uses an up to date powershell download script', async () => {
|
||||||
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
var httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], {
|
||||||
@ -233,7 +134,7 @@ describe('installer tests', () => {
|
|||||||
expect(normalizeFileContents(currentContents)).toBe(
|
expect(normalizeFileContents(currentContents)).toBe(
|
||||||
normalizeFileContents(upToDateContents)
|
normalizeFileContents(upToDateContents)
|
||||||
);
|
);
|
||||||
}, 100000);
|
}, 30000);
|
||||||
});
|
});
|
||||||
|
|
||||||
function normalizeFileContents(contents: string): string {
|
function normalizeFileContents(contents: string): string {
|
||||||
@ -246,4 +147,5 @@ function normalizeFileContents(contents: string): string {
|
|||||||
async function getDotnet(version: string): Promise<void> {
|
async function getDotnet(version: string): Promise<void> {
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
||||||
await dotnetInstaller.installDotnet();
|
await dotnetInstaller.installDotnet();
|
||||||
|
installer.DotnetCoreInstaller.addToPath();
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
using System;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Newtonsoft.Json;
|
using System;
|
||||||
|
|
||||||
namespace sample_csproj
|
namespace sample_csproj
|
||||||
{
|
{
|
||||||
class Program
|
[TestClass]
|
||||||
|
public class Program
|
||||||
{
|
{
|
||||||
static void Main(string[] args)
|
[TestMethod]
|
||||||
|
public void TestMethod1()
|
||||||
{
|
{
|
||||||
var json = JsonConvert.SerializeObject(new[] {"Hello", "World!" });
|
Console.WriteLine("Hello, World!");
|
||||||
Console.WriteLine(json);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"runtimeOptions": {
|
|
||||||
"configProperties": {
|
|
||||||
"System.Globalization.Invariant": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +1,18 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<TargetFrameworks>netcoreapp3.1;netcoreapp3.0;netcoreapp2.2</TargetFrameworks>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
|
||||||
<RootNamespace>sample_csproj</RootNamespace>
|
<RootNamespace>sample_csproj</RootNamespace>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<!-- 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>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
71
__tests__/setup-dotnet.test.ts
Normal file
71
__tests__/setup-dotnet.test.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import io = require('@actions/io');
|
||||||
|
import fs = require('fs');
|
||||||
|
import os = require('os');
|
||||||
|
import path = require('path');
|
||||||
|
|
||||||
|
const toolDir = path.join(__dirname, 'runner', 'tools2');
|
||||||
|
const tempDir = path.join(__dirname, 'runner', 'temp2');
|
||||||
|
|
||||||
|
import * as setup from '../src/setup-dotnet';
|
||||||
|
import * as dotnetInstaller from '../src/installer';
|
||||||
|
|
||||||
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
|
describe('setup-dotnet tests', () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
process.env.RUNNER_TOOL_CACHE = toolDir;
|
||||||
|
process.env.DOTNET_INSTALL_DIR = toolDir;
|
||||||
|
process.env.RUNNER_TEMP = tempDir;
|
||||||
|
process.env['INPUT_INCLUDE-PRERELEASE'] = 'false';
|
||||||
|
await io.rmRF(toolDir);
|
||||||
|
await io.rmRF(tempDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(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);
|
||||||
|
|
||||||
|
it('Acquires version of dotnet from global.json with rollForward option, install the latest patch', async () => {
|
||||||
|
const globalJsonPath = path.join(process.cwd(), 'global.json');
|
||||||
|
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version":"3.1.201",${os.EOL}"rollForward":"latestFeature"${os.EOL}}${os.EOL}}`;
|
||||||
|
if (!fs.existsSync(globalJsonPath)) {
|
||||||
|
fs.writeFileSync(globalJsonPath, jsonContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
const version = '3.1';
|
||||||
|
const installer = new dotnetInstaller.DotnetCoreInstaller(version);
|
||||||
|
const patchVersion = await installer.resolveVersion(
|
||||||
|
new dotnetInstaller.DotNetVersionInfo(version)
|
||||||
|
);
|
||||||
|
await setup.run();
|
||||||
|
|
||||||
|
expect(fs.existsSync(path.join(toolDir, 'sdk', patchVersion))).toBe(true);
|
||||||
|
if (IS_WINDOWS) {
|
||||||
|
expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true);
|
||||||
|
} else {
|
||||||
|
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
|
||||||
|
}
|
||||||
|
}, 400000);
|
||||||
|
});
|
@ -6,15 +6,38 @@ if (!$args[0])
|
|||||||
$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'"
|
||||||
|
|
||||||
|
if($args.count -eq 1)
|
||||||
|
{
|
||||||
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
|
$version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() }
|
||||||
Write-Host "Version $version"
|
Write-Host "Version $version"
|
||||||
# if ($version -ne $args[0])
|
if (-not ($version.StartsWith($args[0].ToString())))
|
||||||
# {
|
{
|
||||||
# Write-Host "PATH='$env:path'"
|
Write-Host "PATH='$env:PATH'"
|
||||||
# Write-Host "gcm dotnet:"
|
throw "Unexpected version"
|
||||||
# gcm dotnet | fl
|
}
|
||||||
# throw "Unexpected version"
|
}
|
||||||
# }
|
|
||||||
|
if ($args[1])
|
||||||
|
{
|
||||||
|
# SDKs are listed on multiple lines with the path afterwards in square brackets
|
||||||
|
$versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() }
|
||||||
|
Write-Host "Installed versions: $versions"
|
||||||
|
$InstalledVersionCount = 0
|
||||||
|
foreach($arg in $args){
|
||||||
|
foreach ($version in $versions)
|
||||||
|
{
|
||||||
|
if ($version.StartsWith($arg.ToString()))
|
||||||
|
{
|
||||||
|
$InstalledVersionCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( $InstalledVersionCount -ne $args.Count)
|
||||||
|
{
|
||||||
|
Write-Host "PATH='$env:PATH'"
|
||||||
|
throw "Unexpected version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write-Host "Building sample csproj"
|
Write-Host "Building sample csproj"
|
||||||
& $dotnet build __tests__/sample-csproj/ --no-cache
|
& $dotnet build __tests__/sample-csproj/ --no-cache
|
||||||
@ -24,9 +47,27 @@ if ($LASTEXITCODE -ne 0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Write-Host "Testing compiled app"
|
Write-Host "Testing compiled app"
|
||||||
$sample_output = "$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample.exe)".Trim()
|
$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)"
|
||||||
Write-Host "Sample output: $sample_output"
|
Write-Host "Sample output: $sample_output"
|
||||||
if ($sample_output -notlike "*Hello*World*")
|
# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once
|
||||||
|
if ($args[1])
|
||||||
|
{
|
||||||
|
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*")
|
||||||
{
|
{
|
||||||
throw "Unexpected output"
|
throw "Unexpected output"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if ($args[2])
|
||||||
|
{
|
||||||
|
if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*Test Run Successful.*")
|
||||||
|
{
|
||||||
|
throw "Unexpected output"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($sample_output -notlike "*Test Run Successful.*")
|
||||||
|
{
|
||||||
|
throw "Unexpected output"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,11 @@ if [ -z "$1" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "../nuget.config" ]; then
|
||||||
|
echo "nuget file not generated correctly"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
dotnet_version="$(dotnet --version)"
|
dotnet_version="$(dotnet --version)"
|
||||||
echo "Found dotnet version '$dotnet_version'"
|
echo "Found dotnet version '$dotnet_version'"
|
||||||
if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
||||||
@ -10,13 +15,30 @@ if [ -z "$(echo $dotnet_version | grep $1)" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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"
|
echo "Building sample csproj"
|
||||||
dotnet build __tests__/sample-csproj/ --no-cache || exit 1
|
dotnet build __tests__/sample-csproj/ --no-cache || exit 1
|
||||||
|
|
||||||
echo "Testing compiled app"
|
echo "Testing compiled app"
|
||||||
sample_output="$(__tests__/sample-csproj/bin/Debug/netcoreapp3.0/sample)"
|
sample_output=$(dotnet test __tests__/sample-csproj/ --no-build)
|
||||||
echo "Sample output: $sample_output"
|
echo "Sample output: $sample_output"
|
||||||
if [ -z "$(echo $sample_output | grep Hello)" ]; then
|
# 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"
|
echo "Unexpected output"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
else
|
||||||
|
if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then
|
||||||
|
echo "Unexpected output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
91
__tests__/versionutil.test.ts
Normal file
91
__tests__/versionutil.test.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import each from 'jest-each';
|
||||||
|
import * as installer from '../src/installer';
|
||||||
|
|
||||||
|
describe('version tests', () => {
|
||||||
|
each(['3.1.999', '3.1.101-preview.3']).test(
|
||||||
|
"Exact version '%s' should be the same",
|
||||||
|
vers => {
|
||||||
|
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||||
|
|
||||||
|
expect(versInfo.isExactVersion()).toBe(true);
|
||||||
|
expect(versInfo.version()).toBe(vers);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
each([
|
||||||
|
['3.x', '3.x'],
|
||||||
|
['3.*', '3.*'],
|
||||||
|
['3.1.x', '3.1'],
|
||||||
|
['1.1.*', '1.1'],
|
||||||
|
['2.0', '2.0']
|
||||||
|
]).test("Generic version '%s' should be '%s'", (vers, resVers) => {
|
||||||
|
let versInfo = new installer.DotNetVersionInfo(vers);
|
||||||
|
|
||||||
|
expect(versInfo.isExactVersion()).toBe(false);
|
||||||
|
expect(versInfo.version()).toBe(resVers);
|
||||||
|
});
|
||||||
|
|
||||||
|
each([
|
||||||
|
'',
|
||||||
|
'.',
|
||||||
|
'..',
|
||||||
|
' . ',
|
||||||
|
'. ',
|
||||||
|
' .',
|
||||||
|
' . . ',
|
||||||
|
' .. ',
|
||||||
|
' . ',
|
||||||
|
'-1.-1',
|
||||||
|
'-1',
|
||||||
|
'-1.-1.-1',
|
||||||
|
'..3',
|
||||||
|
'1..3',
|
||||||
|
'1..',
|
||||||
|
'.2.3',
|
||||||
|
'.2.x',
|
||||||
|
'1',
|
||||||
|
'*.*.1',
|
||||||
|
'*.1',
|
||||||
|
'*.',
|
||||||
|
'1.2.',
|
||||||
|
'1.2.-abc',
|
||||||
|
'a.b',
|
||||||
|
'a.b.c',
|
||||||
|
'a.b.c-preview',
|
||||||
|
' 0 . 1 . 2 '
|
||||||
|
]).test("Malformed version '%s' should throw", vers => {
|
||||||
|
expect(() => new installer.DotNetVersionInfo(vers)).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
each([
|
||||||
|
['3.1.x', '3.1.'],
|
||||||
|
['3.1.*', '3.1.'],
|
||||||
|
['3.1', '3.1.'],
|
||||||
|
['5.0.0-preview.6', '5.0.0-preview.6'],
|
||||||
|
['3.1.201', '3.1.201']
|
||||||
|
]).test(
|
||||||
|
"Resolving version '%s' as '%s'",
|
||||||
|
async (input, expectedVersion) => {
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller(input);
|
||||||
|
let versInfo = await dotnetInstaller.resolveVersion(
|
||||||
|
new installer.DotNetVersionInfo(input)
|
||||||
|
);
|
||||||
|
console.log(versInfo);
|
||||||
|
|
||||||
|
expect(versInfo.startsWith(expectedVersion));
|
||||||
|
},
|
||||||
|
100000
|
||||||
|
);
|
||||||
|
|
||||||
|
it('Resolving a nonexistent generic version fails', async () => {
|
||||||
|
const dotnetInstaller = new installer.DotnetCoreInstaller('999.1.x');
|
||||||
|
try {
|
||||||
|
await dotnetInstaller.resolveVersion(
|
||||||
|
new installer.DotNetVersionInfo('999.1.x')
|
||||||
|
);
|
||||||
|
fail();
|
||||||
|
} catch {
|
||||||
|
expect(true);
|
||||||
|
}
|
||||||
|
}, 100000);
|
||||||
|
});
|
16
action.yml
16
action.yml
@ -1,22 +1,24 @@
|
|||||||
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'
|
||||||
|
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.'
|
||||||
# Deprecated option, do not use. Will not be supported after October 1, 2019
|
include-prerelease:
|
||||||
version:
|
description: 'Whether prerelease versions should be matched with non-exact versions (for example 5.0.0-preview.6 being matched by 5, 5.0, 5.x or 5.0.x). Defaults to false if not provided.'
|
||||||
description: 'Deprecated. Use dotnet-version instead. Will not be supported after October 1, 2019'
|
required: False
|
||||||
deprecationMessage: 'The version property will not be supported after October 1, 2019. Use dotnet-version instead'
|
default: 'false'
|
||||||
runs:
|
runs:
|
||||||
using: 'node12'
|
using: 'node16'
|
||||||
main: 'dist/index.js'
|
main: 'dist/index.js'
|
||||||
|
33613
dist/index.js
vendored
33613
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,17 +1,113 @@
|
|||||||
# Contributors
|
# Contributors
|
||||||
|
|
||||||
|
Thank you for contributing!
|
||||||
|
|
||||||
# Checkin
|
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!
|
||||||
|
|
||||||
- Do checkin source (src)
|
## How can I contribute...
|
||||||
- Do checkin build output (lib)
|
|
||||||
- Do checkin runtime node_modules
|
|
||||||
- Do not checkin
|
|
||||||
|
|
||||||
# Adding a dev dependency
|
* [Contribute Documentation:green_book:](#contribute-documentation)
|
||||||
|
|
||||||
Remember to update .gitignore.
|
* [Contribute Code :computer:](#contribute-code)
|
||||||
|
|
||||||
# Updating toolkit dependency
|
* [Provide Support on Issues:pencil:](#provide-support-on-issues)
|
||||||
|
|
||||||
Until released publically, update tgz packages in toolkit
|
* [Review Pull Requests:mag:](#review-pull-requests)
|
||||||
|
|
||||||
|
## 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 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 [workflow.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/workflow.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
|
192
externals/get-os-distro.sh
vendored
192
externals/get-os-distro.sh
vendored
@ -1,192 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Copyright (c) .NET Foundation and contributors. All rights reserved.
|
|
||||||
# Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
#
|
|
||||||
|
|
||||||
# Stop script on NZEC
|
|
||||||
set -e
|
|
||||||
# Stop script if unbound variable found (use ${var:-} if intentional)
|
|
||||||
set -u
|
|
||||||
# By default cmd1 | cmd2 returns exit code of cmd2 regardless of cmd1 success
|
|
||||||
# This is causing it to fail
|
|
||||||
set -o pipefail
|
|
||||||
|
|
||||||
# Use in the the functions: eval $invocation
|
|
||||||
invocation='say_verbose "Calling: ${yellow:-}${FUNCNAME[0]} ${green:-}$*${normal:-}"'
|
|
||||||
|
|
||||||
# standard output may be used as a return value in the functions
|
|
||||||
# we need a way to write text on the screen in the functions so that
|
|
||||||
# it won't interfere with the return value.
|
|
||||||
# Exposing stream 3 as a pipe to standard output of the script itself
|
|
||||||
exec 3>&1
|
|
||||||
|
|
||||||
say_err() {
|
|
||||||
printf "%b\n" "get-os-distro: Error: $1" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
# This platform list is finite - if the SDK/Runtime has supported Linux distribution-specific assets,
|
|
||||||
# then and only then should the Linux distribution appear in this list.
|
|
||||||
# Adding a Linux distribution to this list does not imply distribution-specific support.
|
|
||||||
get_legacy_os_name_from_platform() {
|
|
||||||
|
|
||||||
platform="$1"
|
|
||||||
case "$platform" in
|
|
||||||
"centos.7")
|
|
||||||
echo "centos"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"debian.8")
|
|
||||||
echo "debian"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"fedora.23")
|
|
||||||
echo "fedora.23"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"fedora.27")
|
|
||||||
echo "fedora.27"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"fedora.24")
|
|
||||||
echo "fedora.24"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"opensuse.13.2")
|
|
||||||
echo "opensuse.13.2"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"opensuse.42.1")
|
|
||||||
echo "opensuse.42.1"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"opensuse.42.3")
|
|
||||||
echo "opensuse.42.3"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"rhel.7"*)
|
|
||||||
echo "rhel"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"ubuntu.14.04")
|
|
||||||
echo "ubuntu"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"ubuntu.16.04")
|
|
||||||
echo "ubuntu.16.04"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"ubuntu.16.10")
|
|
||||||
echo "ubuntu.16.10"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"ubuntu.18.04")
|
|
||||||
echo "ubuntu.18.04"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
"alpine.3.4.3")
|
|
||||||
echo "alpine"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
get_linux_platform_name() {
|
|
||||||
|
|
||||||
if [ -e /etc/os-release ]; then
|
|
||||||
. /etc/os-release
|
|
||||||
echo "$ID.$VERSION_ID"
|
|
||||||
return 0
|
|
||||||
elif [ -e /etc/redhat-release ]; then
|
|
||||||
local redhatRelease=$(</etc/redhat-release)
|
|
||||||
if [[ $redhatRelease == "CentOS release 6."* || $redhatRelease == "Red Hat Enterprise Linux Server release 6."* ]]; then
|
|
||||||
echo "rhel.6"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
say_err "Linux specific platform name and version could not be detected: UName = $uname"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
get_current_os_name() {
|
|
||||||
|
|
||||||
local uname=$(uname)
|
|
||||||
if [ "$uname" = "Darwin" ]; then
|
|
||||||
echo "osx"
|
|
||||||
return 0
|
|
||||||
elif [ "$uname" = "Linux" ]; then
|
|
||||||
local linux_platform_name
|
|
||||||
linux_platform_name="$(get_linux_platform_name)" || { echo "linux" && return 0 ; }
|
|
||||||
|
|
||||||
if [[ $linux_platform_name == "rhel.6" ]]; then
|
|
||||||
echo "$linux_platform_name"
|
|
||||||
return 0
|
|
||||||
elif [[ $linux_platform_name == alpine* ]]; then
|
|
||||||
echo "linux-musl"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
echo "linux"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
say_err "OS name could not be detected: UName = $uname"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
get_legacy_os_name() {
|
|
||||||
|
|
||||||
local uname=$(uname)
|
|
||||||
if [ "$uname" = "Darwin" ]; then
|
|
||||||
echo "osx"
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
if [ -e /etc/os-release ]; then
|
|
||||||
. /etc/os-release
|
|
||||||
os=$(get_legacy_os_name_from_platform "$ID.$VERSION_ID" || echo "")
|
|
||||||
if [ -n "$os" ]; then
|
|
||||||
echo "$os"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
say_err "Distribution specific OS name and version could not be detected: UName = $uname"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
get_machine_architecture() {
|
|
||||||
|
|
||||||
if command -v uname > /dev/null; then
|
|
||||||
CPUName=$(uname -m)
|
|
||||||
case $CPUName in
|
|
||||||
armv7l)
|
|
||||||
echo "arm"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
aarch64)
|
|
||||||
echo "arm64"
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Always default to 'x64'
|
|
||||||
echo "x64"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
osName=$(get_current_os_name || echo "")
|
|
||||||
legacyOsName=$(get_legacy_os_name || echo "")
|
|
||||||
arch=$(get_machine_architecture || echo "")
|
|
||||||
|
|
||||||
primaryName="$osName-$arch"
|
|
||||||
legacyName="$legacyOsName"
|
|
||||||
|
|
||||||
echo "Primary:$primaryName"
|
|
||||||
echo "Legacy:$legacyName"
|
|
||||||
|
|
||||||
if [ -z "$osName" ] && [ -z "$legacyOsName" ];then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
18
externals/get-os-platform.ps1
vendored
18
externals/get-os-platform.ps1
vendored
@ -1,18 +0,0 @@
|
|||||||
function Get-Machine-Architecture()
|
|
||||||
{
|
|
||||||
# possible values: AMD64, IA64, x86
|
|
||||||
return $ENV:PROCESSOR_ARCHITECTURE
|
|
||||||
}
|
|
||||||
|
|
||||||
function Get-CLIArchitecture-From-Architecture([string]$Architecture)
|
|
||||||
{
|
|
||||||
switch ($Architecture.ToLower())
|
|
||||||
{
|
|
||||||
{ ($_ -eq "amd64") -or ($_ -eq "x64") } { return "x64" }
|
|
||||||
{ $_ -eq "x86" } { return "x86" }
|
|
||||||
default { throw "Architecture not supported. If you think this is a bug, please report it at https://github.com/dotnet/cli/issues" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$CLIArchitecture = Get-CLIArchitecture-From-Architecture $(Get-Machine-Architecture)
|
|
||||||
Write-Output "Primary:win-$CLIArchitecture"
|
|
1191
externals/install-dotnet.ps1
vendored
1191
externals/install-dotnet.ps1
vendored
File diff suppressed because it is too large
Load Diff
1039
externals/install-dotnet.sh
vendored
1039
externals/install-dotnet.sh
vendored
File diff suppressed because it is too large
Load Diff
8878
package-lock.json
generated
8878
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
32
package.json
32
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "setup-dotnet",
|
"name": "setup-dotnet",
|
||||||
"version": "1.0.0",
|
"version": "2.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"description": "setup dotnet action",
|
"description": "setup dotnet action",
|
||||||
"main": "lib/setup-dotnet.js",
|
"main": "lib/setup-dotnet.js",
|
||||||
@ -8,6 +8,7 @@
|
|||||||
"build": "tsc && ncc build",
|
"build": "tsc && ncc build",
|
||||||
"format": "prettier --write **/*.ts",
|
"format": "prettier --write **/*.ts",
|
||||||
"format-check": "prettier --check **/*.ts",
|
"format-check": "prettier --check **/*.ts",
|
||||||
|
"prepare": "husky install",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"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"
|
||||||
},
|
},
|
||||||
@ -23,26 +24,29 @@
|
|||||||
"author": "GitHub",
|
"author": "GitHub",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.2.2",
|
"@actions/core": "^1.6.0",
|
||||||
"@actions/exec": "^1.0.3",
|
"@actions/exec": "^1.0.4",
|
||||||
"@actions/github": "^1.1.0",
|
"@actions/github": "^1.1.0",
|
||||||
"@actions/http-client": "^1.0.8",
|
"@actions/http-client": "^1.0.8",
|
||||||
"@actions/io": "^1.0.2",
|
"@actions/io": "^1.0.2",
|
||||||
"@actions/tool-cache": "^1.3.1",
|
|
||||||
"fast-xml-parser": "^3.15.1",
|
"fast-xml-parser": "^3.15.1",
|
||||||
"semver": "^6.3.0",
|
"semver": "^6.3.0",
|
||||||
"xmlbuilder": "^13.0.2"
|
"xmlbuilder": "^13.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^24.0.13",
|
"@types/jest": "^27.0.2",
|
||||||
"@types/node": "^12.0.4",
|
"@types/node": "^16.11.25",
|
||||||
"@types/semver": "^6.0.0",
|
"@types/semver": "^6.2.2",
|
||||||
"@zeit/ncc": "^0.21.0",
|
"@vercel/ncc": "^0.33.4",
|
||||||
"jest": "^26.0.1",
|
"husky": "^8.0.1",
|
||||||
"jest-circus": "^26.0.1",
|
"jest": "^27.2.5",
|
||||||
"prettier": "^1.17.1",
|
"jest-circus": "^27.2.5",
|
||||||
"ts-jest": "^26.0.0",
|
"prettier": "^1.19.1",
|
||||||
"typescript": "^3.9.2",
|
"ts-jest": "^27.0.5",
|
||||||
"wget-improved": "^3.0.2"
|
"typescript": "^3.9.7",
|
||||||
|
"wget-improved": "^3.2.1"
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"testEnvironment": "node"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,18 +4,22 @@ import * as core from '@actions/core';
|
|||||||
import * as github from '@actions/github';
|
import * as github from '@actions/github';
|
||||||
import * as xmlbuilder from 'xmlbuilder';
|
import * as xmlbuilder from 'xmlbuilder';
|
||||||
import * as xmlParser 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: string = '',
|
||||||
|
processRoot: string = process.cwd()
|
||||||
) {
|
) {
|
||||||
const existingNuGetConfig: string = path.resolve(
|
const existingNuGetConfig: string = path.resolve(
|
||||||
process.env['RUNNER_TEMP'] || process.cwd(),
|
processRoot,
|
||||||
existingFileLocation == '' ? 'nuget.config' : existingFileLocation
|
existingFileLocation === ''
|
||||||
|
? getExistingNugetConfig(processRoot)
|
||||||
|
: existingFileLocation
|
||||||
);
|
);
|
||||||
|
|
||||||
const tempNuGetConfig: string = path.resolve(
|
const tempNuGetConfig: string = path.resolve(
|
||||||
process.env['RUNNER_TEMP'] || process.cwd(),
|
processRoot,
|
||||||
'../',
|
'../',
|
||||||
'nuget.config'
|
'nuget.config'
|
||||||
);
|
);
|
||||||
@ -23,6 +27,21 @@ 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,
|
||||||
@ -107,9 +126,9 @@ function writeFeedToFile(
|
|||||||
xml = xml.ele('packageSourceCredentials');
|
xml = xml.ele('packageSourceCredentials');
|
||||||
|
|
||||||
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."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
452
src/installer.ts
452
src/installer.ts
@ -1,40 +1,26 @@
|
|||||||
// Load tempDirectory before it gets wiped by tool-cache
|
// Load tempDirectory before it gets wiped by tool-cache
|
||||||
let tempDirectory = process.env['RUNNER_TEMPDIRECTORY'] || '';
|
|
||||||
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 * as tc from '@actions/tool-cache';
|
|
||||||
import hc = require('@actions/http-client');
|
import hc = require('@actions/http-client');
|
||||||
import {chmodSync} from 'fs';
|
import {chmodSync} from 'fs';
|
||||||
import * as os from 'os';
|
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import {ExecOptions} from '@actions/exec/lib/interfaces';
|
||||||
import * as semver from 'semver';
|
import * as semver from 'semver';
|
||||||
|
|
||||||
const IS_WINDOWS = process.platform === 'win32';
|
const IS_WINDOWS = process.platform === 'win32';
|
||||||
|
|
||||||
if (!tempDirectory) {
|
|
||||||
let baseLocation;
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
// On windows use the USERPROFILE env variable
|
|
||||||
baseLocation = process.env['USERPROFILE'] || 'C:\\';
|
|
||||||
} else {
|
|
||||||
if (process.platform === 'darwin') {
|
|
||||||
baseLocation = '/Users';
|
|
||||||
} else {
|
|
||||||
baseLocation = '/home';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tempDirectory = path.join(baseLocation, 'actions', 'temp');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the inputted version information
|
* Represents the inputted version information
|
||||||
*/
|
*/
|
||||||
export class DotNetVersionInfo {
|
export class DotNetVersionInfo {
|
||||||
|
public inputVersion: string;
|
||||||
private fullversion: string;
|
private fullversion: string;
|
||||||
private isExactVersionSet: boolean = false;
|
private isExactVersionSet: boolean = false;
|
||||||
|
|
||||||
constructor(version: string) {
|
constructor(version: string) {
|
||||||
|
this.inputVersion = version;
|
||||||
|
|
||||||
// Check for exact match
|
// Check for exact match
|
||||||
if (semver.valid(semver.clean(version) || '') != null) {
|
if (semver.valid(semver.clean(version) || '') != null) {
|
||||||
this.fullversion = semver.clean(version) as string;
|
this.fullversion = semver.clean(version) as string;
|
||||||
@ -43,8 +29,7 @@ export class DotNetVersionInfo {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: No support for previews when using generic
|
const parts: string[] = version.split('.');
|
||||||
let parts: string[] = version.split('.');
|
|
||||||
|
|
||||||
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
|
if (parts.length < 2 || parts.length > 3) this.throwInvalidVersionFormat();
|
||||||
|
|
||||||
@ -52,8 +37,10 @@ export class DotNetVersionInfo {
|
|||||||
this.throwInvalidVersionFormat();
|
this.throwInvalidVersionFormat();
|
||||||
}
|
}
|
||||||
|
|
||||||
let major = this.getVersionNumberOrThrow(parts[0]);
|
const major = this.getVersionNumberOrThrow(parts[0]);
|
||||||
let minor = this.getVersionNumberOrThrow(parts[1]);
|
const minor = ['x', '*'].includes(parts[1])
|
||||||
|
? parts[1]
|
||||||
|
: this.getVersionNumberOrThrow(parts[1]);
|
||||||
|
|
||||||
this.fullversion = major + '.' + minor;
|
this.fullversion = major + '.' + minor;
|
||||||
}
|
}
|
||||||
@ -74,7 +61,9 @@ export class DotNetVersionInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private throwInvalidVersionFormat() {
|
private throwInvalidVersionFormat() {
|
||||||
throw 'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*';
|
throw new Error(
|
||||||
|
'Invalid version format! Supported: 1.2.3, 1.2, 1.2.x, 1.2.*'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,91 +78,55 @@ export class DotNetVersionInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a resolved version from the Web-Api
|
|
||||||
*/
|
|
||||||
class ResolvedVersionInfo {
|
|
||||||
downloadUrls: string[];
|
|
||||||
resolvedVersion: string;
|
|
||||||
|
|
||||||
constructor(downloadUrls: string[], resolvedVersion: string) {
|
|
||||||
if (downloadUrls.length === 0) {
|
|
||||||
throw 'DownloadUrls can not be empty';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resolvedVersion) {
|
|
||||||
throw 'Resolved version is invalid';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.downloadUrls = downloadUrls;
|
|
||||||
this.resolvedVersion = resolvedVersion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DotnetCoreInstaller {
|
export class DotnetCoreInstaller {
|
||||||
constructor(version: string) {
|
constructor(version: string, includePrerelease: boolean = false) {
|
||||||
this.versionInfo = new DotNetVersionInfo(version);
|
this.version = version;
|
||||||
this.cachedToolName = 'dncs';
|
this.includePrerelease = includePrerelease;
|
||||||
this.arch = 'x64';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async installDotnet() {
|
public async installDotnet() {
|
||||||
// Check cache
|
let output = '';
|
||||||
let toolPath: string = '';
|
let resultCode = 0;
|
||||||
let osSuffixes = await this.detectMachineOS();
|
|
||||||
let parts = osSuffixes[0].split('-');
|
|
||||||
if (parts.length > 1) {
|
|
||||||
this.arch = parts[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// If version is not generic -> look up cache
|
let calculatedVersion = await this.resolveVersion(
|
||||||
if (this.versionInfo.isExactVersion())
|
new DotNetVersionInfo(this.version)
|
||||||
toolPath = this.getLocalTool(this.versionInfo.version());
|
|
||||||
|
|
||||||
if (!toolPath) {
|
|
||||||
// download, extract, cache
|
|
||||||
console.log('Getting a download url', this.versionInfo.version());
|
|
||||||
let resolvedVersionInfo = await this.resolveInfos(
|
|
||||||
osSuffixes,
|
|
||||||
this.versionInfo
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//Check if cache exists for resolved version
|
var envVariables: {[key: string]: string} = {};
|
||||||
toolPath = this.getLocalTool(resolvedVersionInfo.resolvedVersion);
|
for (let key in process.env) {
|
||||||
if (!toolPath) {
|
if (process.env[key]) {
|
||||||
//If not exists install it
|
let value: any = process.env[key];
|
||||||
toolPath = await this.downloadAndInstall(resolvedVersionInfo);
|
envVariables[key] = value;
|
||||||
} else {
|
|
||||||
console.log('Using cached tool');
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
console.log('Using cached tool');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Need to set this so that .NET Core global tools find the right locations.
|
|
||||||
core.exportVariable('DOTNET_ROOT', toolPath);
|
|
||||||
|
|
||||||
// Prepend the tools path. instructs the agent to prepend for future tasks
|
|
||||||
core.addPath(toolPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private getLocalTool(version: string): string {
|
|
||||||
console.log('Checking tool cache', version);
|
|
||||||
return tc.find(this.cachedToolName, version, this.arch);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async detectMachineOS(): Promise<string[]> {
|
|
||||||
let osSuffix: string[] = [];
|
|
||||||
let output = '';
|
|
||||||
|
|
||||||
let resultCode = 0;
|
|
||||||
if (IS_WINDOWS) {
|
if (IS_WINDOWS) {
|
||||||
let escapedScript = path
|
let escapedScript = path
|
||||||
.join(__dirname, '..', 'externals', 'get-os-platform.ps1')
|
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
||||||
.replace(/'/g, "''");
|
.replace(/'/g, "''");
|
||||||
let command = `& '${escapedScript}'`;
|
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);
|
const powershellPath = await io.which('powershell', true);
|
||||||
|
|
||||||
|
var options: ExecOptions = {
|
||||||
|
listeners: {
|
||||||
|
stdout: (data: Buffer) => {
|
||||||
|
output += data.toString();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
env: envVariables
|
||||||
|
};
|
||||||
|
|
||||||
resultCode = await exec.exec(
|
resultCode = await exec.exec(
|
||||||
`"${powershellPath}"`,
|
`"${powershellPath}"`,
|
||||||
[
|
[
|
||||||
@ -186,98 +139,70 @@ export class DotnetCoreInstaller {
|
|||||||
'-Command',
|
'-Command',
|
||||||
command
|
command
|
||||||
],
|
],
|
||||||
{
|
options
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let scriptPath = path.join(
|
let escapedScript = path
|
||||||
__dirname,
|
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
||||||
'..',
|
.replace(/'/g, "''");
|
||||||
'externals',
|
chmodSync(escapedScript, '777');
|
||||||
'get-os-distro.sh'
|
|
||||||
);
|
|
||||||
chmodSync(scriptPath, '777');
|
|
||||||
|
|
||||||
const toolPath = await io.which(scriptPath, true);
|
const scriptPath = await io.which(escapedScript, true);
|
||||||
resultCode = await exec.exec(`"${toolPath}"`, [], {
|
|
||||||
|
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: {
|
listeners: {
|
||||||
stdout: (data: Buffer) => {
|
stdout: (data: Buffer) => {
|
||||||
output += data.toString();
|
output += data.toString();
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
env: envVariables
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultCode != 0) {
|
if (resultCode != 0) {
|
||||||
throw `Failed to detect os with result code ${resultCode}. Output: ${output}`;
|
throw new Error(`Failed to install dotnet ${resultCode}. ${output}`);
|
||||||
}
|
|
||||||
|
|
||||||
let index;
|
|
||||||
if ((index = output.indexOf('Primary:')) >= 0) {
|
|
||||||
let primary = output.substr(index + 'Primary:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((index = output.indexOf('Legacy:')) >= 0) {
|
|
||||||
let legacy = output.substr(index + 'Legacy:'.length).split(os.EOL)[0];
|
|
||||||
osSuffix.push(legacy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (osSuffix.length == 0) {
|
|
||||||
throw 'Could not detect platform';
|
|
||||||
}
|
|
||||||
|
|
||||||
return osSuffix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async downloadAndInstall(resolvedVersionInfo: ResolvedVersionInfo) {
|
|
||||||
let downloaded = false;
|
|
||||||
let downloadPath = '';
|
|
||||||
for (const url of resolvedVersionInfo.downloadUrls) {
|
|
||||||
try {
|
|
||||||
downloadPath = await tc.downloadTool(url);
|
|
||||||
downloaded = true;
|
|
||||||
break;
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Could not Download', url, JSON.stringify(error));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!downloaded) {
|
static addToPath() {
|
||||||
throw 'Failed to download package';
|
if (process.env['DOTNET_INSTALL_DIR']) {
|
||||||
}
|
core.addPath(process.env['DOTNET_INSTALL_DIR']);
|
||||||
|
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
|
||||||
// extract
|
} else {
|
||||||
console.log('Extracting Package', downloadPath);
|
if (IS_WINDOWS) {
|
||||||
let extPath: string = IS_WINDOWS
|
// This is the default set in install-dotnet.ps1
|
||||||
? await tc.extractZip(downloadPath)
|
core.addPath(
|
||||||
: await tc.extractTar(downloadPath);
|
path.join(process.env['LocalAppData'] + '', 'Microsoft', 'dotnet')
|
||||||
|
|
||||||
// cache tool
|
|
||||||
console.log('Caching tool');
|
|
||||||
let cachedDir = await tc.cacheDir(
|
|
||||||
extPath,
|
|
||||||
this.cachedToolName,
|
|
||||||
resolvedVersionInfo.resolvedVersion,
|
|
||||||
this.arch
|
|
||||||
);
|
);
|
||||||
|
core.exportVariable(
|
||||||
console.log('Successfully installed', resolvedVersionInfo.resolvedVersion);
|
'DOTNET_ROOT',
|
||||||
return cachedDir;
|
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']);
|
||||||
}
|
}
|
||||||
|
|
||||||
// OsSuffixes - The suffix which is a part of the file name ex- linux-x64, windows-x86
|
|
||||||
// Type - SDK / Runtime
|
|
||||||
// versionInfo - versionInfo of the SDK/Runtime
|
// versionInfo - versionInfo of the SDK/Runtime
|
||||||
async resolveInfos(
|
async resolveVersion(versionInfo: DotNetVersionInfo): Promise<string> {
|
||||||
osSuffixes: string[],
|
if (versionInfo.isExactVersion()) {
|
||||||
versionInfo: DotNetVersionInfo
|
return versionInfo.version();
|
||||||
): Promise<ResolvedVersionInfo> {
|
}
|
||||||
|
|
||||||
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
const httpClient = new hc.HttpClient('actions/setup-dotnet', [], {
|
||||||
allowRetries: true,
|
allowRetries: true,
|
||||||
maxRetries: 3
|
maxRetries: 3
|
||||||
@ -293,79 +218,43 @@ export class DotnetCoreInstaller {
|
|||||||
let releasesInfo: any[] = releasesResult['releases'];
|
let releasesInfo: any[] = releasesResult['releases'];
|
||||||
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
|
releasesInfo = releasesInfo.filter((releaseInfo: any) => {
|
||||||
return (
|
return (
|
||||||
semver.satisfies(
|
semver.satisfies(releaseInfo['sdk']['version'], versionInfo.version(), {
|
||||||
releaseInfo['sdk']['version'],
|
includePrerelease: this.includePrerelease
|
||||||
versionInfo.version()
|
}) ||
|
||||||
) ||
|
|
||||||
semver.satisfies(
|
semver.satisfies(
|
||||||
releaseInfo['sdk']['version-display'],
|
releaseInfo['sdk']['version-display'],
|
||||||
versionInfo.version()
|
versionInfo.version(),
|
||||||
|
{
|
||||||
|
includePrerelease: this.includePrerelease
|
||||||
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Exclude versions that are newer than the latest if using not exact
|
// Exclude versions that are newer than the latest if using not exact
|
||||||
if (!versionInfo.isExactVersion()) {
|
|
||||||
let latestSdk: string = releasesResult['latest-sdk'];
|
let latestSdk: string = releasesResult['latest-sdk'];
|
||||||
|
|
||||||
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
|
releasesInfo = releasesInfo.filter((releaseInfo: any) =>
|
||||||
semver.lte(releaseInfo['sdk']['version'], latestSdk)
|
semver.lte(releaseInfo['sdk']['version'], latestSdk, {
|
||||||
|
includePrerelease: this.includePrerelease
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Sort for latest version
|
// Sort for latest version
|
||||||
releasesInfo = releasesInfo.sort((a, b) =>
|
releasesInfo = releasesInfo.sort((a, b) =>
|
||||||
semver.rcompare(a['sdk']['version'], b['sdk']['version'])
|
semver.rcompare(a['sdk']['version'], b['sdk']['version'], {
|
||||||
|
includePrerelease: this.includePrerelease
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
let downloadedVersion: string = '';
|
if (releasesInfo.length == 0) {
|
||||||
let downloadUrls: string[] = [];
|
throw new Error(
|
||||||
|
`Could not find dotnet core version. Please ensure that specified version ${versionInfo.inputVersion} is valid.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (releasesInfo.length != 0) {
|
|
||||||
let release = releasesInfo[0];
|
let release = releasesInfo[0];
|
||||||
|
return release['sdk']['version'];
|
||||||
downloadedVersion = release['sdk']['version'];
|
|
||||||
|
|
||||||
let files: any[] = release['sdk']['files'];
|
|
||||||
files = files.filter((file: any) => {
|
|
||||||
if (file['rid'] == osSuffixes[0] || file['rid'] == osSuffixes[1]) {
|
|
||||||
return (
|
|
||||||
file['url'].endsWith('.zip') || file['url'].endsWith('.tar.gz')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (files.length > 0) {
|
|
||||||
files.forEach((file: any) => {
|
|
||||||
downloadUrls.push(file['url']);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
throw `The specified version's download links are not correctly formed in the supported versions document => ${releasesJsonUrl}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(
|
|
||||||
`Could not fetch download information for version ${versionInfo.version()}`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (versionInfo.isExactVersion()) {
|
|
||||||
console.log('Using fallback');
|
|
||||||
|
|
||||||
downloadUrls = await this.getFallbackDownloadUrls(
|
|
||||||
versionInfo.version()
|
|
||||||
);
|
|
||||||
downloadedVersion = versionInfo.version();
|
|
||||||
} else {
|
|
||||||
console.log('Unable to use fallback, version is generic!');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadUrls.length == 0) {
|
|
||||||
throw `Could not construct download URL. Please ensure that specified version ${versionInfo.version()}/${downloadedVersion} is valid.`;
|
|
||||||
}
|
|
||||||
|
|
||||||
core.debug(`Got download urls ${downloadUrls}`);
|
|
||||||
|
|
||||||
return new ResolvedVersionInfo(downloadUrls, downloadedVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getReleasesJsonUrl(
|
private async getReleasesJsonUrl(
|
||||||
@ -375,124 +264,39 @@ export class DotnetCoreInstaller {
|
|||||||
const response = await httpClient.getJson<any>(DotNetCoreIndexUrl);
|
const response = await httpClient.getJson<any>(DotNetCoreIndexUrl);
|
||||||
const result = response.result || {};
|
const result = response.result || {};
|
||||||
let releasesInfo: any[] = result['releases-index'];
|
let releasesInfo: any[] = result['releases-index'];
|
||||||
|
|
||||||
releasesInfo = releasesInfo.filter((info: any) => {
|
releasesInfo = releasesInfo.filter((info: any) => {
|
||||||
// channel-version is the first 2 elements of the version (e.g. 2.1), filter out versions that don't match 2.1.x.
|
// 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 (versionParts.length >= 2 && versionParts[1] != 'x') {
|
if (
|
||||||
|
versionParts.length >= 2 &&
|
||||||
|
!(versionParts[1] == 'x' || versionParts[1] == '*')
|
||||||
|
) {
|
||||||
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
|
return versionParts[0] == sdkParts[0] && versionParts[1] == sdkParts[1];
|
||||||
}
|
}
|
||||||
return versionParts[0] == sdkParts[0];
|
return versionParts[0] == sdkParts[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (releasesInfo.length === 0) {
|
if (releasesInfo.length === 0) {
|
||||||
throw `Could not find info for version ${versionParts.join(
|
throw new Error(
|
||||||
|
`Could not find info for version ${versionParts.join(
|
||||||
'.'
|
'.'
|
||||||
)} at ${DotNetCoreIndexUrl}`;
|
)} at ${DotNetCoreIndexUrl}`
|
||||||
}
|
|
||||||
return releasesInfo[0]['releases.json'];
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getFallbackDownloadUrls(version: string): Promise<string[]> {
|
|
||||||
let primaryUrlSearchString: string;
|
|
||||||
let legacyUrlSearchString: string;
|
|
||||||
let output = '';
|
|
||||||
let resultCode = 0;
|
|
||||||
|
|
||||||
if (IS_WINDOWS) {
|
|
||||||
let escapedScript = path
|
|
||||||
.join(__dirname, '..', 'externals', 'install-dotnet.ps1')
|
|
||||||
.replace(/'/g, "''");
|
|
||||||
let command = `& '${escapedScript}' -Version ${version} -DryRun`;
|
|
||||||
|
|
||||||
const powershellPath = await io.which('powershell', true);
|
|
||||||
resultCode = await exec.exec(
|
|
||||||
`"${powershellPath}"`,
|
|
||||||
[
|
|
||||||
'-NoLogo',
|
|
||||||
'-Sta',
|
|
||||||
'-NoProfile',
|
|
||||||
'-NonInteractive',
|
|
||||||
'-ExecutionPolicy',
|
|
||||||
'Unrestricted',
|
|
||||||
'-Command',
|
|
||||||
command
|
|
||||||
],
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
const releaseInfo = releasesInfo[0];
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
if (releaseInfo['support-phase'] === 'eol') {
|
||||||
} else {
|
core.warning(
|
||||||
let escapedScript = path
|
`${releaseInfo['product']} ${releaseInfo['channel-version']} is no longer supported and will not receive security updates in the future. Please refer to https://aka.ms/dotnet-core-support for more information about the .NET support policy.`
|
||||||
.join(__dirname, '..', 'externals', 'install-dotnet.sh')
|
|
||||||
.replace(/'/g, "''");
|
|
||||||
chmodSync(escapedScript, '777');
|
|
||||||
|
|
||||||
const scriptPath = await io.which(escapedScript, true);
|
|
||||||
resultCode = await exec.exec(
|
|
||||||
`"${scriptPath}"`,
|
|
||||||
['--version', version, '--dry-run'],
|
|
||||||
{
|
|
||||||
listeners: {
|
|
||||||
stdout: (data: Buffer) => {
|
|
||||||
output += data.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
primaryUrlSearchString = 'dotnet-install: Primary named payload URL: ';
|
|
||||||
legacyUrlSearchString = 'dotnet-install: Legacy named payload URL: ';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resultCode != 0) {
|
return releaseInfo['releases.json'];
|
||||||
throw `Failed to get download urls with result code ${resultCode}. ${output}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let primaryUrl: string = '';
|
private version: string;
|
||||||
let legacyUrl: string = '';
|
private includePrerelease: boolean;
|
||||||
if (!!output && output.length > 0) {
|
|
||||||
let lines: string[] = output.split(os.EOL);
|
|
||||||
|
|
||||||
// Fallback to \n if initial split doesn't work (not consistent across versions)
|
|
||||||
if (lines.length === 1) {
|
|
||||||
lines = output.split('\n');
|
|
||||||
}
|
|
||||||
if (!!lines && lines.length > 0) {
|
|
||||||
lines.forEach((line: string) => {
|
|
||||||
if (!line) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var primarySearchStringIndex = line.indexOf(primaryUrlSearchString);
|
|
||||||
if (primarySearchStringIndex > -1) {
|
|
||||||
primaryUrl = line.substring(
|
|
||||||
primarySearchStringIndex + primaryUrlSearchString.length
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var legacySearchStringIndex = line.indexOf(legacyUrlSearchString);
|
|
||||||
if (legacySearchStringIndex > -1) {
|
|
||||||
legacyUrl = line.substring(
|
|
||||||
legacySearchStringIndex + legacyUrlSearchString.length
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [primaryUrl, legacyUrl];
|
|
||||||
}
|
|
||||||
|
|
||||||
private versionInfo: DotNetVersionInfo;
|
|
||||||
private cachedToolName: string;
|
|
||||||
private arch: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DotNetCoreIndexUrl: string =
|
const DotNetCoreIndexUrl: string =
|
||||||
|
@ -7,31 +7,50 @@ import * as auth from './authutil';
|
|||||||
export async function run() {
|
export async function run() {
|
||||||
try {
|
try {
|
||||||
//
|
//
|
||||||
// Version is optional. If supplied, install / use from the tool cache
|
// dotnet-version is optional, but needs to be provided for most use cases.
|
||||||
// If not supplied then task is still used to setup proxy, auth, etc...
|
// 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 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
|
||||||
//
|
//
|
||||||
let version: string = core.getInput('version');
|
let versions = core.getMultilineInput('dotnet-version');
|
||||||
if (!version) {
|
|
||||||
version = core.getInput('dotnet-version');
|
const globalJsonFileInput = core.getInput('global-json-file');
|
||||||
|
if (globalJsonFileInput) {
|
||||||
|
const globalJsonPath = path.join(process.cwd(), globalJsonFileInput);
|
||||||
|
if (!fs.existsSync(globalJsonPath)) {
|
||||||
|
throw new Error(
|
||||||
|
`The specified global.json file '${globalJsonFileInput}' does not exist`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!version) {
|
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'})
|
|
||||||
);
|
|
||||||
if (globalJson.sdk && globalJson.sdk.version) {
|
|
||||||
version = globalJson.sdk.version;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version) {
|
if (versions.length) {
|
||||||
const dotnetInstaller = new installer.DotnetCoreInstaller(version);
|
const includePrerelease: boolean = core.getBooleanInput(
|
||||||
|
'include-prerelease'
|
||||||
|
);
|
||||||
|
let dotnetInstaller!: installer.DotnetCoreInstaller;
|
||||||
|
for (const version of new Set<string>(versions)) {
|
||||||
|
dotnetInstaller = new installer.DotnetCoreInstaller(
|
||||||
|
version,
|
||||||
|
includePrerelease
|
||||||
|
);
|
||||||
await dotnetInstaller.installDotnet();
|
await dotnetInstaller.installDotnet();
|
||||||
}
|
}
|
||||||
|
installer.DotnetCoreInstaller.addToPath();
|
||||||
|
}
|
||||||
|
|
||||||
const sourceUrl: string = core.getInput('source-url');
|
const sourceUrl: string = core.getInput('source-url');
|
||||||
const configFile: string = core.getInput('config-file');
|
const configFile: string = core.getInput('config-file');
|
||||||
@ -46,4 +65,21 @@ export async function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getVersionFromGlobalJson(globalJsonPath: string): string {
|
||||||
|
let version: string = '';
|
||||||
|
const globalJson = JSON.parse(
|
||||||
|
// .trim() is necessary to strip BOM https://github.com/nodejs/node/issues/20649
|
||||||
|
fs.readFileSync(globalJsonPath, {encoding: 'utf8'}).trim()
|
||||||
|
);
|
||||||
|
if (globalJson.sdk && globalJson.sdk.version) {
|
||||||
|
version = globalJson.sdk.version;
|
||||||
|
const rollForward = globalJson.sdk.rollForward;
|
||||||
|
if (rollForward && rollForward === 'latestFeature') {
|
||||||
|
const [major, minor] = version.split('.');
|
||||||
|
version = `${major}.${minor}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
run();
|
run();
|
||||||
|
Loading…
Reference in New Issue
Block a user