Skip to content

Commit

Permalink
nightly: deploy an appinstaller to an Azure storage account (!) (micr…
Browse files Browse the repository at this point in the history
…osoft#16013)

After the nightly build completes, we'll automatically generate a
.appinstaller and publich it plus the msixbundle to an Azure Storage
account.

I had to add step/job customization to the publish step in the full
release pipeline template.

The .appinstaller hardcodes our XAML dependency, which makes it a bit of
a pain. We can revisit this later, and publish our dependencies
directly and automatically instead of hardcoding them.

I am considering moving the appinstaller generation step to the MSIX
bundling job, but this works right now and is not too terrible.

Closes microsoft#774
  • Loading branch information
DHowett authored Sep 22, 2023
1 parent 29a22c9 commit 86ad3c8
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/actions/spelling/allow/microsoft.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ advapi
altform
altforms
appendwttlogging
appinstaller
appx
appxbundle
appxerror
Expand Down
38 changes: 38 additions & 0 deletions build/config/template.appinstaller
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<AppInstaller
xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"
Version="1.0.0.0"
Uri="$$ROOT$$$$NAME$$.appinstaller">

<MainBundle
Name="$$NAME$$"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="$$VERSION$$"
Uri="$$ROOT$$$$PACKAGE$$" />

<Dependencies>
<Package
Name="Microsoft.UI.Xaml.2.8"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="8.2305.5001.0"
ProcessorArchitecture="x64"
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x64.appx" />
<Package
Name="Microsoft.UI.Xaml.2.8"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="8.2305.5001.0"
ProcessorArchitecture="x86"
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.x86.appx" />
<Package
Name="Microsoft.UI.Xaml.2.8"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="8.2305.5001.0"
ProcessorArchitecture="arm64"
Uri="https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.8.4/Microsoft.UI.Xaml.2.8.arm64.appx" />
</Dependencies>

<UpdateSettings>
<OnLaunch
HoursBetweenUpdateChecks="6" />
</UpdateSettings>
</AppInstaller>
20 changes: 20 additions & 0 deletions build/pipelines/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ schedules:

name: $(BuildDefinitionName)_$(date:yyMM).$(date:dd)$(rev:rrr)

parameters:
- name: publishToAzure
displayName: "Deploy to **PUBLIC** Azure Storage"
type: boolean
default: true

extends:
template: templates-v2\pipeline-full-release-build.yml
parameters:
Expand All @@ -21,3 +27,17 @@ extends:
publishSymbolsToPublic: true
publishVpackToWindows: false
symbolExpiryTime: 15 # Nightly builds do not keep symbols for very long!
${{ if eq(true, parameters.publishToAzure) }}:
extraPublishJobs:
- template: job-deploy-to-azure-storage.yml
parameters:
pool:
name: SHINE-INT-S
dependsOn: [PublishSymbols]
storagePublicRootURL: $(AppInstallerRootURL)
subscription: $(AzureSubscriptionName)
storageAccount: $(AzureStorageAccount)
storageContainer: $(AzureStorageContainer)
buildConfiguration: Release
environment: production-canary

70 changes: 70 additions & 0 deletions build/pipelines/templates-v2/job-deploy-to-azure-storage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
parameters:
- name: buildConfiguration
type: string
- name: pool
type: object
default: []
- name: dependsOn
type: object
default: null
- name: artifactStem
type: string
default: ''
- name: variables
type: object
default: {}
- name: environment
type: string
- name: storagePublicRootURL
type: string
- name: subscription
type: string
- name: storageAccount
type: string
- name: storageContainer
type: string

jobs:
- deployment: DeployAzure
${{ if ne(length(parameters.pool), 0) }}:
pool: ${{ parameters.pool }}
displayName: Publish to Azure Storage (Prod)
dependsOn: ${{ parameters.dependsOn }}
variables:
${{ insert }}: ${{ parameters.variables }}
environment: ${{ parameters.environment }}
strategy:
runOnce:
deploy:
steps:
- download: none

- checkout: self
clean: true
fetchDepth: 1
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
submodules: true
persistCredentials: True

- task: DownloadPipelineArtifact@2
displayName: Download MSIX Bundle Artifact
inputs:
artifactName: appxbundle-${{ parameters.buildConfiguration }}${{ parameters.artifactStem }}
downloadPath: '$(Build.SourcesDirectory)/_out'
itemPattern: '**/*.msixbundle'

- pwsh: |-
$b = Get-Item _out/*.msixbundle
./build/scripts/New-AppInstallerFromTemplateAndBundle.ps1 -BundlePath $b.FullName -AppInstallerTemplatePath ./build/config/template.appinstaller -AppInstallerRoot "${{ parameters.storagePublicRootURL }}" -OutputPath _out/Microsoft.WindowsTerminalCanary.appinstaller
displayName: "Produce AppInstaller for MSIX bundle"
- task: AzureFileCopy@5
displayName: Publish to Storage Account
inputs:
sourcePath: _out/*
Destination: AzureBlob
azureSubscription: ${{ parameters.subscription }}
storage: ${{ parameters.storageAccount }}
ContainerName: ${{ parameters.storageContainer }}
AdditionalArgumentsForBlobCopy: "--content-type application/octet-stream"

2 changes: 2 additions & 0 deletions build/pipelines/templates-v2/job-merge-msix-into-bundle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ jobs:
BundleStemName: Microsoft.WindowsTerminal
${{ elseif eq(parameters.branding, 'Preview') }}:
BundleStemName: Microsoft.WindowsTerminalPreview
${{ elseif eq(parameters.branding, 'Canary') }}:
BundleStemName: Microsoft.WindowsTerminalCanary
${{ else }}:
BundleStemName: WindowsTerminalDev
JobOutputDirectory: '$(System.ArtifactsDirectory)/bundle'
Expand Down
4 changes: 4 additions & 0 deletions build/pipelines/templates-v2/pipeline-full-release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ parameters:
type: boolean
default: false

- name: extraPublishJobs
type: object
default: []
- name: pool
type: object
default:
Expand Down Expand Up @@ -193,4 +196,5 @@ stages:
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}

- ${{ parameters.extraPublishJobs }}
...
42 changes: 42 additions & 0 deletions build/scripts/New-AppInstallerFromTemplateAndBundle.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
[CmdletBinding()]
Param(
[Parameter(Mandatory,
HelpMessage="Path to the .msixbundle")]
[string]
$BundlePath,

[Parameter(Mandatory,
HelpMessage="Path to the .appinstaller template")]
[string]
$AppInstallerTemplatePath,

[string]
$AppInstallerRoot,

[Parameter(Mandatory,
HelpMessage="Output Path")]
[string]
$OutputPath
)

$ErrorActionPreference = "Stop"

$sentinelFile = New-TemporaryFile
$directory = New-Item -Type Directory "$($sentinelFile.FullName)_Package"
Remove-Item $sentinelFile -Force -EA:Ignore

$bundle = (Get-Item $BundlePath)
& tar.exe -x -f $bundle.FullName -C $directory AppxMetadata/AppxBundleManifest.xml

$xml = [xml](Get-Content (Join-Path $directory "AppxMetadata\AppxBundleManifest.xml"))
$name = $xml.Bundle.Identity.Name
$version = $xml.Bundle.Identity.Version

$doc = (Get-Content -ReadCount 0 $AppInstallerTemplatePath)
$doc = $doc -Replace '\$\$ROOT\$\$',$AppInstallerRoot
$doc = $doc -Replace '\$\$NAME\$\$',$name
$doc = $doc -Replace '\$\$VERSION\$\$',$version
$doc = $doc -Replace '\$\$PACKAGE\$\$',$bundle.Name
$doc | Out-File -Encoding utf8NoBOM $OutputPath

Get-Item $OutputPath

0 comments on commit 86ad3c8

Please sign in to comment.