Skip to content

Commit

Permalink
Add support for Azure Artifact authenticated feeds
Browse files Browse the repository at this point in the history
  • Loading branch information
AArnott committed Jul 22, 2019
1 parent 5e96a0b commit 5ee62bf
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ using Windows PowerShell or [PowerShell Core][pwsh] (on any OS).

This repository can be built on Windows, Linux, and OSX.

## Package restore

The easiest way to restore packages may be to run `init.ps1` which automatically authenticates
to the feeds that packages for this repo come from, if any.
`dotnet restore` or `nuget restore` also work but may require extra steps to authenticate to any applicable feeds.

## Building

Building, testing, and packing this repository can be done by using the standard dotnet CLI commands (e.g. `dotnet build`, `dotnet test`, `dotnet pack`, etc.).
Expand Down
9 changes: 5 additions & 4 deletions azure-pipelines/Get-NuGetTool.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ Param(
[string]$NuGetVersion='5.0.2'
)

$binaryToolsPath = "$PSScriptRoot\..\obj\tools\nuget.$NuGetVersion"
if (!(Test-Path $binaryToolsPath)) { $null = New-Item -Type Directory -Path $binaryToolsPath }
$nugetPath = "$binaryToolsPath\nuget.exe"
$toolsPath = & "$PSScriptRoot\Get-TempToolsPath.ps1"
$binaryToolsPath = Join-Path $toolsPath $NuGetVersion
if (!(Test-Path $binaryToolsPath)) { $null = mkdir $binaryToolsPath }
$nugetPath = Join-Path $binaryToolsPath nuget.exe

if (!(Test-Path $nugetPath)) {
Write-Host "Downloading nuget.exe $NuGetVersion..." -ForegroundColor Yellow
Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/v$NuGetVersion/NuGet.exe" -OutFile $nugetPath | Out-Null
}

Write-Output (Resolve-Path $nugetPath).Path
return (Resolve-Path $nugetPath).Path
13 changes: 13 additions & 0 deletions azure-pipelines/Get-TempToolsPath.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
if ($env:AGENT_TOOLSDIRECTORY) {
$path = "$env:AGENT_TOOLSDIRECTORY\vs-platform\tools"
} elseif ($env:localappdata) {
$path = "$env:localappdata\vs-platform\tools"
} else {
$path = "$PSScriptRoot\..\obj\tools"
}

if (!(Test-Path $path)) {
New-Item -ItemType Directory -Path $Path | Out-Null
}

(Resolve-Path $path).Path
39 changes: 39 additions & 0 deletions azure-pipelines/Set-EnvVars.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<#
.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
)

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

$cmdInstructions = !$env:TF_BUILD -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
}

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

# If we're running in Azure Pipelines, set these environment variables
if ($env:TF_BUILD) {
Write-Host "##vso[task.setvariable variable=$($_.Key);]$($_.Value)"
}

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

return !$cmdInstructions
2 changes: 2 additions & 0 deletions azure-pipelines/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ jobs:
- checkout: self
clean: true # "all" doesn't work, but "true" does, despite YAML docs
- template: install-dependencies.yml
parameters:
initArgs: -NoRestore
- template: publish-codecoverage.yml
- template: publish-deployables.yml
3 changes: 0 additions & 3 deletions azure-pipelines/dotnet.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
steps:
- script: dotnet restore /v:m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/restore.binlog"
displayName: dotnet restore
workingDirectory: src

- script: dotnet build --no-restore -c $(BuildConfiguration) /v:m /bl:"$(Build.ArtifactStagingDirectory)/build_logs/build.binlog"
displayName: dotnet build
Expand Down
5 changes: 4 additions & 1 deletion azure-pipelines/install-dependencies.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
parameters:
initArgs:

steps:

- powershell: |
.\init.ps1
.\init.ps1 -AccessToken '$(System.AccessToken)' ${{ parameters['initArgs'] }}
dotnet --info
displayName: Install prerequisites

