Skip to content

UI: implement Windows 11 Mica background effect #76

UI: implement Windows 11 Mica background effect

UI: implement Windows 11 Mica background effect #76

name: Build QuickRotate
on:
push:
branches:
- main
paths:
- 'version.h'
- 'QuickRotate.cpp'
- 'QuickRotate.rc'
- 'assets/icon.ico'
workflow_dispatch:
inputs:
make_release:
description: 'Create a Release?'
required: true
type: boolean
default: false
permissions:
contents: write
jobs:
build-and-release:
runs-on: windows-latest
steps:
- name: Checkout Code
uses: actions/checkout@v7
- name: Set up MSYS2
uses: msys2/setup-msys2@v2
with:
msystem: MINGW32
install: mingw-w64-i686-gcc
update: true
- name: Compile Resources & Executables
shell: msys2 {0}
run: |
windres QuickRotate.rc -O coff -o QuickRotate_res.o
g++ QuickRotate.cpp QuickRotate_res.o -o QuickRotate.exe -static -nostartfiles -e _WinMain@16 -Os -s -fno-exceptions -fno-rtti -fno-stack-protector -fomit-frame-pointer "-Wl,--gc-sections" -lgdi32 -luser32 -lgdiplus -lshell32 -lole32 -luuid -ladvapi32 -mwindows
windres -DLITE QuickRotate.rc -O coff -o QuickRotate_lite_res.o
g++ -DLITE QuickRotate.cpp QuickRotate_lite_res.o -o QuickRotate_L.exe -static -nostartfiles -e _WinMain@16 -Os -s -fno-exceptions -fno-rtti -fno-stack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fomit-frame-pointer "-Wl,--gc-sections" -lgdi32 -luser32 -lgdiplus -lshell32 -lole32 -luuid -ladvapi32 -mwindows
- name: Compress Lite Build with UPX
shell: pwsh
run: |
choco install upx --no-progress
upx --best --lzma -o QuickRotate_Lite.exe QuickRotate_L.exe
Remove-Item QuickRotate_L.exe -Force
- name: Restore Signing Certificate
shell: pwsh
env:
CERT_BASE64: ${{ secrets.SIGNING_CERT }}
run: |
$certBytes = [System.Convert]::FromBase64String($env:CERT_BASE64)
[System.IO.File]::WriteAllBytes("certificate.pfx", $certBytes)
- name: Sign QuickRotate (Full Build Only)
shell: pwsh
env:
CERT_PASS: ${{ secrets.SIGNING_PASS }}
run: |
$signtool = Get-ChildItem -Path "C:\Program Files (x86)\Windows Kits" -Recurse -Filter "signtool.exe" | Select-Object -First 1
if (-not $signtool) { Write-Error "Signtool not found!"; exit 1 }
& $signtool.FullName sign /f "certificate.pfx" /p "$env:CERT_PASS" /fd SHA256 /d "Quick Rotate by ArKT-7" /du "https://github.com/ArKT-7" /tr http://timestamp.digicert.com /td sha256 "QuickRotate.exe"
Remove-Item "certificate.pfx" -Force
- name: VirusTotal Scan
id: vt
uses: crazy-max/ghaction-virustotal@v5
with:
vt_api_key: ${{ secrets.VT_API_KEY }}
files: |
QuickRotate.exe
QuickRotate_Lite.exe
- name: Get Version & Date
id: info
shell: pwsh
run: |
$verLine = Get-Content version.h | Select-String "VERSION_STR" | Select-Object -First 1
$version = $verLine.ToString().Split('"')[1]
echo "APP_VERSION=$version" >> $env:GITHUB_ENV
$date = (Get-Date).ToUniversalTime().ToString("d MMMM yyyy")
$time = (Get-Date).ToUniversalTime().ToString("HH:mm 'UTC'")
echo "BUILD_DATE=$date" >> $env:GITHUB_ENV
echo "BUILD_TIME=$time" >> $env:GITHUB_ENV
- name: Upload Build Artifacts
uses: actions/upload-artifact@v7
with:
name: QuickRotate-${{ env.APP_VERSION }}
path: |
QuickRotate.exe
QuickRotate_Lite.exe
retention-days: 7
- name: Generate Release Notes
if: (github.event_name == 'push' && contains(github.event.head_commit.message, '[release]')) || (github.event_name == 'workflow_dispatch' && inputs.make_release == true)
shell: pwsh
run: |
$repo = "${{ github.repository }}"
$ver = "${{ env.APP_VERSION }}"
$file_full = "QuickRotate.exe"
$file_lite = "QuickRotate_Lite.exe"
$sizeBytes = (Get-Item $file_full).Length
$sizeKB = "{0:N2} KB" -f ($sizeBytes / 1KB)
$sizeBytes_lite = (Get-Item $file_lite).Length
$sizeKB_lite = "{0:N2} KB" -f ($sizeBytes_lite / 1KB)
$md5_full = (Get-FileHash $file_full -Algorithm MD5).Hash
$sha1_full = (Get-FileHash $file_full -Algorithm SHA1).Hash
$sha256_full = (Get-FileHash $file_full -Algorithm SHA256).Hash
$md5_lite = (Get-FileHash $file_lite -Algorithm MD5).Hash
$sha1_lite = (Get-FileHash $file_lite -Algorithm SHA1).Hash
$sha256_lite = (Get-FileHash $file_lite -Algorithm SHA256).Hash
$raw_vt = "${{ steps.vt.outputs.analysis }}"
$vt_parts = $raw_vt -split ','
$vt_url_full = $vt_parts[0]
if ($vt_url_full.Contains('=')) { $vt_url_full = $vt_url_full.Substring($vt_url_full.IndexOf('=') + 1) }
$vt_url_lite = $vt_parts[1]
if ($vt_url_lite.Contains('=')) { $vt_url_lite = $vt_url_lite.Substring($vt_url_lite.IndexOf('=') + 1) }
$body = @"
# <sub>[<img src="./assets/icon.png" width="40" height="40">](https://github.com/$repo/releases/latest)</sub> Quick Rotate v$ver
---
- **Build Date:** ``${{ env.BUILD_DATE }}``
- **Build Time:** ``${{ env.BUILD_TIME }}``
- **File Size:** ``$sizeKB``
- **VirusTotal:** [``Security Report``]($vt_url_full)
---
### 📥 Install & Update Options
* **Direct Download (Latest) ⚡**
<a href="https://github.com/$repo/releases/download/v$ver/$file_full"><img alt="Direct Download .exe" width="200px" src="https://github.com/$repo/blob/main/assets/github-button.svg?raw=true" /></a>
> [!IMPORTANT]
> **Heads up:** It takes a little while for the **``Microsoft Store``** and **``WinGet``** to review and publish new updates. If you don't want to wait, grab the **``Direct Download``** above to get it right now! 😉
* **Microsoft Store**<br>
<a href="https://aka.ms/AA132927"><img alt="Get it from Microsoft" width="200" src="https://get.microsoft.com/images/en-us%20dark.svg" /></a>
* **WinGet CLI**
``````powershell
winget install QuickRotate # Install
winget upgrade QuickRotate # Update
``````
---
### 🔒 Integrity Checksums — **``QuickRotate.exe``**
| Algorithm | Hash |
| :--- | :--- |
| **MD5** | ``$md5_full`` |
| **SHA-1** | ``$sha1_full`` |
| **SHA-256** | ``$sha256_full`` |
---
### 😙 The Lite Edition
> [!WARNING]
> **About the Lite Build:** To hit the smallest possible size, the ``Lite`` build is UPX-compressed and left unsigned. UPX compression is also commonly used by malware to hide its code, so many antivirus engines flag this file purely based on that pattern 😒, not because there's actually anything wrong with it. It's safe to use, although if you prefer having a signed exe with no warnings, you can download and use the **Full** build instead 😉
>
- **File Size:** ``$sizeKB_lite`` ⚡
- **VirusTotal:** [``Security Report``]($vt_url_lite)
#### 🔒 Integrity Checksums — **``QuickRotate_Lite.exe``**
| Algorithm | Hash |
| :--- | :--- |
| **MD5** | ``$md5_lite`` |
| **SHA-1** | ``$sha1_lite`` |
| **SHA-256** | ``$sha256_lite`` |
---
### [``📖 View Readme & Usage Guide 🙂‍↔️``](https://github.com/$repo/blob/main/README.md#-usage-guide)
---
"@
[System.IO.File]::WriteAllText("release_notes.md", $body)
- name: Create Release
if: (github.event_name == 'push' && contains(github.event.head_commit.message, '[release]')) || (github.event_name == 'workflow_dispatch' && inputs.make_release == true)
uses: softprops/action-gh-release@v3
with:
tag_name: v${{ env.APP_VERSION }}
name: Quick Rotate v${{ env.APP_VERSION }}
body_path: release_notes.md
files: |
QuickRotate.exe
QuickRotate_Lite.exe