Skip to content

Commit 0ade8f4

Browse files
authored
Support passing versions via build.psd1
Merge pull request #129 from PoshCode/joel/build.psd1
2 parents fe0d086 + c607a97 commit 0ade8f4

File tree

13 files changed

+209
-44
lines changed

13 files changed

+209
-44
lines changed

Source/Private/InitializeBuild.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,28 @@ function InitializeBuild {
3333
) -join ' ')"
3434
$BuildInfo = GetBuildInfo -BuildManifest $BuildManifest -BuildCommandInvocation $BuildCommandInvocation
3535

36+
# Normalize the version (if it was passed in via build.psd1)
37+
if ($BuildInfo.SemVer) {
38+
Write-Verbose "Update the Version, Prerelease, and BuildMetadata from the SemVer (in case it was passed in via build.psd1)"
39+
$BuildInfo = $BuildInfo | Update-Object @{
40+
Version = if (($V = $BuildInfo.SemVer.Split("+")[0].Split("-", 2)[0])) {
41+
[version]$V
42+
}
43+
Prerelease = $BuildInfo.SemVer.Split("+")[0].Split("-", 2)[1]
44+
BuildMetadata = $BuildInfo.SemVer.Split("+", 2)[1]
45+
}
46+
} elseif($BuildInfo.Version) {
47+
Write-Verbose "Calculate the Semantic Version from the Version - Prerelease + BuildMetadata"
48+
$SemVer = "$($BuildInfo.Version)"
49+
if ($BuildInfo.Prerelease) {
50+
$SemVer = "$SemVer-$($BuildInfo.Prerelease)"
51+
}
52+
if ($BuildInfo.BuildMetadata) {
53+
$SemVer = "$SemVer+$($BuildInfo.BuildMetadata)"
54+
}
55+
$BuildInfo = $BuildInfo | Update-Object @{ SemVer = $SemVer }
56+
}
57+
3658
# Override VersionedOutputDirectory with UnversionedOutputDirectory
3759
if ($BuildInfo.UnversionedOutputDirectory -and $BuildInfo.VersionedOutputDirectory) {
3860
$BuildInfo.VersionedOutputDirectory = $false

Source/Public/Build-Module.ps1

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ function Build-Module {
3232
Build-Module -SemVer $gitVersion
3333
3434
This example shows how to use a semantic version from gitversion to version your build.
35-
Note, this is how we version ModuleBuilder, so if you want to see it in action, check out our azure-pipelines.yml
36-
https://github.com/PoshCode/ModuleBuilder/blob/master/azure-pipelines.yml
3735
#>
3836
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "", Justification="Build is approved now")]
3937
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseCmdletCorrectly", "")]
@@ -150,42 +148,30 @@ function Build-Module {
150148
}
151149
process {
152150
try {
153-
# BEFORE we InitializeBuild we need to "fix" the version
154-
if($PSCmdlet.ParameterSetName -ne "SemanticVersion") {
155-
Write-Verbose "Calculate the Semantic Version from the $Version - $Prerelease + $BuildMetadata"
156-
$SemVer = "$Version"
157-
if($Prerelease) {
158-
$SemVer = "$Version-$Prerelease"
159-
}
160-
if($BuildMetadata) {
161-
$SemVer = "$SemVer+$BuildMetadata"
162-
}
163-
}
164-
165151
# Push into the module source (it may be a subfolder)
166152
$ModuleInfo = InitializeBuild $SourcePath
167153
Write-Progress "Building $($ModuleInfo.Name)" -Status "Use -Verbose for more information"
168154
Write-Verbose "Building $($ModuleInfo.Name)"
169155

170156
# Ensure the OutputDirectory (exists for build, or is cleaned otherwise)
171157
$OutputDirectory = $ModuleInfo | ResolveOutputFolder
172-
if ($Target -notmatch "Build") {
158+
if ($ModuleInfo.Target -notmatch "Build") {
173159
return
174160
}
175161
$RootModule = Join-Path $OutputDirectory "$($ModuleInfo.Name).psm1"
176162
$OutputManifest = Join-Path $OutputDirectory "$($ModuleInfo.Name).psd1"
177163
Write-Verbose "Output to: $OutputDirectory"
178164

179165
# Skip the build if it's up to date already
180-
Write-Verbose "Target $Target"
166+
Write-Verbose "Target $($ModuleInfo.Target)"
181167
$NewestBuild = (Get-Item $RootModule -ErrorAction SilentlyContinue).LastWriteTime
182168
$IsNew = Get-ChildItem $ModuleInfo.ModuleBase -Recurse |
183169
Where-Object LastWriteTime -gt $NewestBuild |
184170
Select-Object -First 1 -ExpandProperty LastWriteTime
185171

186172
if ($null -eq $IsNew) {
187173
# This is mostly for testing ...
188-
if ($Passthru) {
174+
if ($ModuleInfo.Passthru) {
189175
Get-Module $OutputManifest -ListAvailable
190176
}
191177
return # Skip the build
@@ -240,31 +226,31 @@ function Build-Module {
240226
}
241227

242228
try {
243-
if ($Version) {
244-
Write-Verbose "Update Manifest at $OutputManifest with version: $Version"
245-
Update-Metadata -Path $OutputManifest -PropertyName ModuleVersion -Value $Version
229+
if ($ModuleInfo.Version) {
230+
Write-Verbose "Update Manifest at $OutputManifest with version: $($ModuleInfo.Version)"
231+
Update-Metadata -Path $OutputManifest -PropertyName ModuleVersion -Value $ModuleInfo.Version
246232
}
247233
} catch {
248-
Write-Warning "Failed to update version to $Version. $_"
234+
Write-Warning "Failed to update version to $($ModuleInfo.Version). $_"
249235
}
250236

251237
if ($null -ne (Get-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -ErrorAction SilentlyContinue)) {
252-
if ($Prerelease) {
253-
Write-Verbose "Update Manifest at $OutputManifest with Prerelease: $Prerelease"
254-
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value $Prerelease
238+
if ($ModuleInfo.Prerelease) {
239+
Write-Verbose "Update Manifest at $OutputManifest with Prerelease: $($ModuleInfo.Prerelease)"
240+
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value $ModuleInfo.Prerelease
255241
} elseif ($PSCmdlet.ParameterSetName -eq "SemanticVersion" -or $PSBoundParameters.ContainsKey("Prerelease")) {
256242
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.Prerelease -Value ""
257243
}
258-
} elseif($Prerelease) {
244+
} elseif ($ModuleInfo.Prerelease) {
259245
Write-Warning ("Cannot set Prerelease in module manifest. Add an empty Prerelease to your module manifest, like:`n" +
260246
' PrivateData = @{ PSData = @{ Prerelease = "" } }')
261247
}
262248

263-
if ($BuildMetadata) {
264-
Write-Verbose "Update Manifest at $OutputManifest with metadata: $BuildMetadata from $SemVer"
249+
if ($ModuleInfo.BuildMetadata) {
250+
Write-Verbose "Update Manifest at $OutputManifest with metadata: $($ModuleInfo.BuildMetadata) from $($ModuleInfo.SemVer)"
265251
$RelNote = Get-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.ReleaseNotes -ErrorAction SilentlyContinue
266252
if ($null -ne $RelNote) {
267-
$Line = "$($ModuleInfo.Name) v$($SemVer)"
253+
$Line = "$($ModuleInfo.Name) v$($($ModuleInfo.SemVer))"
268254
if ([string]::IsNullOrWhiteSpace($RelNote)) {
269255
Write-Verbose "New ReleaseNotes:`n$Line"
270256
Update-Metadata -Path $OutputManifest -PropertyName PrivateData.PSData.ReleaseNotes -Value $Line
@@ -284,7 +270,7 @@ function Build-Module {
284270
}
285271

286272
# This is mostly for testing ...
287-
if ($Passthru) {
273+
if ($ModuleInfo.Passthru) {
288274
Get-Module $OutputManifest -ListAvailable
289275
}
290276
} finally {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#requires -Module ModuleBuilder
2+
. $PSScriptRoot\..\Convert-FolderSeparator.ps1
3+
4+
Describe "Parameters.Set in build manifest" -Tag Integration {
5+
BeforeAll {
6+
New-Item $PSScriptRoot\Result3\Parameters\ReadMe.md -ItemType File -Force
7+
$Output = Build-Module $PSScriptRoot\Parameters\build.psd1
8+
if ($Output) {
9+
$Module = [IO.Path]::ChangeExtension($Output.Path, "psm1")
10+
$Metadata = Import-Metadata $Output.Path
11+
}
12+
}
13+
14+
It "Passthru works" {
15+
$Output | Should -Not -BeNullOrEmpty
16+
}
17+
18+
It "The Target is Build" {
19+
"$PSScriptRoot\Result3\Parameters\ReadMe.md" | Should -Exist
20+
}
21+
22+
It "The version is set" {
23+
$Metadata.ModuleVersion | Should -Be "3.0.0"
24+
}
25+
26+
It "The PreRelease is set" {
27+
$Metadata.PrivateData.PSData.Prerelease | Should -Be 'alpha001'
28+
}
29+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
@{
2+
# The module version should be SemVer.org compatible
3+
ModuleVersion = "1.0.0"
4+
5+
# PrivateData is where all third-party metadata goes
6+
PrivateData = @{
7+
# PrivateData.PSData is the PowerShell Gallery data
8+
PSData = @{
9+
# Prerelease string should be here, so we can set it
10+
Prerelease = ''
11+
12+
# Release Notes have to be here, so we can update them
13+
ReleaseNotes = '
14+
A test module
15+
'
16+
17+
# Tags applied to this module. These help with module discovery in online galleries.
18+
Tags = 'Authoring','Build','Development','BestPractices'
19+
20+
# A URL to the license for this module.
21+
LicenseUri = 'https://github.com/PoshCode/ModuleBuilder/blob/master/LICENSE'
22+
23+
# A URL to the main website for this project.
24+
ProjectUri = 'https://github.com/PoshCode/ModuleBuilder'
25+
26+
# A URL to an icon representing this module.
27+
IconUri = 'https://github.com/PoshCode/ModuleBuilder/blob/resources/ModuleBuilder.png?raw=true'
28+
} # End of PSData
29+
} # End of PrivateData
30+
31+
# The main script module that is automatically loaded as part of this module
32+
RootModule = 'Parameters.psm1'
33+
34+
# Modules that must be imported into the global environment prior to importing this module
35+
RequiredModules = @()
36+
37+
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
38+
DefaultCommandPrefix = 'Param'
39+
40+
# Always define FunctionsToExport as an empty @() which will be replaced on build
41+
FunctionsToExport = @()
42+
AliasesToExport = @()
43+
44+
# ID used to uniquely identify this module
45+
GUID = 'a264e183-e0f7-4219-bc80-c30d14e0e98e'
46+
Description = 'A module for authoring and building PowerShell modules'
47+
48+
# Common stuff for all our modules:
49+
CompanyName = 'PoshCode'
50+
Author = 'Joel Bennett'
51+
Copyright = "Copyright 2024 Joel Bennett"
52+
53+
# Minimum version of the Windows PowerShell engine required by this module
54+
PowerShellVersion = '5.1'
55+
CompatiblePSEditions = @('Core','Desktop')
56+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using module ModuleBuilder
2+
3+
function GetFinale {
4+
[CmdletBinding()]
5+
# [Alias("gf")]
6+
param()
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
New-Alias -Name 'Get-MyAlias' -Value 'Get-ChildItem'
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using module ModuleBuilder
2+
3+
function GetPreview {
4+
[CmdletBinding()]
5+
# [Alias("gp")]
6+
param()
7+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function TestUnExportedAliases {
2+
[CmdletBinding()]
3+
param()
4+
5+
New-Alias -Name 'New-NotExportedAlias1' -Value 'Write-Verbose'
6+
Set-Alias -Name 'New-NotExportedAlias2' -Value 'Write-Verbose'
7+
}
8+
9+
New-Alias -Name 'New-NotExportedAlias3' -Value 'Write-Verbose' -Scope Global
10+
Set-Alias -Name 'New-NotExportedAlias4' -Value 'Write-Verbose' -Scope Global
11+
12+
New-Alias -Name 'New-NotExportedAlias5' -Value 'Write-Verbose'
13+
Remove-Alias -Name 'New-NotExportedAlias5'
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using module ModuleBuilder
2+
3+
function Get-Source {
4+
[CmdletBinding()]
5+
[Alias("gs","gsou")]
6+
param()
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function Set-Source {
2+
[CmdletBinding()]
3+
[Alias("ss", "ssou")]
4+
param()
5+
"sto͞o′pĭd"
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@{
2+
Path = "Parameters.psd1"
3+
OutputDirectory = "..\Result3"
4+
SemVer = "3.0.0-alpha001"
5+
Target = "Build"
6+
Passthru = $true
7+
}

Tests/Integration/Result3/Parameters/ReadMe.md

Whitespace-only changes.

Tests/Public/Build-Module.Tests.ps1

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,21 +257,28 @@ Describe "Build-Module" {
257257
New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force
258258
New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule/$ExpectedVersion" -Force
259259

260-
Mock InitializeBuild {
261-
# These are actually all the values that we need
260+
Mock ResolveBuildManifest { "TestDrive:/MyModule/build.psd1" }
261+
262+
Mock GetBuildInfo {
262263
[PSCustomObject]@{
263264
OutputDirectory = "TestDrive:/Output"
264-
Name = "MyModule"
265-
Version = $Version
265+
SourcePath = "TestDrive:/MyModule/"
266+
SemVer = $SemVer
266267
Target = $Target
267-
ModuleBase = "TestDrive:/MyModule/"
268268
CopyPaths = @()
269269
Encoding = "UTF8"
270270
PublicFilter = "Public/*.ps1"
271271
VersionedOutputDirectory = $true
272272
}
273273
}
274274

275+
Mock ImportModuleManifest {
276+
[PSCustomObject]@{
277+
Name = "MyModule"
278+
ModuleBase = "TestDrive:/MyModule/"
279+
}
280+
}
281+
275282
$global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/Output/MyModule/$ExpectedVersion"
276283

277284
Mock Get-ChildItem {
@@ -356,22 +363,31 @@ Describe "Build-Module" {
356363
$global:ExpectedVersion = "1.0.0"
357364
Push-Location TestDrive:/ -StackName BuildModuleTest
358365
New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force
359-
New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule/$ExpectedVersion" -Force
366+
New-Item -ItemType Directory -Path "TestDrive:/Output/MyModule" -Force
360367

361-
Mock InitializeBuild {
362-
# These are actually all the values that we need
368+
Mock ResolveBuildManifest { "TestDrive:/MyModule/build.psd1" }
369+
370+
Mock GetBuildInfo {
363371
[PSCustomObject]@{
364372
OutputDirectory = "TestDrive:/Output"
365-
Name = "MyModule"
366-
Version = $Version
367-
Target = $Target
368-
ModuleBase = "TestDrive:/MyModule/"
369-
CopyPaths = @()
373+
SourcePath = "TestDrive:/MyModule/"
374+
Version = "1.0.0"
375+
Prerelease = "beta03"
376+
BuildMetadata = "Sha.22c35ffff166f34addc49a3b80e622b543199cc5.Date.2018-10-11"
377+
Target = "CleanBuild"
378+
CopyPaths = @()
370379
Encoding = "UTF8"
371380
PublicFilter = "Public/*.ps1"
372381
}
373382
}
374383

384+
Mock ImportModuleManifest {
385+
[PSCustomObject]@{
386+
Name = "MyModule"
387+
ModuleBase = "TestDrive:/MyModule/"
388+
}
389+
}
390+
375391
$global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/Output/MyModule"
376392
Mock Get-ChildItem {
377393
[IO.FileInfo]"$TestDrive/MyModule/Public/Get-MyInfo.ps1"
@@ -510,20 +526,28 @@ Describe "Build-Module" {
510526
New-Item -ItemType Directory -Path TestDrive:/MyModule/ -Force
511527
New-Item -ItemType Directory -Path "TestDrive:/$ExpectedVersion/" -Force
512528

513-
Mock InitializeBuild {
529+
Mock GetBuildInfo {
514530
# These are actually all the values that we need
515531
[PSCustomObject]@{
516532
OutputDirectory = "TestDrive:/$Version"
517533
Name = "MyModule"
518534
Version = $Version
535+
PreRelease = $PreRelease
519536
Target = $Target
520-
ModuleBase = "TestDrive:/MyModule/"
537+
SourcePath = "TestDrive:/MyModule/"
521538
CopyPaths = @()
522539
Encoding = "UTF8"
523540
PublicFilter = "Public/*.ps1"
524541
}
525542
}
526543

544+
Mock ImportModuleManifest {
545+
[PSCustomObject]@{
546+
Name = "MyModule"
547+
ModuleBase = "TestDrive:/MyModule/"
548+
}
549+
}
550+
527551
$global:Mock_OutputPath = Convert-FolderSeparator "TestDrive:/MyModule/$ExpectedVersion"
528552

529553
Mock Get-ChildItem {

0 commit comments

Comments
 (0)