10000 Refactor new-msipackage into packaging.psm1 (#6208) · PowerShell/PowerShell@9a46b3f · GitHub
[go: up one dir, main page]

Skip to content

Commit 9a46b3f

Browse files
authored
Refactor new-msipackage into packaging.psm1 (#6208)
Refactor new-msipackage and related function into packaging.psm1
1 parent bdd6008 commit 9a46b3f

File tree

2 files changed

+187
-187
lines changed

2 files changed

+187
-187
lines changed

build.psm1

Lines changed: 0 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,193 +2039,6 @@ function script:Start-NativeExecution([scriptblock]$sb, [switch]$IgnoreExitcode)
20392039
}
20402040
}
20412041

2042-
# Builds coming out of this project can have version number as 'a.b.c' OR 'a.b.c-d-f'
2043-
# This function converts the above version into major.minor[.build[.revision]] format
2044-
function Get-PackageVersionAsMajorMinorBuildRevision
2045-
{
2046-
[CmdletBinding()]
2047-
param (
20 10000 48-
# Version of the Package
2049-
[Parameter(Mandatory = $true)]
2050-
[ValidateNotNullOrEmpty()]
2051-
[string] $Version
2052-
)
2053-
2054-
Write-Verbose "Extract the version in the form of major.minor[.build[.revision]] for $Version"
2055-
$packageVersionTokens = $Version.Split('-')
2056-
$packageVersion = ([regex]::matches($Version, "\d+(\.\d+)+"))[0].value
2057-
2058-
if (1 -eq $packageVersionTokens.Count) {
2059-
# In case the input is of the form a.b.c, add a '0' at the end for revision field
2060-
$packageVersion = $packageVersion + '.0'
2061-
} elseif (1 -lt $packageVersionTokens.Count) {
2062-
# We have all the four fields
2063-
$packageBuildTokens = ([regex]::Matches($packageVersionTokens[1], "\d+"))[0].value
2064-
2065-
if ($packageBuildTokens)
2066-
{
2067-
$packageVersion = $packageVersion + '.' + $packageBuildTokens
2068-
}
2069-
else
2070-
{
2071-
$packageVersion = $packageVersion
2072-
}
2073-
}
2074-
2075-
$packageVersion
2076-
}
2077-
2078-
<#
2079-
.Synopsis
2080-
Creates a Windows installer MSI package and assumes that the binaries are already built using 'Start-PSBuild'.
2081-
This only works on a Windows machine due to the usage of WiX.
2082-
.EXAMPLE
2083-
# This example shows how to produce a Debug-x64 installer for development purposes.
2084-
cd $RootPathOfPowerShellRepo
2085-
Import-Module .\build.psm1; Import-Module .\tools\packaging\packaging.psm1
2086-
New-MSIPackage -Verbose -ProductCode (New-Guid) -ProductSourcePath '.\src\powershell-win-core\bin\Debug\netcoreapp2.0\win7-x64\publish' -ProductTargetArchitecture x64 -ProductVersion '1.2.3'
2087-
#>
2088-
function New-MSIPackage
2089-
{
2090-
[CmdletBinding()]
2091-
param (
2092-
2093-
# Name of the Product
2094-
[ValidateNotNullOrEmpty()]
2095-
[string] $ProductName = 'PowerShell',
2096-
2097-
# Suffix of the Name
2098-
[string] $ProductNameSuffix,
2099-
2100-
# Version of the Product
2101-
[Parameter(Mandatory = $true)]
2102-
[ValidateNotNullOrEmpty()]
2103-
[string] $ProductVersion,
2104-
2105-
# The ProductCode property is a unique identifier for the particular product release
2106-
[Parameter(Mandatory = $true)]
2107-
[ValidateNotNullOrEmpty()]
2108-
[string] $ProductCode,
2109-
2110-
# Source Path to the Product Files - required to package the contents into an MSI
2111-
[Parameter(Mandatory = $true)]
2112-
[ValidateNotNullOrEmpty()]
2113-
[string] $ProductSourcePath,
2114-
2115-
# File describing the MSI Package creation semantics
2116-
[ValidateNotNullOrEmpty()]
2117-
[ValidateScript( {Test-Path $_})]
2118-
[string] $ProductWxsPath = "$PSScriptRoot\assets\Product.wxs",
2119-
2120-
# Path to Assets folder containing artifacts such as icons, images
2121-
[ValidateNotNullOrEmpty()]
2122-
[ValidateScript( {Test-Path $_})]
2123-
[string] $AssetsPath = "$PSScriptRoot\assets",
2124-
2125-
# Path to license.rtf file - for the EULA
2126-
[ValidateNotNullOrEmpty()]
2127-
[ValidateScript( {Test-Path $_})]
2128-
[string] $LicenseFilePath = "$PSScriptRoot\assets\license.rtf",
2129-
2130-
# Architecture to use when creating the MSI
2131-
[Parameter(Mandatory = $true)]
2132-
[ValidateSet("x86", "x64")]
2133-
[ValidateNotNullOrEmpty()]
2134-
[string] $ProductTargetArchitecture,
2135-
2136-
# Force overwrite of package
2137-
[Switch] $Force
2138-
)
2139-
2140-
## AppVeyor base image might update the version for Wix. Hence, we should
2141-
## not hard code version numbers.
2142-
$wixToolsetBinPath = "${env:ProgramFiles(x86)}\WiX Toolset *\bin"
2143-
2144-
Write-Verbose "Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath"
2145-
if (-not (Test-Path $wixToolsetBinPath))
2146-
{
2147-
throw "The latest version of Wix Toolset 3.11 is required to create MSI package. Please install it from https://github.com/wixtoolset/wix3/releases"
2148-
}
2149-
2150-
## Get the latest if multiple versions exist.
2151-
$wixToolsetBinPath = (Get-ChildItem $wixToolsetBinPath).FullName | Sort-Object -Descending | Select-Object -First 1
2152-
2153-
Write-Verbose "Initialize Wix executables - Heat.exe, Candle.exe, Light.exe"
2154-
$wixHeatExePath = Join-Path $wixToolsetBinPath "Heat.exe"
2155-
$wixCandleExePath = Join-Path $wixToolsetBinPath "Candle.exe"
2156-
$wixLightExePath = Join-Path $wixToolsetBinPath "Light.exe"
2157-
2158-
$ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion
2159-
$ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion
2160-
2161-
$assetsInSourcePath = Join-Path $ProductSourcePath 'assets'
2162-
New-Item $assetsInSourcePath -type directory -Force | Write-Verbose
2163-
2164-
Write-Verbose "Place dependencies such as icons to $assetsInSourcePath"
2165-
Copy-Item "$AssetsPath\*.ico" $assetsInSourcePath -Force
2166-
2167-
$productVersionWithName = $ProductName + '_' + $ProductVersion
2168-
$productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion
2169-
2170-
Write-Verbose "Create MSI for Product $productSemanticVersionWithName"
2171-
2172-
[Environment]::SetEnvironmentVariable("ProductSourcePath", $ProductSourcePath, "Process")
2173-
# These variables are used by Product.wxs in assets directory
2174-
[Environment]::SetEnvironmentVariable("ProductName", $ProductName, "Process")
2175-
[Environment]::SetEnvironmentVariable("ProductCode", $ProductCode, "Process")
2176-
[Environment]::SetEnvironmentVariable("ProductVersion", 10000 $ProductVersion, "Process")
2177-
[Environment]::SetEnvironmentVariable("ProductSemanticVersion", $ProductSemanticVersion, "Process")
2178-
[Environment]::SetEnvironmentVariable("ProductVersionWithName", $productVersionWithName, "Process")
2179-
$ProductProgFilesDir = "ProgramFiles64Folder"
2180-
if ($ProductTargetArchitecture -eq "x86")
2181-
{
2182-
$ProductProgFilesDir = "ProgramFilesFolder"
2183-
}
2184-
[Environment]::SetEnvironmentVariable("ProductProgFilesDir", $ProductProgFilesDir, "Process")
2185-
2186-
$wixFragmentPath = Join-Path $env:Temp "Fragment.wxs"
2187-
$wixObjProductPath = Join-Path $env:Temp "Product.wixobj"
2188-
$wixObjFragmentPath = Join-Path $env:Temp "Fragment.wixobj"
2189-
2190-
$packageName = $productSemanticVersionWithName
2191-
if ($ProductNameSuffix) {
2192-
$packageName += "-$ProductNameSuffix"
2193-
}
2194-
$msiLocationPath = Join-Path $pwd "$packageName.msi"
2195-
2196-
if(!$Force.IsPresent -and (Test-Path -Path $msiLocationPath))
2197-
{
2198-
Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop
2199-
}
2200-
2201-
$WiXHeatLog = & $wixHeatExePath dir $ProductSourcePath -dr $productVersionWithName -cg $productVersionWithName -gg -sfrag -srd -scom -sreg -out $wixFragmentPath -var env.ProductSourcePath -v
2202-
$WiXCandleLog = & $wixCandleExePath "$ProductWxsPath" "$wixFragmentPath" -out (Join-Path "$env:Temp" "\\") -ext WixUIExtension -ext WixUtilExtension -arch $ProductTargetArchitecture -v
2203-
$WiXLightLog = & $wixLightExePath -out $msiLocationPath $wixObjProductPath $wixObjFragmentPath -ext WixUIExtension -ext WixUtilExtension -dWixUILicenseRtf="$LicenseFilePath" -v
2204-
2205-
Remove-Item -ErrorAction SilentlyContinue *.wixpdb -Force
2206-
Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force
2207-
Remove-Item -ErrorAction SilentlyContinue $wixObjProductPath -Force
2208-
Remove-Item -ErrorAction SilentlyContinue $wixObjFragmentPath -Force
2209-
2210-
if (Test-Path $msiLocationPath)
2211-
{
2212-
Write-Verbose "You can find the MSI @ $msiLocationPath" -Verbose
2213-
$msiLocationPath
2214-
}
2215-
else
2216-
{
2217-
$WiXHeatLog | Out-String | Write-Verbose -Verbose
2218-
$WiXCandleLog | Out-String | Write-Verbose -Verbose
2219-
$WiXLightLog | Out-String | Write-Verbose -Verbose
2220-
$errorMessage = "Failed to create $msiLocationPath"
2221-
if ($null -ne $env:CI)
2222-
{
2223-
Add-AppveyorCompilationMessage $errorMessage -Category Error -FileName $MyInvocation.ScriptName -Line $MyInvocation.ScriptLineNumber
2224-
}
2225-
throw $errorMessage
2226-
}
2227-
}
2228-
22292042
function Start-CrossGen {
22302043
[CmdletBinding()]
22312044
param(

tools/packaging/packaging.psm1

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,3 +1429,190 @@ function Get-NugetSemanticVersion
14291429

14301430
$packageSemanticVersion
14311431
}
1432+
1433+
<#
1434+
.Synopsis
1435+
Creates a Windows installer MSI package and assumes that the binaries are already built using 'Start-PSBuild'.
1436+
This only works on a Windows machine due to the usage of WiX.
1437+
.EXAMPLE
1438+
# This example shows how to produce a Debug-x64 installer for development purposes.
1439+
cd $RootPathOfPowerShellRepo
1440+
Import-Module .\build.psm1; Import-Module .\tools\packaging\packaging.psm1
1441+
New-MSIPackage -Verbose -ProductCode (New-Guid) -ProductSourcePath '.\src\powershell-win-core\bin\Debug\netcoreapp2.0\win7-x64\publish' -ProductTargetArchitecture x64 -ProductVersion '1.2.3'
1442+
#>
1443+
function New-MSIPackage
1444+
{
1445+
[CmdletBinding()]
1446+
param (
1447+
1448+
# Name of the Product
1449+
[ValidateNotNullOrEmpty()]
1450+
[string] $ProductName = 'PowerShell',
1451+
1452+
# Suffix of the Name
1453+
[string] $ProductNameSuffix,
1454+
1455+
# Version of the Product
1456+
[Parameter(Mandatory = $true)]
1457+
[ValidateNotNullOrEmpty()]
1458+
[string] $ProductVersion,
1459+
1460+
# The ProductCode property is a unique identifier for the particular product release
1461+
[Parameter(Mandatory = $true)]
1462+
[ValidateNotNullOrEmpty()]
1463+
[string] $ProductCode,
1464+
1465+
# Source Path to the Product Files - required to package the contents into an MSI
1466+
[Parameter(Mandatory = $true)]
1467+
[ValidateNotNullOrEmpty()]
1468+
[string] $ProductSourcePath,
1469+
1470+
# File describing the MSI Package creation semantics
1471+
[ValidateNotNullOrEmpty()]
1472+
[ValidateScript( {Test-Path $_})]
1473+
[string] $ProductWxsPath = "$PSScriptRoot\..\..\assets\Product.wxs",
1474+
1475+
# Path to Assets folder containing artifacts such as icons, images
1476+
[ValidateNotNullOrEmpty()]
1477+
[ValidateScript( {Test-Path $_})]
1478+
[string] $AssetsPath = "$PSScriptRoot\..\..\assets",
1479+
1480+
# Path to license.rtf file - for the EULA
1481+
[ValidateNotNullOrEmpty()]
1482+
[ValidateScript( {Test-Path $_})]
1483+
[string] $LicenseFilePath = "$PSScriptRoot\..\..\assets\license.rtf",
1484+
1485+
# Architecture to use when creating the MSI
1486+
[Parameter(Mandatory = $true)]
1487+
[ValidateSet("x86", "x64")]
1488+
[ValidateNotNullOrEmpty()]
1489+
[string] $ProductTargetArchitecture,
1490+
1491+
# Force overwrite of package
1492+
[Switch] $Force
1493+
)
1494+
1495+
## AppVeyor base image might update the version for Wix. Hence, we should
1496+
## not hard code version numbers.
1497+
$wixToolsetBinPath = "${env:ProgramFiles(x86)}\WiX Toolset *\bin"
1498+
1499+
Write-Verbose "Ensure Wix Toolset is present on the machine @ $wixToolsetBinPath"
1500+
if (-not (Test-Path $wixToolsetBinPath))
1501+
{
1502+
throw "The latest version of Wix Toolset 3.11 is required to create MSI package. Please install it from https://github.com/wixtoolset/wix3/releases"
1503+
}
1504+
1505+
## Get the latest if multiple versions exist.
1506+
$wixToolsetBinPath = (Get-ChildItem $wixToolsetBinPath).FullName | Sort-Object -Descending | Select-Object -First 1
1507+
1508+
Write-Verbose "Initialize Wix executables - Heat.exe, Candle.exe, Light.exe"
1509+
$wixHeatExePath = Join-Path $wixToolsetBinPath "Heat.exe"
1510+
$wixCandleExePath = Join-Path $wixToolsetBinPath "Candle.exe"
1511+
$wixLightExePath = Join-Path $wixToolsetBinPath "Light.exe"
1512+
1513+
$ProductSemanticVersion = Get-PackageSemanticVersion -Version $ProductVersion
1514+
$ProductVersion = Get-PackageVersionAsMajorMinorBuildRevision -Version $ProductVersion
1515+
1516+
$assetsInSourcePath = Join-Path $ProductSourcePath 'assets'
1517+
New-Item $assetsInSourcePath -type directory -Force | Write-Verbose
1518+
1519+
Write-Verbose "Place dependencies such as icons to $assetsInSourcePath"
1520+
Copy-Item "$AssetsPath\*.ico" $assetsInSourcePath -Force
1521+
1522+
$productVersionWithName = $ProductName + '_' + $ProductVersion
1523+
$productSemanticVersionWithName = $ProductName + '-' + $ProductSemanticVersion
1524+
1525+
Write-Verbose "Create MSI for Product $productSemanticVersionWithName"
1526+
1527+
[Environment]::SetEnvironmentVariable("ProductSourcePath", $ProductSourcePath, "Process")
1528+
# These variables are used by Product.wxs in assets directory
1529+
[Environment]::SetEnvironmentVariable("ProductName", $ProductName, "Process")
1530+
[Environment]::SetEnvironmentVariable("ProductCode", $ProductCode, "Process")
1531+
[Environment]::SetEnvironmentVariable("ProductVersion", $ProductVersion, "Process")
1532+
[Environment]::SetEnvironmentVariable("ProductSemanticVersion", $ProductSemanticVersion, "Process")
1533+
[Environment]::SetEnvironmentVariable("ProductVersionWithName", $productVersionWithName, "Process")
1534+
$ProductProgFilesDir = "ProgramFiles64Folder"
1535+
if ($ProductTargetArchitecture -eq "x86")
1536+
{
1537+
$ProductProgFilesDir = "ProgramFilesFolder"
1538+
}
1539+
[Environment]::SetEnvironmentVariable("ProductProgFilesDir", $ProductProgFilesDir, "Process")
1540+
1541+
$wixFragmentPath = Join-Path $env:Temp "Fragment.wxs"
1542+
$wixObjProductPath = Join-Path $env:Temp "Product.wixobj"
1543+
$wixObjFragmentPath = Join-Path $env:Temp "Fragment.wixobj"
1544+
1545+
$packageName = $productSemanticVersionWithName
1546+
if ($ProductNameSuffix) {
1547+
$packageName += "-$ProductNameSuffix"
1548+
}
1549+
$msiLocationPath = Join-Path $pwd "$packageName.msi"
1550+
1551+
if(!$Force.IsPresent -and (Test-Path -Path $msiLocationPath))
1552+
{
1553+
Write-Error -Message "Package already exists, use -Force to overwrite, path: $msiLocationPath" -ErrorAction Stop
1554+
}
1555+
1556+
$WiXHeatLog = & $wixHeatExePath dir $ProductSourcePath -dr $productVersionWithName -cg $productVersionWithName -gg -sfrag -srd -scom -sreg -out $wixFragmentPath -var env.ProductSourcePath -v
1557+
$WiXCandleLog = & $wixCandleExePath "$ProductWxsPath" "$wixFragmentPath" -out (Join-Path "$env:Temp" "\\") -ext WixUIExtension -ext WixUtilExtension -arch $ProductTargetArchitecture -v
1558+
$WiXLightLog = & $wixLightExePath -out $msiLocationPath $wixObjProductPath $wixObjFragmentPath -ext WixUIExtension -ext WixUtilExtension -dWixUILicenseRtf="$LicenseFilePath" -v
1559+
1560+
Remove-Item -ErrorAction SilentlyContinue *.wixpdb -Force
1561+
Remove-Item -ErrorAction SilentlyContinue $wixFragmentPath -Force
1562+
Remove-Item -ErrorAction SilentlyContinue $wixObjProductPath -Force
1563+
Remove-Item -ErrorAction SilentlyContinue $wixObjFragmentPath -Force
1564+
1565+
if (Test-Path $msiLocationPath)
1566+
{
1567+
Write-Verbose "You can find the MSI @ $msiLocationPath" -Verbose
1568+
$msiLocationPath
1569+
}
1570+
else
1571+
{
1572+
$WiXHeatLog | Out-String | Write-Verbose -Verbose
1573+
$WiXCandleLog | Out-String | Write-Verbose -Verbose
1574+
$WiXLightLog | Out-String | Write-Verbose -Verbose
1575+
$errorMessage = "Failed to create $msiLocationPath"
1576+
if ($null -ne $env:CI)
1577+
{
1578+
Add-AppveyorCompilationMessage $errorMessage -Category Error -FileName $MyInvocation.ScriptName -Line $MyInvocation.ScriptLineNumber
1579+
}
1580+
throw $errorMessage
1581+
}
1582+
}
1583+
1584+
# Builds coming out of this project can have version number as 'a.b.c' OR 'a.b.c-d-f'
1585+
# This function converts the above version into major.minor[.build[.revision]] format
1586+
function Get-PackageVersionAsMajorMinorBuildRevision
1587+
{
1588+
[CmdletBinding()]
1589+
param (
1590+
# Version of the Package
1591+
[Parameter(Mandatory = $true)]
1592+
[ValidateNotNullOrEmpty()]
1593+
[string] $Version
1594+
)
1595+
1596+
Write-Verbose "Extract the version in the form of major.minor[.build[.revision]] for $Version"
1597+
$packageVersionTokens = $Version.Split('-')
1598+
$packageVersion = ([regex]::matches($Version, "\d+(\.\d+)+"))[0].value
1599+
1600+
if (1 -eq $packageVersionTokens.Count) {
1601+
# In case the input is of the form a.b.c, add a '0' at the end for revision field
1602+
$packageVersion = $packageVersion + '.0'
1603+
} elseif (1 -lt $packageVersionTokens.Count) {
1604+
# We have all the four fields
1605+
$packageBuildTokens = ([regex]::Matches($packageVersionTokens[1], "\d+"))[0].value
1606+
1607+
if ($packageBuildTokens)
1608+
{
1609+
$packageVersion = $packageVersion + '.' + $packageBuildTokens
1610+
}
1611+
else
1612+
{
1613+
$packageVersion = $packageVersion
1614+
}
1615+
}
1616+
1617+
$packageVersion
1618+
}

0 commit comments

Comments
 (0)
0