Expand Down
39 changes: 37 additions & 2 deletions init.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,46 @@ Per-user allows sharing the installed dependencies across repositories and allow
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`.
.PARAMETER NoPrerequisites
Skips the installation of prerequisite software (e.g. SDKs, tools).
.PARAMETER NoRestore
Skips the package restore step.
.PARAMETER AccessToken
An optional access token for authenticating to Azure Artifacts authenticated feeds.
#>
[CmdletBinding(SupportsShouldProcess=$true)]
Param (
[ValidateSet('repo','user')]
[string]$InstallLocality='user'
[string]$InstallLocality='user',
[Parameter()]
[switch]$NoPrerequisites,
[Parameter()]
[switch]$NoRestore,
[Parameter()]
[string]$AccessToken
)

& "$PSScriptRoot\tools\Install-DotNetSdk.ps1" -InstallLocality $InstallLocality
if (!$NoPrerequisites) {
& "$PSScriptRoot\tools\Install-NuGetCredProvider.ps1" -AccessToken $AccessToken
& "$PSScriptRoot\tools\Install-DotNetSdk.ps1" -InstallLocality $InstallLocality
}

Push-Location $PSScriptRoot
try {
$HeaderColor = 'Green'

if (!$NoRestore) {
Write-Host "Restoring NuGet packages" -ForegroundColor $HeaderColor
dotnet restore src
if ($lastexitcode -ne 0) {
throw "Failure while restoring packages."
}
}
}
catch {
Write-Error $error[0]
exit $lastexitcode
}
finally {
Pop-Location
}
2 changes: 1 addition & 1 deletion nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
<packageSources>
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
<add key="nuget" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
</configuration>
62 changes: 62 additions & 0 deletions tools/Install-NuGetCredProvider.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<#
.SYNOPSIS
Downloads and installs the Microsoft Artifacts Credential Provider
from https://github.com/microsoft/artifacts-credprovider
to assist in authenticating to Azure Artifact feeds in interactive development
or unattended build agents.
.PARAMETER AccessToken
An optional access token for authenticating to Azure Artifacts authenticated feeds.
#>
[CmdletBinding()]
Param (
[Parameter()]
[string]$AccessToken
)

$toolsPath = & "$PSScriptRoot\..\azure-pipelines\Get-TempToolsPath.ps1"

if ($IsMacOS -or $IsLinux) {
$installerScript = "installcredprovider.sh"
$sourceUrl = "https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh"
} else {
$installerScript = "installcredprovider.ps1"
$sourceUrl = "https://raw.githubusercontent.com/microsoft/artifacts-credprovider/master/helpers/installcredprovider.ps1"
}

$installerScript = Join-Path $toolsPath $installerScript

if (!(Test-Path $installerScript)) {
Invoke-WebRequest $sourceUrl -OutFile $installerScript
}

$installerScript = (Resolve-Path $installerScript).Path

if ($IsMacOS -or $IsLinux) {
chmod u+x $installerScript
}

& $installerScript

if ($AccessToken) {
$endpoints = @()

$nugetConfig = [xml](Get-Content -Path "$PSScriptRoot\..\nuget.config")

$nugetConfig.configuration.packageSources.add |? { $_.value -match '^https://pkgs\.dev\.azure\.com/' } |% {
$endpoint = New-Object -TypeName PSObject
Add-Member -InputObject $endpoint -MemberType NoteProperty -Name endpoint -Value $_.value
Add-Member -InputObject $endpoint -MemberType NoteProperty -Name username -Value ado
Add-Member -InputObject $endpoint -MemberType NoteProperty -Name password -Value $AccessToken
$endpoints += $endpoint
}

$auth = New-Object -TypeName PSObject
Add-Member -InputObject $auth -MemberType NoteProperty -Name endpointCredentials -Value $endpoints

$authJson = ConvertTo-Json -InputObject $auth
$envVars = @{
'VSS_NUGET_EXTERNAL_FEED_ENDPOINTS'=$authJson;
}

& "$PSScriptRoot\..\azure-pipelines\Set-EnvVars.ps1" -Variables $envVars | Out-Null
}

0 comments on commit 5ee62bf

Please sign in to comment.