3.0.8 #15
Workflow file for this run
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: Update doc images | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| packages: read | |
| concurrency: | |
| group: update-release-images | |
| cancel-in-progress: true | |
| jobs: | |
| update-main-window-screenshot: | |
| name: Update Main Window Screenshot | |
| runs-on: windows-latest | |
| defaults: | |
| run: | |
| shell: pwsh | |
| steps: | |
| - name: checkout-repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| ref: main | |
| token: ${{ secrets.PAT_TOKEN }} | |
| - name: Set Variables | |
| id: set_vars | |
| run: | | |
| $TAG = "${{ github.event.release.tag_name }}" | |
| $TAG_CLEAN = $TAG -replace '^v' | |
| echo "TAG_CLEAN=$TAG_CLEAN" >> $env:GITHUB_OUTPUT | |
| echo "TAG=$TAG" >> $env:GITHUB_OUTPUT | |
| - name: Download signed EXE from release | |
| id: download-exe | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| $TAG = "${{ steps.set_vars.outputs.TAG }}" | |
| gh release download $TAG --pattern "WinMemoryCleaner.exe" | |
| if (-not (Test-Path ".\WinMemoryCleaner.exe")) { | |
| Write-Host "::error::Failed to download WinMemoryCleaner.exe from release $TAG" | |
| exit 1 | |
| } | |
| Write-Host "Downloaded signed WinMemoryCleaner.exe" | |
| - name: Capture window screenshot from SIGNED exe | |
| id: capture_screenshot | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $appPath = ".\WinMemoryCleaner.exe" | |
| $windowScreenshotPath = "main-window-raw.png" | |
| $proc = Start-Process -FilePath $appPath -PassThru | |
| $maxWaitMs = 30000; $elapsed = | |
| while ($proc.MainWindowHandle -eq 0 -and $elapsed -lt $maxWaitMs) { | |
| Start-Sleep -Milliseconds 200; $proc.Refresh(); $elapsed += 200 | |
| } | |
| if ($proc.MainWindowHandle -eq 0) { | |
| Write-Host "::error::Main window not found for signed EXE." | |
| Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue | |
| exit 1 | |
| } | |
| Add-Type -AssemblyName System.Drawing | |
| $sig = 'using System; using System.Runtime.InteropServices; public static class Win32 { [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect); [DllImport("user32.dll")] public static extern bool SetForegroundWindow(IntPtr hWnd); }' | |
| Add-Type -TypeDefinition $sig -Language CSharp | |
| [void][Win32]::SetForegroundWindow([IntPtr]$proc.MainWindowHandle) | |
| $rect = New-Object Win32+RECT | |
| if (-not [Win32]::GetWindowRect([IntPtr]$proc.MainWindowHandle, [ref]$rect)) { | |
| Write-Host "::error::GetWindowRect failed." | |
| Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue; exit 1 | |
| } | |
| $width = $rect.Right - $rect.Left; $height = $rect.Bottom - $rect.Top | |
| if ($width -le 0 -or $height -le 0) { | |
| Write-Host "::error::Invalid window size: $($width)x$($height)" | |
| Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue; exit 1 | |
| } | |
| $wbmp = New-Object System.Drawing.Bitmap $width, $height | |
| $wgfx = [System.Drawing.Graphics]::FromImage($wbmp) | |
| $wgfx.CopyFromScreen($rect.Left, $rect.Top, 0, 0, (New-Object System.Drawing.Size($width, $height))) | |
| $wbmp.Save($windowScreenshotPath, [System.Drawing.Imaging.ImageFormat]::Png) | |
| $wgfx.Dispose(); $wbmp.Dispose() | |
| Stop-Process -Id $proc.Id -Force | |
| - name: check-screenshot-exists | |
| id: check-screenshot | |
| run: | | |
| if (Test-Path -Path "main-window-raw.png" -PathType Leaf) { | |
| echo "screenshot_exists=true" >> $env:GITHUB_OUTPUT | |
| } else { | |
| Write-Host "::error::Screenshot was not created." | |
| echo "screenshot_exists=false" >> $env:GITHUB_OUTPUT | |
| exit 1 | |
| } | |
| - name: install-imagemagick | |
| if: steps.check-screenshot.outputs.screenshot_exists == 'true' | |
| run: choco install imagemagick | |
| - name: process-screenshot-image | |
| if: steps.check-screenshot.outputs.screenshot_exists == 'true' | |
| run: | | |
| $ErrorActionPreference = "Stop" | |
| $DOC_DIR = "docs/assets/images" | |
| $RAW_FILE = "main-window-raw.png" | |
| $OUT_FILE = "$DOC_DIR/main-window.png" | |
| New-Item -ItemType Directory -Path $DOC_DIR -Force | Out-Null | |
| try { | |
| $imageInfo = magick identify -format "%w %h" $RAW_FILE | |
| if (-not $imageInfo) { | |
| Write-Host "::error::Failed to read image $RAW_FILE with ImageMagick (magick identify)." | |
| exit 1 | |
| } | |
| } catch { | |
| Write-Host "::error::Failed to read image $RAW_FILE with ImageMagick." | |
| Write-Host $_.Exception.Message | |
| exit 1 | |
| } | |
| $parts = $imageInfo -split " " | |
| $W = [int]$parts[0] | |
| $H = [int]$parts[1] | |
| if ($W -le 0 -or $H -le 0) { | |
| Write-Host "::error::Failed to get image size for $RAW_FILE" | |
| exit 1 | |
| } | |
| if ($W -lt $H) { $MIN = $W } else { $MIN = $H } | |
| $R = [int]($MIN / 50) | |
| if ($R -lt 10) { $R = 10 } | |
| if ($R -gt 24) { $R = 24 } | |
| $W_1 = $W - 1 | |
| $H_1 = $H - 1 | |
| magick convert "$RAW_FILE" ` | |
| "(" -size "${W}x${H}" xc:none -fill white -draw "roundrectangle 0,0,$W_1,$H_1,$R,$R" ")" ` | |
| -compose DstIn -composite ` | |
| $OUT_FILE | |
| if (-not (Test-Path $OUT_FILE -PathType Leaf) -or (Get-Item $OUT_FILE).Length -eq 0) { | |
| Write-Host "::error::Image processing failed and output file was not created." | |
| exit 1 | |
| } | |
| - name: Update index.html with Cache Buster | |
| if: steps.check-screenshot.outputs.screenshot_exists == 'true' | |
| run: | | |
| $NewVersion = "${{ steps.set_vars.outputs.TAG_CLEAN }}" | |
| $FilePath = "docs/index.html" | |
| if (-not (Test-Path $FilePath)) { | |
| Write-Host "::error::index.html not found at path $FilePath" | |
| exit 1 | |
| } | |
| (Get-Content $FilePath) | | |
| ForEach-Object { | |
| $_ -replace 'src="./assets/images/main-window.png(\?v=.*)?"', "src=`"./assets/images/main-window.png?v=$NewVersion`"" | |
| } | Set-Content $FilePath -Encoding UTF8 | |
| - name: create-pull-request | |
| id: cpr | |
| if: steps.check-screenshot.outputs.screenshot_exists == 'true' | |
| uses: peter-evans/create-pull-request@v6 | |
| with: | |
| token: ${{ secrets.PAT_TOKEN }} | |
| commit-message: "chore(docs): update main window screenshot and cache buster" | |
| title: "Docs: Update Assets for Release ${{ steps.set_vars.outputs.TAG }}" | |
| body: | | |
| This is an automated PR to update the main window screenshot and the cache-busting parameter in index.html for release **${{ steps.set_vars.outputs.TAG }}**. | |
| It will be automatically merged once all status checks pass. | |
| branch: "docs/main-window-update-${{ github.run_id }}" | |
| base: main | |
| delete-branch: true | |
| add-paths: | | |
| docs/assets/images/main-window.png | |
| docs/index.html | |
| committer: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | |
| author: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | |
| - name: auto-merge-pull-request | |
| if: steps.check-screenshot.outputs.screenshot_exists == 'true' && steps.cpr.outputs.pull-request-number != '' | |
| env: | |
| GH_TOKEN: ${{ secrets.PAT_TOKEN }} | |
| run: | | |
| $PR_NUMBER = "${{ steps.cpr.outputs.pull-request-number }}" | |
| gh pr merge $PR_NUMBER --squash --auto --delete-branch |