work #15
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: Development build | |
| on: | |
| push: | |
| branches: | |
| - master | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: development-release | |
| cancel-in-progress: true | |
| jobs: | |
| build-test-publish: | |
| name: Build, test, and publish | |
| runs-on: windows-latest | |
| steps: | |
| - name: Check out source | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up .NET | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: 10.0.x | |
| - name: Restore | |
| run: dotnet restore src/WordSearchGenerator.sln --runtime win-x64 | |
| - name: Build | |
| run: dotnet build src/WordSearchGenerator.sln --configuration Release --no-restore | |
| - name: Test | |
| run: dotnet test src/WordSearchGenerator.sln --configuration Release --no-build --no-restore --filter "TestCategory!=LongRunning" | |
| - name: Publish Windows x64 application | |
| shell: pwsh | |
| run: | | |
| dotnet publish src/WordSearchGenerator.Desktop/WordSearchGenerator.Desktop.csproj ` | |
| --configuration Release ` | |
| --runtime win-x64 ` | |
| --self-contained true ` | |
| --no-restore ` | |
| -p:PublishSingleFile=false ` | |
| -p:DebugType=None ` | |
| -p:DebugSymbols=false ` | |
| --output artifacts/wose-win64 | |
| - name: Remove unused Chromium locales | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $publishDirectory = (Resolve-Path 'artifacts/wose-win64').Path | |
| $localeDirectory = (Resolve-Path ` | |
| (Join-Path $publishDirectory 'locales')).Path | |
| if ((Split-Path $localeDirectory -Parent) -ne $publishDirectory) { | |
| throw "Unexpected Chromium locale directory: $localeDirectory" | |
| } | |
| $retainedLocales = @('cs.pak', 'en-US.pak') | |
| foreach ($locale in $retainedLocales) { | |
| $localeFile = Join-Path $localeDirectory $locale | |
| if (-not (Test-Path -LiteralPath $localeFile -PathType Leaf)) { | |
| throw "Required Chromium locale was not published: $locale" | |
| } | |
| } | |
| $unusedLocales = Get-ChildItem -LiteralPath $localeDirectory -File | | |
| Where-Object { $_.Name -notin $retainedLocales } | |
| foreach ($locale in $unusedLocales) { | |
| Remove-Item -LiteralPath $locale.FullName | |
| } | |
| $remainingLocales = Get-ChildItem -LiteralPath $localeDirectory -File | |
| if ($remainingLocales.Count -ne $retainedLocales.Count) { | |
| throw 'Unexpected files remain in the Chromium locale directory.' | |
| } | |
| - name: Bundle Visual C++ runtime | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $vswhere = Join-Path ${env:ProgramFiles(x86)} ` | |
| 'Microsoft Visual Studio\Installer\vswhere.exe' | |
| if (-not (Test-Path -LiteralPath $vswhere)) { | |
| throw 'vswhere.exe was not found.' | |
| } | |
| $vsInstall = & $vswhere ` | |
| -latest ` | |
| -products * ` | |
| -requires Microsoft.VisualStudio.Component.VC.Redist.14.Latest ` | |
| -property installationPath | |
| if (-not $vsInstall) { | |
| throw 'Visual Studio installation was not found.' | |
| } | |
| $redistRoot = Join-Path $vsInstall 'VC\Redist\MSVC' | |
| if (-not (Test-Path -LiteralPath $redistRoot -PathType Container)) { | |
| throw "Visual C++ redistributable directory was not found: $redistRoot" | |
| } | |
| $redistVersion = Get-ChildItem -LiteralPath $redistRoot -Directory | | |
| Where-Object { $_.Name -match '^\d+(\.\d+)+$' } | | |
| Sort-Object { [version]$_.Name } -Descending | | |
| Select-Object -First 1 | |
| if (-not $redistVersion) { | |
| throw "No versioned Visual C++ redistributable directory was found in: $redistRoot" | |
| } | |
| $x64RedistRoot = Join-Path $redistVersion.FullName 'x64' | |
| $crtDirectory = Get-ChildItem -LiteralPath $x64RedistRoot -Directory | | |
| Where-Object { $_.Name -like 'Microsoft.VC*.CRT' } | | |
| Select-Object -First 1 | |
| if (-not $crtDirectory) { | |
| throw "The x64 Visual C++ runtime directory was not found in: $x64RedistRoot" | |
| } | |
| Copy-Item ` | |
| -Path (Join-Path $crtDirectory.FullName '*.dll') ` | |
| -Destination 'artifacts/wose-win64' ` | |
| -Force | |
| $requiredRuntimeFiles = @( | |
| 'msvcp140.dll', | |
| 'vcruntime140.dll', | |
| 'vcruntime140_1.dll' | |
| ) | |
| foreach ($file in $requiredRuntimeFiles) { | |
| $publishedFile = Join-Path 'artifacts/wose-win64' $file | |
| if (-not (Test-Path -LiteralPath $publishedFile -PathType Leaf)) { | |
| throw "Required Visual C++ runtime file was not bundled: $file" | |
| } | |
| } | |
| - name: Determine archive name | |
| id: package | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $archiveName = "wose-win64.zip" | |
| "archive_name=$archiveName" >> $env:GITHUB_OUTPUT | |
| - name: Create application archive | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| $archive = Join-Path ` | |
| $PWD ` | |
| 'artifacts/${{ steps.package.outputs.archive_name }}' | |
| Compress-Archive ` | |
| -Path (Join-Path $PWD 'artifacts/wose-win64/*') ` | |
| -DestinationPath $archive ` | |
| -CompressionLevel Optimal ` | |
| -Force | |
| - name: Move development tag | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| git config user.name 'github-actions[bot]' | |
| git config user.email '41898282+github-actions[bot]@users.noreply.github.com' | |
| git tag --force dev $env:GITHUB_SHA | |
| if ($LASTEXITCODE -ne 0) { | |
| throw 'Could not create the dev tag.' | |
| } | |
| git push origin refs/tags/dev --force | |
| if ($LASTEXITCODE -ne 0) { | |
| throw 'Could not update the remote dev tag.' | |
| } | |
| - name: Update development release | |
| shell: pwsh | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| gh release view dev --repo $env:GITHUB_REPOSITORY *> $null | |
| if ($LASTEXITCODE -eq 0) { | |
| gh release edit dev ` | |
| --repo $env:GITHUB_REPOSITORY ` | |
| --title 'Development build' ` | |
| --prerelease | |
| } | |
| else { | |
| gh release create dev ` | |
| --repo $env:GITHUB_REPOSITORY ` | |
| --title 'Development build' ` | |
| --prerelease ` | |
| --notes "Automated development build of commit $env:GITHUB_SHA." | |
| } | |
| if ($LASTEXITCODE -ne 0) { | |
| throw 'Could not create or update the development release.' | |
| } | |
| $archiveName = '${{ steps.package.outputs.archive_name }}' | |
| $oldAssets = @( | |
| gh release view dev ` | |
| --repo $env:GITHUB_REPOSITORY ` | |
| --json assets ` | |
| --jq '.assets[].name' | |
| ) | |
| if ($LASTEXITCODE -ne 0) { | |
| throw 'Could not list existing development release assets.' | |
| } | |
| $oldArchives = $oldAssets | Where-Object { | |
| $_ -eq 'wosecon-win64.zip' -or | |
| $_ -match '^wosecon-[0-9a-f]+-win64\.zip$' -or | |
| $_ -eq 'wose-win64.zip' -or | |
| $_ -match '^wose-[0-9a-f]+-win64\.zip$' | |
| } | |
| foreach ($oldArchive in $oldArchives) { | |
| gh release delete-asset dev $oldArchive ` | |
| --repo $env:GITHUB_REPOSITORY ` | |
| --yes | |
| if ($LASTEXITCODE -ne 0) { | |
| throw "Could not delete old development archive: $oldArchive" | |
| } | |
| } | |
| $archiveAsset = "artifacts/$archiveName#$archiveName" | |
| gh release upload dev ` | |
| $archiveAsset ` | |
| --repo $env:GITHUB_REPOSITORY ` | |
| --clobber | |
| if ($LASTEXITCODE -ne 0) { | |
| throw 'Could not upload the development archive.' | |
| } |