Skip to content

Commit

Permalink
Pin the .NET Core SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Jan 30, 2020
1 parent 7cdddd2 commit f95e579
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 12 deletions.
23 changes: 17 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@
# see travis-ci.org for details

language: csharp
dist: xenial
dotnet: 2.1.802
mono: none
osx_image: xcode8.3

os:
- osx
- linux
matrix:
include:
- os: linux
dist: xenial
before_install:
- |
wget -q https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell
- os: osx
osx_image: xcode8.3
before_install:
- brew update # This is necessary to get pwsh 6.2 instead of some 6.0-preview that isn't named `pwsh`
- brew cask install powershell
fast_finish: true

before_install:
- date -u
Expand All @@ -18,6 +28,7 @@ before_install:

install:
- git fetch --unshallow
- pwsh ./tools/Install-DotNetSdk.ps1 ; export PATH=~/.dotnet:$PATH

# Build libgit2, LibGit2Sharp and run the tests
script:
Expand Down
15 changes: 11 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ We love Pull Requests! Your contributions help make LibGit2Sharp great.

## Getting Started

So you want to contribute to LibGit2Sharp. Great! Contributions take many forms from
So you want to contribute to LibGit2Sharp. Great! Contributions take many forms from
submitting issues, writing documentation, to making code changes. We welcome it all.

But first things first...
Expand All @@ -14,18 +14,25 @@ But first things first...
* Clearly describe the issue including steps to reproduce when it is a bug.
* Make sure you fill in the earliest version that you know has the issue.
* Fork the repository on GitHub, then clone it using your favorite Git client.
* Make sure the project builds and all tests pass on your machine by running
* Make sure the project builds and all tests pass on your machine by running
the `buildandtest.cmd` script on Windows or `buildandtest.sh` on Linux/Mac.

## LibGit2

