Skip to content

Commit dd6ebaa

Browse files
authored
[Build MSI] Adding MSI generation capability. (#1869)
* Added MSI creation assets and CI/CD integration scripts. * Fixed PowerShell build script's MSI generation branch limitation arguments. * Regenerated MSI GUIDs. * Adding tag-gating.
1 parent 4f77699 commit dd6ebaa

8 files changed

+154
-10
lines changed

Diff for: azure-pipelines.yml

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ variables:
2121
devops_buildNumber: $[counter(format(''), 1500)]
2222
APPVEYOR_REPO_BRANCH: $[coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranchName'])]
2323
APPVEYOR_REPO_COMMIT: $(Build.SourceVersion)
24-
2524
steps:
2625
- pwsh: |
2726
Write-Host "Target branch: '$(APPVEYOR_REPO_BRANCH)'"
@@ -47,7 +46,7 @@ steps:
4746
$accessToken = (az account get-access-token --query "accessToken" | % { $_.Trim('"') })
4847
echo "##vso[task.setvariable variable=azure_management_access_token]$accessToken"
4948
- pwsh: |
50-
.\build.ps1
49+
.\build.ps1 -MsiGenBranches @("v3.x") -CommitMessage $(Build.SourceVersionMessage)
5150
env:
5251
AzureBlobSigningConnectionString: $(AzureBlobSigningConnectionString)
5352
BuildArtifactsStorage: $(BuildArtifactsStorage)
@@ -63,7 +62,9 @@ steps:
6362
- task: CopyFiles@2
6463
inputs:
6564
SourceFolder: '$(Build.Repository.LocalPath)\artifacts'
66-
Contents: 'Azure.Functions.Cli.*'
65+
Contents: |
66+
Azure.Functions.Cli.*
67+
func-cli*.msi
6768
TargetFolder: '$(Build.ArtifactStagingDirectory)'
6869
CleanTargetFolder: true
6970
- task: PublishBuildArtifacts@1

Diff for: build.ps1

+54
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
param([String[]] $MsiGenBranches, [string] $CommitMessage)
2+
3+
$baseDir = Get-Location
14

25
if ($env:APPVEYOR_REPO_BRANCH -eq "disabled") {
36
Set-Location ".\src\Azure.Functions.Cli"
@@ -39,3 +42,54 @@ else {
3942
Invoke-Expression -Command "dotnet run"
4043
if ($LastExitCode -ne 0) { $host.SetShouldExit($LastExitCode) }
4144
}
45+
46+
if ($MsiGenBranches -Contains $env:APPVEYOR_REPO_BRANCH -or $CommitMessage -Contains "[Build MSI]") {
47+
Write-Host "Generating MSI files"
48+
49+
# Add WiX to PATH
50+
if (-not (@($env:Path -split ";") -contains $env:WIX))
51+
{
52+
# Check if the Wix path points to the bin folder
53+
if ((Split-Path $env:WIX -Leaf) -ne "bin")
54+
{
55+
$env:Path += ";$env:WIX\bin"
56+
}
57+
else
58+
{
59+
$env:Path += ";$env:WIX"
60+
}
61+
}
62+
63+
# Get runtime version
64+
$artifactsPath = "$baseDir\artifacts"
65+
$buildDir = "$baseDir\build"
66+
$cli = Get-ChildItem -Path $artifactsPath -Include func.dll -Recurse | Select-Object -First 1
67+
$cliVersion = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($cli).FileVersion
68+
69+
# Generate MSI installers for Windows
70+
@('x64', 'x86') | ForEach-Object {
71+
$platform = $_
72+
$targetDir = "$artifactsPath\win-$platform"
73+
74+
Copy-Item "$buildDir\icon.ico" -Destination $artifactsPath\win-$platform
75+
Copy-Item "$buildDir\license.rtf" -Destination $artifactsPath\win-$platform
76+
Copy-Item "$buildDir\installbanner.bmp" -Destination $artifactsPath\win-$platform
77+
Copy-Item "$buildDir\installdialog.bmp" -Destination $artifactsPath\win-$platform
78+
Set-Location $targetDir
79+
80+
$masterWxsName = "funcinstall"
81+
$fragmentName = "$platform-frag"
82+
$msiName = "func-cli-$cliVersion-$platform"
83+
84+
$masterWxsPath = "$buildDir\$masterWxsName.wxs"
85+
$fragmentPath = "$buildDir\$fragmentName.wxs"
86+
$msiPath = "$artifactsPath\$msiName.msi"
87+
88+
Invoke-Expression "heat dir '.' -cg FuncHost -dr INSTALLDIR -gg -ke -out $fragmentPath -srd -sreg -template fragment -var var.Source"
89+
Invoke-Expression "candle -arch $platform -dPlatform='$platform' -dSource='.' -dProductVersion='$cliVersion' $masterWxsPath $fragmentPath"
90+
Invoke-Expression "light -ext WixUIExtension -out $msiPath -sice:ICE61 $masterWxsName.wixobj $fragmentName.wixobj"
91+
92+
Set-Location $baseDir
93+
Get-ChildItem -Path $targetDir -Recurse | Remove-Item -Force -Recurse -ea SilentlyContinue
94+
}
95+
}

Diff for: build/BuildSteps.cs

+10-7
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,16 @@ public static void Zip()
437437
ColoredConsole.WriteLine($"Creating {shaPath}");
438438
File.WriteAllText(shaPath, ComputeSha256(zipPath));
439439

440-
try
441-
{
442-
Directory.Delete(path, recursive: true);
443-
}
444-
catch
445-
{
446-
ColoredConsole.Error.WriteLine($"Error deleting {path}");
440+
if (!runtime.StartsWith("win")) {
441+
try
442+
{
443+
Directory.Delete(path, recursive: true);
444+
}
445+
catch
446+
{
447+
ColoredConsole.Error.WriteLine($"Error deleting {path}");
448+
}
449+
447450
}
448451

449452
ColoredConsole.WriteLine();

Diff for: build/funcinstall.wxs

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?xml version='1.0' encoding='windows-1252'?>
2+
<?define Manufacturer='Microsoft'?>
3+
<?define ProductName='Azure Functions Core Tools'?>
4+
5+
<?if $(var.Platform)=x64?>
6+
<?define UpgradeCodeGuid='E9F5190E-0E1F-49C0-BAF5-3D47FE5837B9'?>
7+
<?define PathGuid='E7D05676-5209-45E2-99DB-F4B20CF3D89D'?>
8+
<?define ProgramMenuDirGuid='09195356-949C-4CEF-9C2C-84EA559E5C19'?>
9+
<?define PlatformProgramFilesFolder='ProgramFiles64Folder'?>
10+
<?else?>
11+
<?define UpgradeCodeGuid='31C010A9-2414-4DB7-BFEA-A6F1D085382E'?>
12+
<?define PathGuid='35765F38-08D4-4E00-A006-CD71240AD39F'?>
13+
<?define ProgramMenuDirGuid='46CAA18B-4C44-4954-8D99-C681CD1F301D'?>
14+
<?define PlatformProgramFilesFolder='ProgramFilesFolder'?>
15+
<?endif?>
16+
17+
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
18+
<!-- Product, Package and Upgrade Information -->
19+
<Product Id='*'
20+
Name='$(var.ProductName) - $(var.ProductVersion) ($(var.Platform))'
21+
UpgradeCode='$(var.UpgradeCodeGuid)'
22+
Language='1033'
23+
Codepage='1252'
24+
Version='$(var.ProductVersion)'
25+
Manufacturer='$(var.Manufacturer)'>
26+
27+
<Package Id='*'
28+
Keywords='Azure, Functions, Core Tools, Installer'
29+
Description='$(var.ProductName) $(var.ProductVersion) $(var.Platform) Installer'
30+
Manufacturer='$(var.Manufacturer)'
31+
Comments='Copyright (c) .NET Foundation. All rights reserved. Licensed under the MIT License.'
32+
InstallerVersion='300'
33+
Compressed='yes'
34+
Languages='1033'
35+
SummaryCodepage='1252' />
36+
37+
<MajorUpgrade AllowDowngrades='yes' Schedule='afterInstallInitialize' />
38+
39+
<Media Id='1' Cabinet='funchost.cab' EmbedCab='yes' />
40+
41+
<!-- Directory Structure and Feature Definition -->
42+
<Directory Id='TARGETDIR' Name='SourceDir'>
43+
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
44+
<Directory Id='$(var.Manufacturer)' Name='$(var.Manufacturer)'>
45+
<Directory Id='INSTALLDIR' Name='$(var.ProductName)'>
46+
<!-- FuncHost componentgroup in fragment -->
47+
<Component Id='Path' Guid='$(var.PathGuid)' KeyPath='yes'>
48+
<Environment Id='UpdatePath' Name='PATH' Value='[INSTALLDIR]' Permanent='no' Part='last' Action='set' System='yes' />
49+
</Component>
50+
</Directory>
51+
</Directory>
52+
</Directory>
53+
54+
<Directory Id='ProgramMenuFolder' Name='Programs'>
55+
<Directory Id='ProgramMenuDir' Name='$(var.ProductName)'>
56+
<Component Id='ProgramMenuDir' Guid='$(var.ProgramMenuDirGuid)'>
57+
<RemoveFolder Id='ProgramMenuDir' On='uninstall' />
58+
<RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' />
59+
</Component>
60+
</Directory>
61+
</Directory>
62+
</Directory>
63+
64+
<Feature Id='Complete'
65+
Level='1'
66+
Title='$(var.ProductName)'
67+
Description='Placeholder description'
68+
Display='expand'>
69+
<ComponentGroupRef Id='FuncHost' />
70+
<ComponentRef Id='ProgramMenuDir' />
71+
<ComponentRef Id='Path' />
72+
</Feature>
73+
74+
<!-- UI -->
75+
<UIRef Id='WixUI_InstallDir' />
76+
<UIRef Id='WixUI_ErrorProgressText' />
77+
<Property Id='WIXUI_INSTALLDIR' Value='INSTALLDIR' />
78+
79+
<Icon Id='icon.ico' SourceFile='icon.ico' />
80+
<Property Id='ARPPRODUCTICON' Value='icon.ico' />
81+
82+
<WixVariable Id='WixUILicenseRtf' Value='license.rtf' />
83+
<WixVariable Id='WixUIBannerBmp' Value='installbanner.bmp' />
84+
<WixVariable Id='WixUIDialogBmp' Value='installdialog.bmp' />
85+
</Product>
86+
</Wix>

Diff for: build/icon.ico

32 KB
Binary file not shown.

Diff for: build/installbanner.bmp

83.9 KB
Binary file not shown.

Diff for: build/installdialog.bmp

451 KB
Binary file not shown.

Diff for: build/license.rtf

1.26 KB
Binary file not shown.

0 commit comments

Comments
 (0)