|
| 1 | +# Copyright (c) Cloud Software Group, Inc. |
| 2 | +# |
| 3 | +# Redistribution and use in source and binary forms, |
| 4 | +# with or without modification, are permitted provided |
| 5 | +# that the following conditions are met: |
| 6 | +# |
| 7 | +# * Redistributions of source code must retain the above |
| 8 | +# copyright notice, this list of conditions and the |
| 9 | +# following disclaimer. |
| 10 | +# * Redistributions in binary form must reproduce the above |
| 11 | +# copyright notice, this list of conditions and the |
| 12 | +# following disclaimer in the documentation and/or other |
| 13 | +# materials provided with the distribution. |
| 14 | +# |
| 15 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
| 16 | +# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| 17 | +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 | +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 19 | +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
| 20 | +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 22 | +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 23 | +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 24 | +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 25 | +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 26 | +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 27 | +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 28 | +# SUCH DAMAGE. |
| 29 | + |
| 30 | +Param( |
| 31 | + [Parameter(HelpMessage = "Global build number", Mandatory = $true)] |
| 32 | + [int]$buildNumber, |
| 33 | + |
| 34 | + [Parameter(HelpMessage = "Thumbprint of the certificate to use for signing")] |
| 35 | + [string]$thumbPrint, |
| 36 | + |
| 37 | + [Parameter(HelpMessage = "Timestamp server to use for signing")] |
| 38 | + [string]$timestampServer |
| 39 | +) |
| 40 | + |
| 41 | +$verbose = $false |
| 42 | +if ($PSBoundParameters.ContainsKey('Verbose')) { |
| 43 | + $verbose = $PsBoundParameters['Verbose'] |
| 44 | +} |
| 45 | + |
| 46 | +$ErrorActionPreference = "Stop" |
| 47 | + |
| 48 | +#################### |
| 49 | +# Helper functions # |
| 50 | +#################### |
| 51 | + |
| 52 | +function mkdir_clean([string]$path) { |
| 53 | + if ([System.IO.Directory]::Exists($path)) { |
| 54 | + Remove-Item -Path $path -Force -Recurse -Verbose:$verbose |
| 55 | + } |
| 56 | + New-Item -ItemType Directory -Path $path -Verbose:$verbose |
| 57 | +} |
| 58 | + |
| 59 | +function build([string]$solution) { |
| 60 | + msbuild /m /verbosity:minimal /p:Configuration=Release /p:TargetFrameworkVersion=v4.8 /p:VisualStudioVersion=17.0 $solution |
| 61 | +} |
| 62 | + |
| 63 | +function get_locale_id([string]$locale) { |
| 64 | + switch ($locale) { |
| 65 | + "ja-jp" { 1041 } |
| 66 | + "zh-cn" { 2052 } |
| 67 | + "zh-tw" { 1028 } |
| 68 | + default { 1033 } #en-us |
| 69 | + } |
| 70 | +} |
| 71 | + |
| 72 | +###################### |
| 73 | +# clean working area # |
| 74 | +###################### |
| 75 | + |
| 76 | +$REPO = Get-Item "$PSScriptRoot\.." | Select-Object -ExpandProperty FullName |
| 77 | +$SCRATCH_DIR="$REPO\_scratch" |
| 78 | +$OUTPUT_DIR="$REPO\_output" |
| 79 | + |
| 80 | +Write-Host "INFO: Cleaning scratch and output directories" |
| 81 | +mkdir_clean $SCRATCH_DIR |
| 82 | +mkdir_clean $OUTPUT_DIR |
| 83 | + |
| 84 | +. $REPO\scripts\branding.ps1 |
| 85 | +$appName = $BRANDING_BRAND_CONSOLE |
| 86 | + |
| 87 | +############################################ |
| 88 | +# package sources BEFORE applying branding # |
| 89 | +############################################ |
| 90 | + |
| 91 | +Write-Host "INFO: Packaging source files" |
| 92 | + |
| 93 | +$gitCommit = git rev-parse HEAD |
| 94 | +git archive --format=zip -o "$SCRATCH_DIR\xenadmin-sources.zip" $gitCommit |
| 95 | + |
| 96 | +Compress-Archive -Path "$SCRATCH_DIR\xenadmin-sources.zip","$REPO\packages\dotnet-packages-sources.zip" ` |
| 97 | + -DestinationPath "$OUTPUT_DIR\$appName-source.zip" -Verbose:$verbose |
| 98 | + |
| 99 | +################## |
| 100 | +# apply branding # |
| 101 | +################## |
| 102 | + |
| 103 | +.$REPO\scripts\rebranding.ps1 $buildNumber -Verbose:$verbose |
| 104 | + |
| 105 | +Write-Host "INFO: Expanding External Tools" |
| 106 | +Expand-Archive -Path $REPO\packages\XenCenterOVF.zip -DestinationPath $SCRATCH_DIR -Verbose:$verbose |
| 107 | + |
| 108 | +Write-Host "INFO: Building solution" |
| 109 | +build $REPO\XenAdmin.sln |
| 110 | + |
| 111 | +############## |
| 112 | +# sign files # |
| 113 | +############## |
| 114 | + |
| 115 | +if ([System.IO.File]::Exists("$REPO\scripts\sign.ps1")) { |
| 116 | + . $REPO\scripts\sign.ps1 |
| 117 | + |
| 118 | + $filesToSign = @( |
| 119 | + "$REPO\XenAdmin\bin\Release\CommandLib.dll", |
| 120 | + "$REPO\XenAdmin\bin\Release\MSTSCLib.dll", |
| 121 | + "$REPO\XenAdmin\bin\Release\CoreUtilsLib.dll", |
| 122 | + "$REPO\XenAdmin\bin\Release\XenModel.dll", |
| 123 | + "$REPO\XenAdmin\bin\Release\XenOvf.dll", |
| 124 | + "$REPO\XenAdmin\bin\Release\$appName.exe", |
| 125 | + "$REPO\xe\bin\Release\xe.exe", |
| 126 | + "$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.dll", |
| 127 | + "$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.ProcessingObjectModel.dll", |
| 128 | + "$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.WinForms.dll", |
| 129 | + "$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.Common.resources.dll", |
| 130 | + "$REPO\XenAdmin\ReportViewer\Microsoft.ReportViewer.WinForms.resources.dll" |
| 131 | + ) |
| 132 | + |
| 133 | + foreach ($file in $filesToSign) { |
| 134 | + sign_artifact $file $appName $thumbPrint $timestampServer |
| 135 | + } |
| 136 | + |
| 137 | + sign_artifact $REPO\XenAdmin\bin\Release\CookComputing.XmlRpcV2.dll "XML-RPC.NET" $thumbPrint $timestampServer |
| 138 | + sign_artifact $REPO\XenAdmin\bin\Release\Newtonsoft.Json.CH.dll "JSON.NET" $thumbPrint $timestampServer |
| 139 | + sign_artifact $REPO\XenAdmin\bin\Release\log4net.dll "Log4Net" $thumbPrint $timestampServer |
| 140 | + sign_artifact $REPO\XenAdmin\bin\Release\ICSharpCode.SharpZipLib.dll "SharpZipLib" $thumbPrint $timestampServer |
| 141 | + sign_artifact $REPO\XenAdmin\bin\Release\DiscUtils.dll "DiscUtils" $thumbPrint $timestampServer |
| 142 | + |
| 143 | +} |
| 144 | +else { |
| 145 | + Write-Host "INFO: Sign script does not exist; skip signing binaries" |
| 146 | +} |
| 147 | + |
| 148 | +############### |
| 149 | +# prepare Wix # |
| 150 | +############### |
| 151 | + |
| 152 | +Write-Host "INFO: Preparing Wix binaries and UI sources" |
| 153 | +mkdir_clean $SCRATCH_DIR\wixbin |
| 154 | +Expand-Archive -Path $REPO\packages\wix311-binaries.zip -DestinationPath $SCRATCH_DIR\wixbin |
| 155 | +mkdir_clean $SCRATCH_DIR\wixsrc |
| 156 | +Expand-Archive -Path $REPO\packages\wix311-debug.zip -DestinationPath $SCRATCH_DIR\wixsrc |
| 157 | + |
| 158 | +Copy-Item -Recurse $REPO\WixInstaller $SCRATCH_DIR -Verbose:$verbose |
| 159 | +Copy-Item -Recurse $SCRATCH_DIR\wixsrc\src\ext\UIExtension\wixlib $SCRATCH_DIR\WixInstaller -Verbose:$verbose |
| 160 | +Copy-Item $SCRATCH_DIR\WixInstaller\wixlib\CustomizeDlg.wxs $SCRATCH_DIR\WixInstaller\wixlib\CustomizeStdDlg.wxs -Verbose:$verbose |
| 161 | + |
| 162 | +if ("XenCenter" -ne $appName) { |
| 163 | + Rename-Item -Path $SCRATCH_DIR\WixInstaller\XenCenter.wxs -NewName "$appName.wxs" -Verbose:$verbose |
| 164 | +} |
| 165 | + |
| 166 | +$origLocation = Get-Location |
| 167 | +Set-Location $SCRATCH_DIR\WixInstaller\wixlib -Verbose:$verbose |
| 168 | +try { |
| 169 | + Write-Host "INFO: Patching Wix UI library" |
| 170 | + git apply --verbose $SCRATCH_DIR\WixInstaller\wix_src.patch |
| 171 | + Write-Host "INFO: Patching Wix UI library completed" |
| 172 | +} |
| 173 | +finally { |
| 174 | + Set-Location $origLocation -Verbose:$verbose |
| 175 | +} |
| 176 | + |
| 177 | +New-Item -ItemType File -Path $SCRATCH_DIR\WixInstaller\PrintEula.dll -Verbose:$verbose |
| 178 | + |
| 179 | +############### |
| 180 | +# compile Wix # |
| 181 | +############### |
| 182 | + |
| 183 | +$CANDLE="$SCRATCH_DIR\wixbin\candle.exe" |
| 184 | +$LIT="$SCRATCH_DIR\wixbin\lit.exe" |
| 185 | +$LIGHT="$SCRATCH_DIR\wixbin\light.exe" |
| 186 | + |
| 187 | +$installerUiFiles = @( |
| 188 | + "BrowseDlg", |
| 189 | + "CancelDlg", |
| 190 | + "Common", |
| 191 | + "CustomizeDlg", |
| 192 | + "CustomizeStdDlg", |
| 193 | + "DiskCostDlg", |
| 194 | + "ErrorDlg", |
| 195 | + "ErrorProgressText", |
| 196 | + "ExitDialog", |
| 197 | + "FatalError", |
| 198 | + "FilesInUse", |
| 199 | + "InstallDirDlg", |
| 200 | + "InvalidDirDlg", |
| 201 | + "LicenseAgreementDlg", |
| 202 | + "MaintenanceTypeDlg", |
| 203 | + "MaintenanceWelcomeDlg", |
| 204 | + "MsiRMFilesInUse", |
| 205 | + "OutOfDiskDlg", |
| 206 | + "OutOfRbDiskDlg", |
| 207 | + "PrepareDlg", |
| 208 | + "ProgressDlg", |
| 209 | + "ResumeDlg", |
| 210 | + "SetupTypeDlg", |
| 211 | + "UserExit", |
| 212 | + "VerifyReadyDlg", |
| 213 | + "WaitForCostingDlg", |
| 214 | + "WelcomeDlg", |
| 215 | + "WixUI_InstallDir", |
| 216 | + "WixUI_FeatureTree" |
| 217 | +) |
| 218 | + |
| 219 | +$candleList = $installerUiFiles | ForEach-Object { "$SCRATCH_DIR\WixInstaller\wixlib\$_.wxs" } |
| 220 | +$candleListString = $candleList -join " " |
| 221 | +$litList = $installerUiFiles | ForEach-Object { "$SCRATCH_DIR\WixInstaller\wixlib\$_.wixobj" } |
| 222 | +$litListString = $litList -join " " |
| 223 | + |
| 224 | +$env:RepoRoot=$REPO |
| 225 | +$env:WixLangId=get_locale_id $locale |
| 226 | + |
| 227 | +Write-Host "INFO: Compiling Wix UI" |
| 228 | +Invoke-Expression "$CANDLE -v -out $SCRATCH_DIR\WixInstaller\wixlib\ $candleListString" |
| 229 | +Invoke-Expression "$LIT -v -out $SCRATCH_DIR\WixInstaller\wixlib\WixUiLibrary.wixlib $litListString" |
| 230 | + |
| 231 | +########################################################## |
| 232 | +# for each locale create an msi containing all resources # |
| 233 | +########################################################## |
| 234 | + |
| 235 | +$locales = @("en-us") |
| 236 | + |
| 237 | +foreach ($locale in $locales) { |
| 238 | + if ($locale -eq "en-us") { |
| 239 | + $name=$appName |
| 240 | + } |
| 241 | + else { |
| 242 | + $name=$appName.$locale |
| 243 | + } |
| 244 | + |
| 245 | + Write-Host "INFO: Building msi installer" |
| 246 | + |
| 247 | + Invoke-Expression "$CANDLE -v -ext WiXNetFxExtension -ext WixUtilExtension -out $SCRATCH_DIR\WixInstaller\ $SCRATCH_DIR\WixInstaller\$appName.wxs" |
| 248 | + |
| 249 | + Invoke-Expression "$LIGHT -v -sval -ext WiXNetFxExtension -ext WixUtilExtension -out $SCRATCH_DIR\WixInstaller\$name.msi -loc $SCRATCH_DIR\WixInstaller\wixlib\wixui_$locale.wxl -loc $SCRATCH_DIR\WixInstaller\$locale.wxl $SCRATCH_DIR\WixInstaller\$appName.wixobj $SCRATCH_DIR\WixInstaller\wixlib\WixUiLibrary.wixlib" |
| 250 | +} |
| 251 | + |
| 252 | +######################################## |
| 253 | +# copy and sign the combined installer # |
| 254 | +######################################## |
| 255 | + |
| 256 | +if ([System.IO.File]::Exists("$REPO\scripts\sign.ps1")) { |
| 257 | + sign_artifact "$SCRATCH_DIR\WixInstaller\$appName.msi" $appName $thumbPrint $timestampServer |
| 258 | +} |
| 259 | +else { |
| 260 | + Write-Host "INFO: Sign script does not exist; skip signing installer" |
| 261 | +} |
| 262 | + |
| 263 | +Copy-Item "$SCRATCH_DIR\WixInstaller\$appName.msi" $OUTPUT_DIR |
| 264 | + |
| 265 | +################### |
| 266 | +# build the tests # |
| 267 | +################### |
| 268 | + |
| 269 | +Write-Host "INFO: Building the tests" |
| 270 | +build $REPO\XenAdminTests\XenAdminTests.csproj |
| 271 | +Copy-Item $REPO\XenAdmin\ReportViewer\* $REPO\XenAdminTests\bin\Release\ -Verbose:$verbose |
| 272 | + |
| 273 | +Compress-Archive -Path $REPO\XenAdminTests\bin\Release -DestinationPath $OUTPUT_DIR\XenAdminTests.zip -Verbose:$verbose |
| 274 | +Compress-Archive -Path $REPO\XenAdmin\TestResources\* -DestinationPath "$OUTPUT_DIR\$($appName)TestResources.zip" -Verbose:$verbose |
| 275 | + |
| 276 | +#################################################### |
| 277 | +# include cfu validator binary in output directory # |
| 278 | +#################################################### |
| 279 | + |
| 280 | +Compress-Archive -Path $REPO\CFUValidator\bin\Release\*.dll -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose |
| 281 | +Compress-Archive -Path $REPO\CFUValidator\bin\Release\CFUValidator.exe -Update -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose |
| 282 | +Compress-Archive -Path $REPO\CFUValidator\bin\Release\$appName.exe -Update -DestinationPath $OUTPUT_DIR\CFUValidator.zip -Verbose:$verbose |
| 283 | + |
| 284 | +#################### |
| 285 | +# package the pdbs # |
| 286 | +#################### |
| 287 | + |
| 288 | +Compress-Archive -Path $REPO\packages\*.pdb,$REPO\XenAdmin\bin\Release\*.pdb,$REPO\xe\bin\Release\xe.pdb ` |
| 289 | + -DestinationPath "$OUTPUT_DIR\$appName.Symbols.zip" -Verbose:$verbose |
| 290 | + |
| 291 | +################################################ |
| 292 | +# calculate installer and source zip checksums # |
| 293 | +################################################ |
| 294 | + |
| 295 | +$msi_checksum = (Get-FileHash -Path "$OUTPUT_DIR\$appName.msi" -Algorithm SHA256 |` |
| 296 | + Select-Object -ExpandProperty Hash).ToLower() |
| 297 | + |
| 298 | +$msi_checksum | Out-File -FilePath "$OUTPUT_DIR\$appName.msi.checksum" -Encoding utf8 |
| 299 | + |
| 300 | +Write-Host "INFO: Calculated checksum installer checksum: $msi_checksum" |
| 301 | + |
| 302 | +$source_checksum = (Get-FileHash -Path "$OUTPUT_DIR\$appName-source.zip" -Algorithm SHA256 |` |
| 303 | + Select-Object -ExpandProperty Hash).ToLower() |
| 304 | + |
| 305 | +$source_checksum | Out-File -FilePath "$OUTPUT_DIR\$appName-source.zip.checksum" -Encoding utf8 |
| 306 | + |
| 307 | +Write-Host "INFO: Calculated checksum source checksum: $source_checksum" |
| 308 | + |
| 309 | +$xmlFormat=@" |
| 310 | +<?xml version=\"1.0\" ?> |
| 311 | +<patchdata> |
| 312 | + <versions> |
| 313 | + <version |
| 314 | + latest="true" |
| 315 | + latestcr="true" |
| 316 | + name="{0}" |
| 317 | + timestamp="{1}" |
| 318 | + url="{2}" |
| 319 | + checksum="{3}" |
| 320 | + value="{4}" |
| 321 | + /> |
| 322 | + </versions> |
| 323 | +</patchdata> |
| 324 | +"@ |
| 325 | + |
| 326 | +$msi_url = $XC_UPDATES_URL -replace "XCUpdates.xml","$appName.msi" |
| 327 | +$date=(Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") |
| 328 | +$productFullName = "$appName $productVersion" |
| 329 | +$productVersion = "$BRANDING_XC_PRODUCT_VERSION.$buildNumber" |
| 330 | + |
| 331 | +Write-Host "INFO: Generating XCUpdates.xml" |
| 332 | + |
| 333 | +[string]::Format($xmlFormat, $productFullName, $date, $msi_url, $msi_checksum, $productVersion) |` |
| 334 | + Out-File -FilePath $OUTPUT_DIR\XCUpdates.xml -Encoding utf8 |
| 335 | + |
| 336 | +Write-Host "INFO: Generating stage-test-XCUpdates.xml. URL is a placeholder value" |
| 337 | + |
| 338 | +[string]::Format($xmlFormat, $productFullName, $date, "@DEV_MSI_URL_PLACEHOLDER@", $msi_checksum, $productVersion) |` |
| 339 | + Out-File -FilePath $OUTPUT_DIR\stage-test-XCUpdates.xml -Encoding utf8 |
0 commit comments