Skip to content

Commit 6e62193

Browse files
Enable Caching of PS Modules (#21425)
- Remove copied AzPowershell utilities - Add latest AZ module path already on hosted agents to PSModulePath - Rename setup-az-modules template setup-environments to reflect what is is doing - Add support for Caching the current user PS Module folder - Add support for install-module if not already present in module folder - Organize the live test clean-up script to be in the standard location Co-authored-by: Wes Haggard <[email protected]>
1 parent 66bd872 commit 6e62193

File tree

8 files changed

+122
-169
lines changed

8 files changed

+122
-169
lines changed

eng/common/TestResources/AzurePowerShellV4/Utility.ps1

Lines changed: 0 additions & 153 deletions
This file was deleted.

eng/common/TestResources/Import-AzModules.ps1

Lines changed: 0 additions & 11 deletions
This file was deleted.

eng/common/TestResources/deploy-test-resources.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,12 @@ parameters:
3333

3434

3535
steps:
36-
- template: /eng/common/TestResources/setup-az-modules.yml
36+
- template: /eng/common/pipelines/templates/steps/cache-ps-modules.yml
37+
38+
- template: /eng/common/TestResources/setup-environments.yml
3739

3840
- pwsh: |
39-
eng/common/TestResources/Import-AzModules.ps1
41+
eng/common/scripts/Import-AzModules.ps1
4042
4143
$subscriptionConfiguration = @'
4244
${{ parameters.SubscriptionConfiguration }}

eng/common/TestResources/remove-test-resources.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ parameters:
2121

2222
steps:
2323
- pwsh: |
24-
eng/common/TestResources/Import-AzModules.ps1
24+
eng/common/scripts/Import-AzModules.ps1
2525
2626
$subscriptionConfiguration = @"
2727
${{ parameters.SubscriptionConfiguration }}

eng/common/TestResources/setup-az-modules.yml renamed to eng/common/TestResources/setup-environments.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ steps:
2121
condition: contains(variables['OSVmImage'], 'mac')
2222

2323
- task: Powershell@2
24+
displayName: Register Dogfood environment
2425
inputs:
25-
displayName: Register Dogfood environment
2626
targetType: inline
2727
pwsh: true
2828
script: |
29-
eng/common/TestResources/Import-AzModules.ps1
29+
eng/common/scripts/Import-AzModules.ps1
3030
3131
$environmentSpec = @"
3232
$(env-config-dogfood)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
steps:
2+
- pwsh: |
3+
. ./eng/common/scripts/Helpers/PSModule-Helpers.ps1
4+
Write-Host "##vso[task.setvariable variable=CachedPSModulePath]$global:CurrentUserModulePath"
5+
displayName: Set PS Modules Cache Directory
6+
- task: Cache@2
7+
inputs:
8+
key: 'PSModulePath | $(CacheSalt) | $(Agent.OS) | $(Build.SourcesDirectory)/eng/common/scripts/Import-AzModules.ps1'
9+
path: $(CachedPSModulePath)
10+
displayName: Cache PS Modules
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
$DefaultPSRepositoryUrl = "https://www.powershellgallery.com/api/v2"
2+
$global:CurrentUserModulePath = ""
3+
4+
function Update-PSModulePath()
5+
{
6+
# Information on PSModulePath taken from docs
7+
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath
8+
9+
# Information on Az custom module paths on hosted agents taken from
10+
# https://github.com/microsoft/azure-pipelines-tasks/blob/c9771bc064cd60f47587c68e5c871b7cd13f0f28/Tasks/AzurePowerShellV5/Utility.ps1
11+
12+
if ($IsWindows) {
13+
$hostedAgentModulePath = $env:SystemDrive + "\Modules"
14+
$moduleSeperator = ";"
15+
} else {
16+
$hostedAgentModulePath = "/usr/share"
17+
$moduleSeperator = ":"
18+
}
19+
$modulePaths = $env:PSModulePath -split $moduleSeperator
20+
21+
# Remove any hosted agent paths (needed to remove old default azure/azurerm paths which cause conflicts)
22+
$modulePaths = $modulePaths.Where({ !$_.StartsWith($hostedAgentModulePath) })
23+
24+
# Add any "az_" paths from the agent which is the lastest set of azure modules
25+
$AzModuleCachPath = (Get-ChildItem "$hostedAgentModulePath/az_*" -Attributes Directory) -join $moduleSeperator
26+
if ($AzModuleCachPath -and $env.PSModulePath -notcontains $AzModuleCachPath) {
27+
$modulePaths += $AzModuleCachPath
28+
}
29+
30+
$env:PSModulePath = $modulePaths -join $moduleSeperator
31+
32+
# Find the path that is under user home directory
33+
$homeDirectories = $modulePaths.Where({ $_.StartsWith($home) })
34+
if ($homeDirectories.Count -gt 0) {
35+
$global:CurrentUserModulePath = $homeDirectories[0]
36+
if ($homeDirectories.Count -gt 1) {
37+
Write-Verbose "Found more then one module path starting with $home so selecting the first one $global:CurrentUserModulePath"
38+
}
39+
40+
# In some cases the directory might not exist so we need to create it otherwise caching an empty directory will fail
41+
if (!(Test-Path $global:CurrentUserModulePath)) {
42+
New-Item $global:CurrentUserModulePath -ItemType Directory > $null
43+
}
44+
}
45+
else {
46+
Write-Error "Did not find a module path starting with $home to set up a user module path in $env:PSModulePath"
47+
}
48+
}
49+
50+
# If we want to use another default repository other then PSGallery we can update the default parameters
51+
function Install-ModuleIfNotInstalled($moduleName, $version, $repositoryUrl = $DefaultPSRepositoryUrl)
52+
{
53+
# Check installed modules
54+
$modules = (Get-Module -ListAvailable $moduleName)
55+
if ($version -as [Version]) {
56+
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
57+
}
58+
59+
if ($modules.Count -eq 0)
60+
{
61+
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
62+
if ($repositories.Count -eq 0)
63+
{
64+
Register-PSRepository -Name $repositoryUrl -SourceLocation $repositoryUrl -InstallationPolicy Trusted
65+
$repositories = (Get-PSRepository).Where({ $_.SourceLocation -eq $repositoryUrl })
66+
if ($repositories.Count -eq 0) {
67+
Write-Error "Failed to registory package repository $repositoryUrl."
68+
return
69+
}
70+
}
71+
$repository = $repositories[0]
72+
73+
if ($repository.InstallationPolicy -ne "Trusted") {
74+
Set-PSRepository -Name $repository.Name -InstallationPolicy "Trusted"
75+
}
76+
77+
Write-Host "Installing module $moduleName with min version $version from $repositoryUrl"
78+
# Install under CurrentUser scope so that the end up under $CurrentUserModulePath for caching
79+
Install-Module $moduleName -MinimumVersion $version -Repository $repository.Name -Scope CurrentUser -Force
80+
81+
# Ensure module installed
82+
$modules = (Get-Module -ListAvailable $moduleName)
83+
if ($version -as [Version]) {
84+
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
85+
}
86+
87+
if ($modules.Count -eq 0) {
88+
Write-Error "Failed to install module $moduleName with version $version"
89+
return
90+
}
91+
}
92+
93+
Write-Host "Using module $($modules[0].Name) with version $($modules[0].Version)."
94+
return $modules[0]
95+
}
96+
97+
Update-PSModulePath
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[CmdletBinding()]
2+
param (
3+
[string]$AzModuleVersion = "5.7.0" # Current version cached on agents
4+
)
5+
6+
. (Join-Path $PSScriptRoot Helpers PSModule-Helpers.ps1)
7+
8+
Install-ModuleIfNotInstalled "Az" $AzModuleVersion | Import-Module

0 commit comments

Comments
 (0)