Skip to content

Release Package

Release Package #30

name: Release Package
on:
workflow_dispatch:
inputs:
run_id:
description: workflow run id
default: latest
required: true
rev_id:
description: build revision id
default: '0'
required: true
skip-publish:
description: Skip publishing
required: true
type: boolean
default: false
dry-run:
description: Dry run (simulate)
required: true
type: boolean
default: true
jobs:
preflight:
name: preflight
runs-on: ubuntu-22.04
outputs:
package-env: ${{ steps.info.outputs.package-env }}
dry-run: ${{ steps.info.outputs.dry-run }}
steps:
- name: Package information
id: info
shell: pwsh
run: |
$IsMasterBranch = ('${{ github.ref_name }}' -eq 'master')
$DryRun = [System.Boolean]::Parse('${{ inputs.dry-run }}')
$PackageEnv = if ($IsMasterBranch) {
"publish-prod"
} else {
"publish-test"
}
if (-Not $IsMasterBranch) {
$DryRun = $true # force dry run when not on master branch
}
echo "package-env=$PackageEnv" >> $Env:GITHUB_OUTPUT
echo "dry-run=$($DryRun.ToString().ToLower())" >> $Env:GITHUB_OUTPUT
echo "::notice::DryRun: $DryRun"
package:
name: Build packages
runs-on: windows-2022
needs: preflight
environment: ${{ needs.preflight.outputs.package-env }}
steps:
- name: Clone project
uses: actions/checkout@v3
- name: Install code signing tools
run: |
dotnet tool install --global AzureSignTool
dotnet tool install --global NuGetKeyVaultSignTool
# trust test code signing CA
$TestCertsUrl = "https://raw.githubusercontent.com/Devolutions/devolutions-authenticode/master/data/certs"
Invoke-WebRequest -Uri "$TestCertsUrl/authenticode-test-ca.crt" -OutFile ".\authenticode-test-ca.crt"
Import-Certificate -FilePath ".\authenticode-test-ca.crt" -CertStoreLocation "cert:\LocalMachine\Root"
Remove-Item ".\authenticode-test-ca.crt" -ErrorAction SilentlyContinue | Out-Null
- name: Download Windows Terminal
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
run: |
$RunId = '${{ inputs.run_id }}'
if ($RunId -eq 'latest') {
$RunId = $(gh run list -w 'Windows Terminal' --json 'status,databaseId,conclusion') |
ConvertFrom-Json | Where-Object { ($_.status -eq 'completed') -and ($_.conclusion -eq 'success') } |
Select-Object -First 1 -ExpandProperty databaseId
}
Write-Host "Downloading run $RunId"
& gh run download $RunId
Get-ChildItem */*.zip | ForEach-Object {
if ($_.BaseName -Match "WindowsTerminal-(\d+.\d+.\d+.\d+)-(.*)") {
$Version = $Matches[1]
$Architecture = $Matches[2]
$Destination = "runtimes/win-${Architecture}/native/wt"
New-Item $Destination -ItemType Directory -Force | Out-Null
Expand-Archive $_.FullName $Destination
Remove-Item $_.FullName
Remove-Item $_.Directory -ErrorAction SilentlyContinue
}
}
$RevId = '${{ inputs.rev_id }}'
$Version -Replace "(\d+).(\d+).(\d+).(\d+)", "`$1.`$2.`$3.$RevId"
New-Item .\package -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
Set-Content -Path .\VERSION -Value $Version -NoNewLine -Force
Set-Content -Path .\package\VERSION -Value $Version -NoNewLine -Force
- name: Code sign Windows Terminal
shell: pwsh
run: |
$Params = @('sign',
'-kvt', '${{ secrets.AZURE_TENANT_ID }}',
'-kvu', '${{ secrets.CODE_SIGNING_KEYVAULT_URL }}',
'-kvi', '${{ secrets.CODE_SIGNING_CLIENT_ID }}',
'-kvs', '${{ secrets.CODE_SIGNING_CLIENT_SECRET }}',
'-kvc', '${{ secrets.CODE_SIGNING_CERTIFICATE_NAME }}',
'-tr', '${{ vars.CODE_SIGNING_TIMESTAMP_SERVER }}',
'-v')
foreach ($Architecture in @('x64', 'arm64')) {
$WtDir = "runtimes/win-${Architecture}/native/wt"
Get-ChildItem -Path "$WtDir/*" -Include @("*.exe","*.dll") -Exclude @("*.Xaml*.dll") | ForEach-Object {
AzureSignTool @Params $_.FullName
}
}
- name: Build zip package
shell: pwsh
run: |
$Version = Get-Content -Path .\VERSION
Write-Host "Package Version: $Version"
New-Item -Path "./package" -ItemType Directory -Force | Out-Null
foreach ($Architecture in @('x64', 'arm64')) {
$WtDir = "runtimes/win-${Architecture}/native/wt"
$ZipFile = "WindowsTerminal-${Version}-${Architecture}.zip"
Compress-Archive -Path "$WtDir/*" -CompressionLevel Optimal -DestinationPath "./package/${ZipFile}"
}
- name: Code sign zip package
shell: pwsh
run: |
$Params = @('sign',
'-kvt', '${{ secrets.AZURE_TENANT_ID }}',
'-kvu', '${{ secrets.CODE_SIGNING_KEYVAULT_URL }}',
'-kvi', '${{ secrets.CODE_SIGNING_CLIENT_ID }}',
'-kvs', '${{ secrets.CODE_SIGNING_CLIENT_SECRET }}',
'-kvc', '${{ secrets.CODE_SIGNING_CERTIFICATE_NAME }}',
'-tr', '${{ vars.CODE_SIGNING_TIMESTAMP_SERVER }}',
'-v')
Install-Module -Name Devolutions.Authenticode -Force
Get-ChildItem -Path "./package/*.zip" | ForEach-Object {
$ZipFile = $_.FullName
Get-ZipAuthenticodeDigest $ZipFile -Export
AzureSignTool @Params "${ZipFile}.sig.ps1"
Import-ZipAuthenticodeSignature $ZipFile -Remove
}
- name: Build nuget package
shell: pwsh
run: |
$Version = Get-Content -Path .\VERSION
Write-Host "Package Version: $Version"
dotnet pack .\dotnet\Devolutions.WindowsTerminal -c Release -o package /p:Version=$Version
- name: Code sign nuget package
shell: pwsh
run: |
$NugetPackage = (Get-Item ".\package\*.nupkg" | Select-Object -First 1) | Resolve-Path -Relative
$Params = @('sign', $NugetPackage,
'-kvt', '${{ secrets.AZURE_TENANT_ID }}',
'-kvu', '${{ secrets.CODE_SIGNING_KEYVAULT_URL }}',
'-kvi', '${{ secrets.CODE_SIGNING_CLIENT_ID }}',
'-kvs', '${{ secrets.CODE_SIGNING_CLIENT_SECRET }}',
'-kvc', '${{ secrets.CODE_SIGNING_CERTIFICATE_NAME }}',
'-tr', '${{ vars.CODE_SIGNING_TIMESTAMP_SERVER }}',
'-v')
& NuGetKeyVaultSignTool @Params
- name: Build MSI package
shell: pwsh
run: |
$Version = Get-Content -Path .\VERSION
Write-Host "Package Version: $Version"
dotnet tool install --global wix --version 4.0.2
$WixVariables = Get-Content .\installer\Variables.wxi
$WixVariables = $WixVariables -Replace 'ProductVersion = "([^"]*)"', "ProductVersion = `"$Version`""
Set-Content .\installer\Variables.wxi $WixVariables
foreach ($Architecture in @('x64', 'arm64')) {
dotnet build /p:Configuration=Release /p:Platform=${Architecture} installer/WindowsTerminal.sln
Move-Item ./installer/bin/${Architecture}/Release/en-US/WindowsTerminal.msi ./package/WindowsTerminal-${Version}-${Architecture}.msi
}
- name: Code sign MSI package
shell: pwsh
run: |
$Params = @('sign',
'-kvt', '${{ secrets.AZURE_TENANT_ID }}',
'-kvu', '${{ secrets.CODE_SIGNING_KEYVAULT_URL }}',
'-kvi', '${{ secrets.CODE_SIGNING_CLIENT_ID }}',
'-kvs', '${{ secrets.CODE_SIGNING_CLIENT_SECRET }}',
'-kvc', '${{ secrets.CODE_SIGNING_CERTIFICATE_NAME }}',
'-tr', '${{ vars.CODE_SIGNING_TIMESTAMP_SERVER }}',
'-v')
Get-ChildItem .\package\*.msi | ForEach-Object {
AzureSignTool @Params $_.FullName
}
- name: Upload packages
uses: actions/upload-artifact@v3
with:
name: wt-release
path: package/*
publish:
name: Publish packages
runs-on: ubuntu-22.04
environment: publish
needs: [preflight, package]
if: ${{ fromJSON(inputs.skip-publish) == false }}
steps:
- name: Download packages
uses: actions/download-artifact@v3
with:
name: wt-release
path: package
- name: Publish to nuget.org
shell: pwsh
run: |
$DryRun = [System.Boolean]::Parse('${{ needs.preflight.outputs.dry-run }}')
$NugetPackage = (Get-Item ./package/*.nupkg) | Resolve-Path -Relative
$PushArgs = @(
'nuget', 'push', "$NugetPackage",
'--api-key', '${{ secrets.NUGET_API_KEY }}',
'--source', 'https://api.nuget.org/v3/index.json',
'--skip-duplicate', '--no-symbols'
)
Write-Host "dotnet $($PushArgs -Join ' ')"
if ($DryRun) {
Write-Host "Dry Run: skipping nuget.org publishing!"
} else {
& 'dotnet' $PushArgs
}
- name: Create GitHub Release
shell: pwsh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
working-directory: package
run: |
$DryRun = [System.Boolean]::Parse('${{ needs.preflight.outputs.dry-run }}')
$Version = Get-Content -Path .\VERSION
Remove-Item .\VERSION | Out-Null
$HashPath = 'checksums'
$Files = Get-Item * -Exclude ('VERSION','CHANGELOG.md') | % { Get-FileHash -Algorithm SHA256 $_.FullName }
$Files | % { "$($_.Hash) $(Split-Path $_.Path -Leaf)" } | Out-File -FilePath $HashPath -Append -Encoding ASCII
echo "::group::checksums"
Get-Content $HashPath
echo "::endgroup::"
$ReleaseTag = "v$Version"
$Repository = $Env:GITHUB_REPOSITORY
$ReleaseTitle = "Devolutions Windows Terminal v${Version}"
if ($DryRun) {
Write-Host "Dry Run: skipping GitHub release!"
} else {
& gh release create $ReleaseTag --repo $Repository --title $ReleaseTitle --draft ./*
}