Release Package #36
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
sign-nuget: | |
description: Sign nuget package | |
required: true | |
type: boolean | |
default: false | |
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","*.winmd") -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 | |
if: ${{ fromJSON(inputs.sign-nuget) == true }} | |
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 | |
needs: [preflight, package] | |
environment: ${{ needs.preflight.outputs.package-env }} | |
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 ./* | |
} |