LibGit2Sharp brings all the might and speed of libgit2, a native Git implementation, to the managed world of .Net and Mono.
LibGit2 is a git submodule referencing the [libgit2 project](https://github.com/libgit2/libgit2). To learn more about
LibGit2 is a git submodule referencing the [libgit2 project](https://github.com/libgit2/libgit2). To learn more about
submodules read [here](http://git-scm.com/book/en/v2/Git-Tools-Submodules).
To build libgit2 see [here](https://github.com/libgit2/libgit2sharp/wiki/How-to-build-x64-libgit2-and-LibGit2Sharp).

## Making Changes

Make sure you have the required .NET Core SDK and runtimes installed.
The easiest way to do this is run our `tools\Install-DotNetSdk.ps1` script.
Using the `-InstallLocality Machine` switch requires elevation but ensures
that Visual Studio will be able to load the solution even when launched from a shortcut.

Then proceed to:

* Create a topic branch off master (don't work directly on master).
* Implement your feature or fix your bug. Please following existing coding styles and do not introduce new ones.
* Make atomic, focused commits with good commit messages.
Expand All @@ -42,7 +49,7 @@ Some things that will increase the chance that your pull request is accepted.
* Following existing code conventions.
* Including unit tests that would otherwise fail without the patch, but pass after applying it.
* Updating the documentation and tests that are affected by the contribution.
* If code from elsewhere is used, proper credit and a link to the source should exist in the code comments.
* If code from elsewhere is used, proper credit and a link to the source should exist in the code comments.
Then licensing issues can be checked against LibGit2Sharp's very permissive MIT based open source license.
* Having a configured git client that converts line endings to LF. [See here.](https://help.github.com/articles/dealing-with-line-endings/).
# Additional Resources
Expand Down
4 changes: 3 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: '{build}'

os: Visual Studio 2017
os: Visual Studio 2019

branches:
only:
Expand Down Expand Up @@ -68,6 +68,8 @@ install:
cinst curl -y
}
./tools/Install-DotNetSdk.ps1
before_build:
- ps: |
msbuild "$Env:APPVEYOR_BUILD_FOLDER\LibGit2Sharp.sln" `
Expand Down
11 changes: 10 additions & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,25 @@ variables:
jobs:
- job: Windows
pool:
vmImage: 'VS2017-Win2016'
vmImage: 'windows-2019'
steps:
- pwsh: ./tools/Install-DotNetSdk.ps1
displayName: Installing .NET Core SDK and runtimes
- script: buildandtest.cmd
displayName: Build and test
- job: Linux
pool:
vmImage: 'Ubuntu 16.04'
steps:
- pwsh: ./tools/Install-DotNetSdk.ps1
displayName: Installing .NET Core SDK and runtimes
- script: ./buildandtest.sh
displayName: Build and test
- job: macOS
pool:
vmImage: 'macOS 10.13'
steps:
- pwsh: ./tools/Install-DotNetSdk.ps1
displayName: Installing .NET Core SDK and runtimes
- script: ./buildandtest.sh
displayName: Build and test
5 changes: 5 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"sdk": {
"version": "2.1.802"
}
}
2 changes: 2 additions & 0 deletions tools/DotNetSdkVersion.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
$globalJson = Get-Content -Path "$PSScriptRoot\..\global.json" | ConvertFrom-Json
$globalJson.sdk.version
160 changes: 160 additions & 0 deletions tools/Install-DotNetSdk.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<#
.SYNOPSIS
Installs the .NET SDK specified in the global.json file at the root of this repository,
along with supporting .NET Core runtimes used for testing.
.DESCRIPTION
This MAY not require elevation, as the SDK and runtimes are installed locally to this repo location,
unless `-InstallLocality machine` is specified.
.PARAMETER InstallLocality
A value indicating whether dependencies should be installed locally to the repo or at a per-user location.
Per-user allows sharing the installed dependencies across repositories and allows use of a shared expanded package cache.
Visual Studio will only notice and use these SDKs/runtimes if VS is launched from the environment that runs this script.
Per-repo allows for high isolation, allowing for a more precise recreation of the environment within an Azure Pipelines build.
When using 'repo', environment variables are set to cause the locally installed dotnet SDK to be used.
Per-repo can lead to file locking issues when dotnet.exe is left running as a build server and can be mitigated by running `dotnet build-server shutdown`.
Per-machine requires elevation and will download and install all SDKs and runtimes to machine-wide locations so all applications can find it.
#>
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact='Medium')]
Param (
[ValidateSet('repo','user','machine')]
[string]$InstallLocality='user'
)

$DotNetInstallScriptRoot = "$PSScriptRoot/../obj/tools"
if (!(Test-Path $DotNetInstallScriptRoot)) { New-Item -ItemType Directory -Path $DotNetInstallScriptRoot | Out-Null }
$DotNetInstallScriptRoot = Resolve-Path $DotNetInstallScriptRoot

# Look up actual required .NET Core SDK version from global.json
$sdkVersion = & "$PSScriptRoot/DotNetSdkVersion.ps1"

# Search for all .NET Core runtime versions referenced from MSBuild projects and arrange to install them.
$runtimeVersions = @()
Get-ChildItem "$PSScriptRoot\..\*.*proj" -Recurse |% {
$projXml = [xml](Get-Content -Path $_)
$targetFrameworks = $projXml.Project.PropertyGroup.TargetFramework
if (!$targetFrameworks) {
$targetFrameworks = $projXml.Project.PropertyGroup.TargetFrameworks
if ($targetFrameworks) {
$targetFrameworks = $targetFrameworks -Split ';'
}
}
$targetFrameworks |? { $_ -match 'netcoreapp(\d+\.\d+)' } |% {
$runtimeVersions += $Matches[1]
}
}

Function Get-FileFromWeb([Uri]$Uri, $OutDir) {
$OutFile = Join-Path $OutDir $Uri.Segments[-1]
if (!(Test-Path $OutFile)) {
Write-Verbose "Downloading $Uri..."
try {
(New-Object System.Net.WebClient).DownloadFile($Uri, $OutFile)
} finally {
# This try/finally causes the script to abort
}
}

$OutFile
}

Function Get-InstallerExe($Version, [switch]$Runtime) {
$sdkOrRuntime = 'Sdk'
if ($Runtime) { $sdkOrRuntime = 'Runtime' }

# Get the latest/actual version for the specified one
if (([Version]$Version).Build -eq -1) {
$versionInfo = -Split (Invoke-WebRequest -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sdkOrRuntime/$Version/latest.version" -UseBasicParsing)
$Version = $versionInfo[-1]
}

Get-FileFromWeb -Uri "https://dotnetcli.blob.core.windows.net/dotnet/$sdkOrRuntime/$Version/dotnet-$($sdkOrRuntime.ToLowerInvariant())-$Version-win-x64.exe" -OutDir "$DotNetInstallScriptRoot"
}

Function Install-DotNet($Version, [switch]$Runtime) {
if ($Runtime) { $sdkSubstring = '' } else { $sdkSubstring = 'SDK ' }
Write-Host "Downloading .NET Core $sdkSubstring$Version..."
$Installer = Get-InstallerExe -Version $Version -Runtime:$Runtime
Write-Host "Installing .NET Core $sdkSubstring$Version..."
cmd /c start /wait $Installer /install /quiet
if ($LASTEXITCODE -ne 0) {
throw "Failure to install .NET Core SDK"
}
}

if ($InstallLocality -eq 'machine') {
if ($IsMacOS -or $IsLinux) {
Write-Error "Installing the .NET Core SDK or runtime at a machine-wide location is only supported by this script on Windows."
exit 1
}

if ($PSCmdlet.ShouldProcess(".NET Core SDK $sdkVersion", "Install")) {
Install-DotNet -Version $sdkVersion
}

$runtimeVersions |% {
if ($PSCmdlet.ShouldProcess(".NET Core runtime $_", "Install")) {
Install-DotNet -Version $_ -Runtime
}
}

return
}

$switches = @(
'-Architecture','x64'
)
$envVars = @{
# For locally installed dotnet, skip first time experience which takes a long time
'DOTNET_SKIP_FIRST_TIME_EXPERIENCE' = 'true';
}

if ($InstallLocality -eq 'repo') {
$DotNetInstallDir = "$DotNetInstallScriptRoot/.dotnet"
} elseif ($env:AGENT_TOOLSDIRECTORY) {
$DotNetInstallDir = "$env:AGENT_TOOLSDIRECTORY/dotnet"
} else {
$DotNetInstallDir = Join-Path $HOME .dotnet
}

Write-Host "Installing .NET Core SDK and runtimes to $DotNetInstallDir" -ForegroundColor Blue

if ($DotNetInstallDir) {
$switches += '-InstallDir',$DotNetInstallDir
$envVars['DOTNET_MULTILEVEL_LOOKUP'] = '0'
$envVars['DOTNET_ROOT'] = $DotNetInstallDir
}

if ($IsMacOS -or $IsLinux) {
$DownloadUri = "https://dot.net/v1/dotnet-install.sh"
$DotNetInstallScriptPath = "$DotNetInstallScriptRoot/dotnet-install.sh"
} else {
$DownloadUri = "https://dot.net/v1/dotnet-install.ps1"
$DotNetInstallScriptPath = "$DotNetInstallScriptRoot/dotnet-install.ps1"
}

if (-not (Test-Path $DotNetInstallScriptPath)) {
Invoke-WebRequest -Uri $DownloadUri -OutFile $DotNetInstallScriptPath -UseBasicParsing
if ($IsMacOS -or $IsLinux) {
chmod +x $DotNetInstallScriptPath
}
}

if ($PSCmdlet.ShouldProcess(".NET Core SDK $sdkVersion", "Install")) {
Invoke-Expression -Command "$DotNetInstallScriptPath -Version $sdkVersion $switches"
} else {
Invoke-Expression -Command "$DotNetInstallScriptPath -Version $sdkVersion $switches -DryRun"
}

$switches += '-Runtime','dotnet'

$runtimeVersions | Get-Unique |% {
if ($PSCmdlet.ShouldProcess(".NET Core runtime $_", "Install")) {
Invoke-Expression -Command "$DotNetInstallScriptPath -Channel $_ $switches"
} else {
Invoke-Expression -Command "$DotNetInstallScriptPath -Channel $_ $switches -DryRun"
}
}

if ($PSCmdlet.ShouldProcess("Set DOTNET environment variables to discover these installed runtimes?")) {
& "$PSScriptRoot/Set-EnvVars.ps1" -Variables $envVars -PrependPath $DotNetInstallDir | Out-Null
}
79 changes: 79 additions & 0 deletions tools/Set-EnvVars.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<#
.SYNOPSIS
Set environment variables in the environment.
Azure Pipeline and CMD environments are considered.
.PARAMETER Variables
A hashtable of variables to be set.
.OUTPUTS
A boolean indicating whether the environment variables can be expected to propagate to the caller's environment.
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param(
[Parameter(Mandatory=$true, Position=1)]
$Variables,
[string[]]$PrependPath
)

if ($Variables.Count -eq 0) {
return $true
}

$cmdInstructions = !$env:TF_BUILD -and !$env:GITHUB_ACTIONS -and $env:PS1UnderCmd -eq '1'
if ($cmdInstructions) {
Write-Warning "Environment variables have been set that will be lost because you're running under cmd.exe"
Write-Host "Environment variables that must be set manually:" -ForegroundColor Blue
} else {
Write-Host "Environment variables set:" -ForegroundColor Blue
$envVars
if ($PrependPath) {
Write-Host "Paths prepended to PATH: $PrependPath"
}
}

if ($env:TF_BUILD) {
Write-Host "Azure Pipelines detected. Logging commands will be used to propagate environment variables and prepend path."
}

if ($env:GITHUB_ACTIONS) {
Write-Host "GitHub Actions detected. Logging commands will be used to propagate environment variables and prepend path."
}

$Variables.GetEnumerator() |% {
Set-Item -Path env:$($_.Key) -Value $_.Value

# If we're running in a cloud CI, set these environment variables so they propagate.
if ($env:TF_BUILD) {
Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)"
}
if ($env:GITHUB_ACTIONS) {
Write-Host "::set-env name=$($_.Key)::$($_.Value)"
}

if ($cmdInstructions) {
Write-Host "SET $($_.Key)=$($_.Value)"
}
}

$pathDelimiter = ';'
if ($IsMacOS -or $IsLinux) {
$pathDelimiter = ':'
}

if ($PrependPath) {
$PrependPath |% {
$newPathValue = "$_$pathDelimiter$env:PATH"
Set-Item -Path env:PATH -Value $newPathValue
if ($cmdInstructions) {
Write-Host "SET PATH=$newPathValue"
}

if ($env:TF_BUILD) {
Write-Host "##vso[task.prependpath]$_"
}
if ($env:GITHUB_ACTIONS) {
Write-Host "::add-path::$_"
}
}
}

return !$cmdInstructions

0 comments on commit f95e579

Please sign in to comment.