Skip to content

fix(macOS): Restore UI tuning throttle to 3000ms #833

fix(macOS): Restore UI tuning throttle to 3000ms

fix(macOS): Restore UI tuning throttle to 3000ms #833

Workflow file for this run

name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
release:
types: [published, released]
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
permissions:
contents: write # Needed for softprops/action-gh-release
jobs:
validate:
name: Lint & Test
strategy:
matrix:
os: [windows-latest, macos-latest]
runs-on: ${{ matrix.os }}
if: github.event_name == 'pull_request' || github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4 # Use latest checkout action
- name: Set up Go
uses: actions/setup-go@v5 # Use latest setup-go action
with:
go-version: '1.25.x'
cache: true
- name: Install Windows Dependencies
if: runner.os == 'Windows'
run: |
choco install mingw -y --no-progress
choco install make -y --no-progress
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
timeout-minutes: 10
with:
version: v1.64.6
args: --out-format=colored-line-number --timeout=10m ./...
install-mode: goinstall # Build from source using Go 1.25 to prevent version panic
env:
GOGC: 100
CGO_ENABLED: 1
- name: Run tests
run: go test ./...
- name: Check i18n integrity
run: make check-i18n
- name: Dry Run Build (No Secrets)
if: runner.os == 'Windows'
run: make build-win-amd64
- name: Dry Run macOS App Build
if: runner.os == 'macOS'
run: |
brew install create-dmg
go install fyne.io/tools/cmd/fyne@latest
SKIP_EXTENSION_BUILD=1 make build-extension
SKIP_EXTENSION_BUILD=1 make build-darwin-arm64
build-win:
name: Build Windows
runs-on: windows-latest
if: github.event.action == 'published'
env:
GOOGLE_PHOTOS_CLIENT_ID: ${{ secrets.GOOGLE_PHOTOS_CLIENT_ID }}
GOOGLE_PHOTOS_CLIENT_SECRET: ${{ secrets.GOOGLE_PHOTOS_CLIENT_SECRET }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.x'
cache: true
- name: Install Dependencies
run: |
choco install mingw -y --no-progress
choco install make -y --no-progress
- name: Update version.txt
run: |
echo "${{ github.event.release.tag_name }}" | Out-File -Encoding UTF8 version.txt
shell: pwsh
- name: Build Application
run: make build-win-amd64
- name: Sign Inner Executable
uses: azure/artifact-signing-action@v1.2.0
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: https://weu.codesigning.azure.net/
signing-account-name: SpiceOSS
certificate-profile-name: Spice
files: |
${{ github.workspace }}\bin\Spice.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Build MSIX Package
run: make build-msix
- name: Build Setup
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
with:
path: Spice.iss
options: /Q /DMyAppPlatform=amd64
- name: Pack Extensions (Chrome/Firefox)
run: make pack-extension
- name: Upload to Microsoft Store
# Uncomment and configure the secrets in your repository to enable automatic MS Store submission.
run: echo "Microsoft Store upload is currently disabled. See ci.yml to configure."
# env:
# TENANT_ID: ${{ secrets.MS_STORE_TENANT_ID }}
# CLIENT_ID: ${{ secrets.MS_STORE_CLIENT_ID }}
# CLIENT_SECRET: ${{ secrets.MS_STORE_CLIENT_SECRET }}
# SELLER_ID: ${{ secrets.MS_STORE_SELLER_ID }}
# run: make upload-ms-store
- name: Upload Windows Artifacts
uses: actions/upload-artifact@v4
with:
name: spice-win-artifacts
path: |
bin/
dist/
build-mac:
name: Build macOS
runs-on: macos-latest
if: github.event.action == 'published'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.3'
- name: Install Dependencies
run: |
brew install create-dmg
go install fyne.io/tools/cmd/fyne@latest
- name: Update version.txt
run: echo "${{ github.event.release.tag_name }}" > version.txt
- name: Import Apple Certificates
run: |
echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 --decode > certificate.p12
if [ -n "${{ secrets.MAC_APP_CERTIFICATE_BASE64 }}" ]; then echo "${{ secrets.MAC_APP_CERTIFICATE_BASE64 }}" | base64 --decode > app_cert.p12; fi
if [ -n "${{ secrets.MAC_INSTALLER_CERTIFICATE_BASE64 }}" ]; then echo "${{ secrets.MAC_INSTALLER_CERTIFICATE_BASE64 }}" | base64 --decode > installer_cert.p12; fi
security create-keychain -p "${{ runner.temp }}" build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p "${{ runner.temp }}" build.keychain
security import certificate.p12 -k build.keychain -P "${{ secrets.MACOS_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign
if [ -f app_cert.p12 ]; then security import app_cert.p12 -k build.keychain -P "${{ secrets.MAC_APP_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign -T /usr/bin/productbuild; fi
if [ -f installer_cert.p12 ]; then security import installer_cert.p12 -k build.keychain -P "${{ secrets.MAC_INSTALLER_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign -T /usr/bin/productbuild; fi
security set-key-partition-list -S apple-tool:,apple:,codesign: -k "${{ runner.temp }}" -s build.keychain
security set-keychain-settings -t 3600 -u build.keychain
echo "Listing identities in keychain:"
security find-identity -v -p codesigning build.keychain
rm -f certificate.p12 app_cert.p12 installer_cert.p12
- name: Set up notarytool credentials
run: |
xcrun notarytool store-credentials "AC_PASSWORD" --apple-id "${{ secrets.APPLE_ID }}" --password "${{ secrets.APPLE_ID_PASSWORD }}" --team-id "${{ secrets.APPLE_TEAM_ID }}"
- name: Build and Sign macOS App
env:
SIGNING_IDENTITY: "Developer ID Application: Karl Kwong (T96W95GY4U)"
GOOGLE_PHOTOS_CLIENT_ID: ${{ secrets.GOOGLE_PHOTOS_CLIENT_ID }}
GOOGLE_PHOTOS_CLIENT_SECRET: ${{ secrets.GOOGLE_PHOTOS_CLIENT_SECRET }}
run: |
xcodebuild -project "Spice Wallpaper Manager Extension/Spice Wallpaper Manager Extension.xcodeproj" \
-scheme "Spice Wallpaper Manager Extension (macOS)" \
-configuration Release \
-derivedDataPath "build" \
CODE_SIGN_IDENTITY="${SIGNING_IDENTITY}" \
CODE_SIGN_STYLE="Manual" \
OTHER_CODE_SIGN_FLAGS="--timestamp" \
build
echo "Copying built extension to root for packaging..."
cp -R "build/Build/Products/Release/Spice Wallpaper Manager Extension.app" "."
echo "Current directory contents:"
ls -laR .
SKIP_EXTENSION_BUILD=1 make build-darwin-arm64
echo "Dist directory contents after build:"
ls -laR dist/
- name: Notarize macOS App
run: make notarize-mac-arm64
- name: Build macOS App Store Package
env:
SIGNING_IDENTITY: "3rd Party Mac Developer Application: Karl Kwong (${{ secrets.APPLE_TEAM_ID }})"
INSTALLER_IDENTITY: "3rd Party Mac Developer Installer: Karl Kwong (${{ secrets.APPLE_TEAM_ID }})"
GOOGLE_PHOTOS_CLIENT_ID: ${{ secrets.GOOGLE_PHOTOS_CLIENT_ID }}
GOOGLE_PHOTOS_CLIENT_SECRET: ${{ secrets.GOOGLE_PHOTOS_CLIENT_SECRET }}
run: |
if [ -n "${{ secrets.MAC_PROVISIONING_PROFILE_BASE64 }}" ]; then
echo "Decoding provisioning profile..."
echo "${{ secrets.MAC_PROVISIONING_PROFILE_BASE64 }}" | base64 --decode > embedded.provisionprofile
fi
SKIP_EXTENSION_BUILD=1 make build-darwin-appstore-arm64 BUILD_NUMBER=${{ github.run_number }} APPLE_TEAM_ID=${{ secrets.APPLE_TEAM_ID }}
echo "Verifying entitlements injection:"
plutil -p Spice-AppStore.entitlements
rm -f embedded.provisionprofile
- name: Upload to Mac App Store
env:
APP_STORE_API_KEY_ID: ${{ secrets.APP_STORE_API_KEY_ID }}
APP_STORE_API_ISSUER_ID: ${{ secrets.APP_STORE_API_ISSUER_ID }}
APP_STORE_API_KEY: ${{ secrets.APP_STORE_API_KEY }}
run: |
if [ -n "$APP_STORE_API_KEY_ID" ] && [ -n "$APP_STORE_API_ISSUER_ID" ]; then
mkdir -p ~/.appstoreconnect/private_keys/
echo "$APP_STORE_API_KEY" | base64 --decode > ~/.appstoreconnect/private_keys/AuthKey_${APP_STORE_API_KEY_ID}.p8
xcrun altool --upload-app -f dist/*-AppStore.pkg -t macos --apiKey "$APP_STORE_API_KEY_ID" --apiIssuer "$APP_STORE_API_ISSUER_ID"
rm -f ~/.appstoreconnect/private_keys/AuthKey_${APP_STORE_API_KEY_ID}.p8
else
echo "Skipping App Store upload: API credentials not set."
fi
- name: Upload macOS Artifacts
uses: actions/upload-artifact@v4
with:
name: spice-mac-artifacts
path: dist/
publish-release:
name: Publish Release
runs-on: windows-latest
needs: [build-win, build-mac]
if: github.event.action == 'published'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.x'
cache: true
- name: Download Windows Artifacts
uses: actions/download-artifact@v4
with:
name: spice-win-artifacts
path: .
- name: Download macOS Artifacts
uses: actions/download-artifact@v4
with:
name: spice-mac-artifacts
path: dist
- name: Normalize Artifact Names
id: filenames
run: |
$tagName = '${{ github.event.release.tag_name }}'
$version = $tagName -replace '^v'
# Define new normalized names
$rawExe = "Spice.exe"
$newExe = "Spice-${version}-windows-amd64.exe"
$rawSetup = "Spice-Setup-${version}-amd64.exe"
$newSetup = "Spice-Setup-${version}-windows-amd64.exe"
$rawDmg = "Spice-${tagName}-arm64.dmg"
$newDmg = "Spice-${version}-macos-arm64.dmg"
$rawMsix = "Spice.msix"
$newMsix = "Spice-${version}-windows-amd64.msix"
$rawChrome = "spice-extension-chrome.zip"
$newChrome = "Spice-Extension-${version}-chrome.zip"
$rawFirefox = "spice-extension-firefox.zip"
$newFirefox = "Spice-Extension-${version}-firefox.zip"
# Rename the files physically on disk
Rename-Item -Path "bin\$rawExe" -NewName $newExe
Rename-Item -Path "bin\$rawSetup" -NewName $newSetup
Rename-Item -Path "dist\$rawDmg" -NewName $newDmg
Rename-Item -Path "dist\$rawMsix" -NewName $newMsix
Rename-Item -Path "dist\$rawChrome" -NewName $newChrome
Rename-Item -Path "dist\$rawFirefox" -NewName $newFirefox
# Export for remaining steps
echo "EXE_NAME=$newExe" >> $env:GITHUB_OUTPUT
echo "SETUP_NAME=$newSetup" >> $env:GITHUB_OUTPUT
echo "DMG_NAME=$newDmg" >> $env:GITHUB_OUTPUT
echo "MSIX_NAME=$newMsix" >> $env:GITHUB_OUTPUT
echo "CHROME_NAME=$newChrome" >> $env:GITHUB_OUTPUT
echo "FIREFOX_NAME=$newFirefox" >> $env:GITHUB_OUTPUT
shell: pwsh
- name: Sign Windows Executables
uses: azure/artifact-signing-action@v1
with:
azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
endpoint: https://weu.codesigning.azure.net/
signing-account-name: SpiceOSS
certificate-profile-name: Spice
files: |
${{ github.workspace }}\bin\${{ steps.filenames.outputs.EXE_NAME }}
${{ github.workspace }}\bin\${{ steps.filenames.outputs.SETUP_NAME }}
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
- name: Run Spice Releaser
run: go run cmd/util/spice_releaser/main.go
env:
SPICE_RELEASER_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
SKIP_DISTRIBUTION: ${{ github.event.release.prerelease }}
distribute-release:
name: Distribute (Prerelease Promotion)
runs-on: windows-latest
if: github.event.action == 'released' && github.event.release.prerelease == false
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.25.x'
cache: true
- name: Download Release Assets
run: |
$tagName = '${{ github.event.release.tag_name }}'
$version = $tagName -replace '^v'
New-Item -ItemType Directory -Force -Path bin
New-Item -ItemType Directory -Force -Path dist
gh release download $tagName --pattern "Spice-*-windows-amd64.exe" --dir bin
gh release download $tagName --pattern "Spice-Setup-*-windows-amd64.exe" --dir bin
gh release download $tagName --pattern "Spice-*-macos-arm64.dmg" --dir dist
gh release download $tagName --pattern "Spice-Extension-*-chrome.zip" --dir dist
gh release download $tagName --pattern "Spice-Extension-*-firefox.zip" --dir dist
env:
GH_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
shell: pwsh
- name: Run Spice Releaser
run: go run cmd/util/spice_releaser/main.go
env:
SPICE_RELEASER_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}