Skip to content

Commit 2bca386

Browse files
Create Publish-Admf.ps1
1 parent 261321f commit 2bca386

File tree

1 file changed

+235
-0
lines changed

1 file changed

+235
-0
lines changed

scripts/Publish-Admf.ps1

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
<#
2+
.SYNOPSIS
3+
A publishing script used to bullk-publish modules.
4+
5+
.DESCRIPTION
6+
A publishing script used to bullk-publish modules.
7+
This assumes a source control system such as Azure DevOps or any other viable tool with direct git access.
8+
It also expects an installed git client and makes no provisions for authentication.
9+
10+
All modules must be provided via the same "DevOpsPath" - meaning they must be in the same collection if on Azure DevOps.
11+
Each module requires its own repository (or ideally project).
12+
13+
While this script _assumes_ the use of Azure DevOps, it should be compatible with other services.
14+
15+
There are also no provisions for powershell repository authentication.
16+
Either come pre-authenticated, use windows authentication or use PSResourceGet and have authentication configured for the repository.
17+
18+
.PARAMETER Repository
19+
Name of the PowerShell repository to publish the finished modules to.
20+
21+
.PARAMETER DevOpsPath
22+
The full path used for "git clone".
23+
Insert a "{0}" placeholder for the name of the module.
24+
25+
.PARAMETER UseGetV3
26+
By default, this script will use "Find-Module" and "Publish-MModule"
27+
Use this switch to instead use "Find-PSResource" and "Publish-PSResource"
28+
29+
.PARAMETER Modules
30+
The modules to publish.
31+
Must be provided in the correct order of dependency.
32+
Will possibly fail if not all dependencies are specified, even if the target repository contains said dependencies.
33+
Defaults to include all modules needed for the ADMF project.
34+
35+
.EXAMPLE
36+
PS C:\> .\Publish-Admf.ps1 -Repository internal -DevOpsPath "<insertgoodexample>" -UseGetV3
37+
38+
Uses PSResourceGet to clone all ADMF repositories from the source control system, and publish as needed to the internal repository using PSResourceGet.
39+
#>
40+
[CmdletBinding()]
41+
param (
42+
[Parameter(Mandatory = $true)]
43+
[string]
44+
$Repository,
45+
46+
[Parameter(Mandatory = $true)]
47+
[string]
48+
$DevOpsPath,
49+
50+
[switch]
51+
$UseGetV3,
52+
53+
[string[]]
54+
$Modules = @(
55+
'string'
56+
'PSFramework'
57+
'ResolveString'
58+
'Principal'
59+
'ADSec'
60+
'ADMF.Core'
61+
'DCManagement'
62+
'DomainManagement'
63+
'ForestManagement'
64+
'ADMF'
65+
)
66+
)
67+
68+
$ErrorActionPreference = 'Stop'
69+
trap {
70+
Remove-Item -Path $tempRoot -Force -Recurse -ErrorAction SilentlyContinue
71+
Write-Warning "Script failed: $_"
72+
throw $_
73+
}
74+
75+
#region Functions
76+
function New-TempDirectory {
77+
[CmdletBinding()]
78+
param (
79+
80+
)
81+
82+
$directory = New-Item -Path $env:TEMP -Name "PSModule-$(Get-Random)" -ItemType Directory
83+
$directory.FullName
84+
}
85+
86+
function Build-Module {
87+
[CmdletBinding()]
88+
param (
89+
[string]
90+
$WorkingDirectory,
91+
92+
[string]
93+
$Repository,
94+
95+
[string]
96+
$Name,
97+
98+
[string]
99+
$DevOpsPath,
100+
101+
[switch]
102+
$UseGetV3
103+
)
104+
105+
Assert-ModulePath -Root $WorkingDirectory
106+
107+
Install-ModuleProject -Path $WorkingDirectory -DevOpsPath $DevOpsPath -Name $Name
108+
Publish-FakeModule -Path $WorkingDirectory -Name $Name
109+
if (-not (Test-ModuleUpdatePending -Path $WorkingDirectory -Name $Name -Repository $Repository -UseGetV3:$UseGetV3)) {
110+
Write-Host "Skipping Module $Name - no update needed."
111+
return
112+
}
113+
114+
Write-Host "Updating Module $Name"
115+
switch ($Name) {
116+
'string' {
117+
if ($UseGetV3) { Publish-PSResource -Path "$WorkingDirectory\$Name\$Name" -Repository $Repository }
118+
else { Publish-Module -Path "$WorkingDirectory\$Name\$Name" -Repository $Repository }
119+
}
120+
default {
121+
& "$WorkingDirectory\$Name\build\vsts-build.ps1" -Repository $Repository -ApiKey DevOps
122+
}
123+
}
124+
}
125+
126+
function Assert-ModulePath {
127+
[CmdletBinding()]
128+
param (
129+
[Parameter(Mandatory = $true)]
130+
[string]
131+
$Root
132+
)
133+
134+
$modulePath = Join-Path -Path $Root -ChildPath '_modules'
135+
if (Test-Path -Path $modulePath) { return }
136+
137+
$null = New-Item -Path $modulePath -ItemType Directory -Force
138+
$env:PSModulePath = $modulePath, $env:PSModulePath -join ';'
139+
}
140+
141+
function Install-ModuleProject {
142+
[CmdletBinding()]
143+
param (
144+
[Parameter(Mandatory = $true)]
145+
[string]
146+
$Path,
147+
148+
[Parameter(Mandatory = $true)]
149+
[string]
150+
$DevOpsPath,
151+
152+
[Parameter(Mandatory = $true)]
153+
[string]
154+
$Name
155+
)
156+
157+
Push-Location -Path $Path
158+
git clone "$($DevOpsPath -f $Name)"
159+
Pop-Location
160+
}
161+
162+
function Publish-FakeModule {
163+
<#
164+
.SYNOPSIS
165+
Copies the module code of the selected repository into the modules folders.
166+
167+
.DESCRIPTION
168+
Copies the module code of the selected repository into the modules folders.
169+
The folder being the "_modules" subfolder.
170+
171+
Publish-Module requires all dependencies to be present not only in the repository, but also on the machine doing the publishing.
172+
This command - together with "Assert-ModulePath" - will ensure a copy is in a local location PowerShell knows to look for.
173+
174+
.PARAMETER Path
175+
The root path where the module repositories to be published are cloned to.
176+
Also the parent folder under which this function expects a "_modules" folder.
177+
178+
.PARAMETER Name
179+
Name of the module to fake-pulish.
180+
#>
181+
[CmdletBinding()]
182+
param (
183+
[Parameter(Mandatory = $true)]
184+
[string]
185+
$Path,
186+
187+
[Parameter(Mandatory = $true)]
188+
[string]
189+
$Name
190+
)
191+
192+
Copy-Item -Path "$Path\$Name\$Name" -Destination "$Path\_modules" -Recurse -Force
193+
}
194+
195+
function Test-ModuleUpdatePending {
196+
[CmdletBinding()]
197+
param (
198+
[Parameter(Mandatory = $true)]
199+
[string]
200+
$Path,
201+
202+
[Parameter(Mandatory = $true)]
203+
[string]
204+
$Name,
205+
206+
[Parameter(Mandatory = $true)]
207+
[string]
208+
$Repository,
209+
210+
[switch]
211+
$UseGetV3
212+
)
213+
214+
# Would prefer to use "Import-PowerShellDataFile", but some manifests cannot be read that way
215+
$localVersion = (Get-Content -Path "$Path\$Name\$Name\$Name.psd1" | Where-Object { $_ -match 'ModuleVersion' }) -replace "^.+?['`"]" -replace "['`"]+$" -as [version]
216+
217+
if ($UseGetV3) { $remoteVersion = (Find-PSResource -Name $Name -Repository $Repository).Version -as [Version] }
218+
else { $remoteVersion = (Find-Module -Name $Name -Repository $Repository).Version -as [Version] }
219+
220+
if (-not $remoteVersion) { return $true }
221+
if ($remoteVersion -lt $localVersion) { return $true }
222+
$false
223+
}
224+
#endregion Functions
225+
226+
if ($UseGetV3) {
227+
Set-Alias -Scope Global -Name Publish-Module -Value Publish-PSResource
228+
}
229+
$tempRoot = New-TempDirectory
230+
231+
foreach ($moduleName in $Modules) {
232+
Build-Module -WorkingDirectory $tempRoot -Repository $Repository -Name $moduleName -DevOpsPath $DevOpsPath -UseGetV3:$UseGetV3
233+
}
234+
235+
Remove-Item -Path $tempRoot -Force -Recurse

0 commit comments

Comments
 (0)