build package #83
This file contains hidden or 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: build package | |
on: | |
workflow_dispatch: | |
inputs: | |
version: | |
description: 'release version' | |
default: "latest" | |
required: true | |
target-package: | |
type: choice | |
description: target package to build | |
required: true | |
options: | |
- all | |
- MacOS | |
- DevExpress | |
- Linux | |
skip-publish: | |
description: 'Skip publishing' | |
required: true | |
type: boolean | |
default: false | |
dry-run: | |
description: 'Dry run (simulate)' | |
required: true | |
type: boolean | |
default: true | |
schedule: | |
- cron: '32 5 * * 1' # 05:32 AM UTC every Monday | |
jobs: | |
preflight: | |
name: Preflight | |
runs-on: ubuntu-22.04 | |
outputs: | |
package-env: ${{ steps.info.outputs.package-env }} | |
package-version: ${{ steps.info.outputs.package-version }} | |
package-list: ${{ steps.info.outputs.package-list }} | |
skip-publish: ${{ steps.info.outputs.skip-publish }} | |
dry-run: ${{ steps.info.outputs.dry-run }} | |
steps: | |
- name: Package information | |
id: info | |
shell: pwsh | |
run: | | |
$IsMasterBranch = ('${{ github.ref_name }}' -eq 'master') | |
$IsScheduledJob = ('${{ github.event_name }}' -eq 'schedule') | |
try { $SkipPublish = [System.Boolean]::Parse('${{ inputs.skip-publish }}') } catch { $SkipPublish = $false } | |
try { $DryRun = [System.Boolean]::Parse('${{ inputs.dry-run }}') } catch { $DryRun = $true } | |
$PackageEnv = if ($IsMasterBranch -And -Not $IsScheduledJob) { | |
"publish-prod" | |
} else { | |
"publish-test" | |
} | |
if ((-Not $IsMasterBranch) -or $IsScheduledJob) { | |
$DryRun = $true # force dry run | |
} | |
$PackageVersion = '${{ inputs.version }}' | |
if ([string]::IsNullOrEmpty($PackageVersion) -or $PackageVersion -eq 'latest') { | |
$PackageVersion = (Get-Date -Format "yyyy.MM.dd") + ".0" | |
} | |
if ($PackageVersion -NotMatch '^\d+\.\d+\.\d+\.\d+$') { | |
throw "invalid version format: $PackageVersion, expected: 1.2.3.4" | |
} | |
$TargetPackage = '${{ inputs.target-package }}' | |
if ([string]::IsNullOrEmpty($TargetPackage) -or $TargetPackage -eq 'all') { | |
$PackageList = "MacOS,DevExpress,Linux" | |
} else { | |
$PackageList = $TargetPackage | |
} | |
echo "package-env=$PackageEnv" >> $Env:GITHUB_OUTPUT | |
echo "package-version=$PackageVersion" >> $Env:GITHUB_OUTPUT | |
echo "package-list=$PackageList" >> $Env:GITHUB_OUTPUT | |
echo "skip-publish=$($SkipPublish.ToString().ToLower())" >> $Env:GITHUB_OUTPUT | |
echo "dry-run=$($DryRun.ToString().ToLower())" >> $Env:GITHUB_OUTPUT | |
echo "::notice::Version: $PackageVersion" | |
echo "::notice::DryRun: $DryRun" | |
build-nuget: | |
name: Build nuget | |
runs-on: windows-2022 | |
needs: [preflight] | |
environment: ${{ needs.preflight.outputs.package-env }} | |
steps: | |
- name: Check out ${{ github.repository }} | |
uses: actions/checkout@v4 | |
- name: Configure runner | |
shell: pwsh | |
run: | | |
New-Item .\package -ItemType Directory -ErrorAction SilentlyContinue | Out-Null | |
- name: Install code signing tools | |
run: | | |
dotnet tool install --global AzureSignTool | |
# 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: Set package version | |
shell: pwsh | |
run: | | |
$PackageVersion = '${{ needs.preflight.outputs.package-version }}' | |
$PackageList = '${{ needs.preflight.outputs.package-list }}' | |
$ProjectDirs = @($PackageList -Split ',' | ForEach-Object { ".\src\Devolutions.AvaloniaTheme.$_" }) | |
foreach ($ProjectDir in $ProjectDirs) { | |
$csprojPath = (Get-Item "$ProjectDir\*.csproj" | Select-Object -First 1).FullName | |
$csprojContent = Get-Content $csprojPath -Raw | |
$csprojContent = $csprojContent -Replace '(<Version>).*?(</Version>)', "<Version>$PackageVersion</Version>" | |
Set-Content -Path $csprojPath -Value $csprojContent -Encoding UTF8 | |
} | |
- name: Build nuget packages | |
shell: pwsh | |
run: | | |
$PackageList = '${{ needs.preflight.outputs.package-list }}' | |
$ProjectDirs = @($PackageList -Split ',' | ForEach-Object { ".\src\Devolutions.AvaloniaTheme.$_" }) | |
foreach ($ProjectDir in $ProjectDirs) { | |
& dotnet pack $ProjectDir -o package | |
} | |
- name: Code sign nuget contents | |
shell: pwsh | |
run: | | |
$NugetPackages = Get-Item ./package/*.nupkg | |
foreach ($Package in $NugetPackages) { | |
$NugetBaseName = $Package.BaseName | |
$PackedFile = $Package.FullName | |
$UnpackedDir = "./package/${NugetBaseName}" | |
$OutputDirectory = $Package.Directory.FullName | |
Expand-Archive -Path $PackedFile -Destination $UnpackedDir -Force | |
$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 "$UnpackedDir\lib" -Include @("*.dll") -Recurse | ForEach-Object { | |
AzureSignTool @Params $_.FullName | |
} | |
Remove-Item $PackedFile -ErrorAction SilentlyContinue | Out-Null | |
Compress-Archive -Path "$UnpackedDir\*" -Destination $PackedFile -CompressionLevel Optimal | |
} | |
- name: Upload nuget packages | |
uses: actions/[email protected] | |
with: | |
name: package-nupkg | |
path: package/*.nupkg | |
publish: | |
name: Publish packages | |
runs-on: ubuntu-22.04 | |
needs: [preflight, build-nuget] | |
environment: ${{ needs.preflight.outputs.package-env }} | |
if: ${{ fromJSON(needs.preflight.outputs.skip-publish) == false }} | |
steps: | |
- name: Download nuget package | |
uses: actions/download-artifact@v4 | |
with: | |
name: package-nupkg | |
path: package | |
- name: Publish to nuget.org | |
shell: pwsh | |
run: | | |
$DryRun = [System.Boolean]::Parse('${{ needs.preflight.outputs.dry-run }}') | |
$NugetPackages = (Get-Item ./package/*.nupkg) | Resolve-Path -Relative | |
foreach ($NugetPackage in $NugetPackages) { | |
$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 | |
} | |
} |