Skip to content

feat: add Windows build support with Scoop manifest #22

feat: add Windows build support with Scoop manifest

feat: add Windows build support with Scoop manifest #22

Workflow file for this run

name: Release
on:
push:
tags:
- '[0-9]+.[0-9]+.[0-9]+'
jobs:
release:
runs-on: ubuntu-latest
permissions:
contents: write
outputs:
version: ${{ steps.version.outputs.version }}
tarball-hash: ${{ steps.sha256.outputs.hash }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
fetch-tags: true
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y meson ninja-build gettext appstream desktop-file-utils libglib2.0-dev
- name: Get version from tag
id: version
run: echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Create source tarball
run: |
meson setup build
meson dist -C build --no-tests --include-subprojects
TARBALL=$(ls build/meson-dist/*.tar.xz)
mv "$TARBALL" "awakeonlan-${{ steps.version.outputs.version }}.tar.xz"
- name: Calculate SHA256
id: sha256
run: |
HASH=$(sha256sum awakeonlan-${{ steps.version.outputs.version }}.tar.xz | awk '{print $1}')
echo "hash=$HASH" >> $GITHUB_OUTPUT
echo "SHA256: $HASH"
- name: Generate release notes
id: release_notes
run: |
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | head -2 | tail -1)
if [ -z "$PREVIOUS_TAG" ]; then
PREVIOUS_TAG=$(git rev-list --max-parents=0 HEAD)
fi
echo "Comparing $PREVIOUS_TAG..HEAD"
{
echo 'notes<<EOF'
git log --oneline --no-decorate "$PREVIOUS_TAG..HEAD" \
| sed 's/^\([a-f0-9]\+\) \(.*\)/- \2 (\1)/' \
|| echo "- Initial release"
echo 'EOF'
} >> $GITHUB_OUTPUT
- name: Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release create ${{ steps.version.outputs.version }} \
awakeonlan-${{ steps.version.outputs.version }}.tar.xz \
--title "Awake on LAN ${{ steps.version.outputs.version }}" \
--notes "${{ steps.release_notes.outputs.notes }}"
windows-build:
runs-on: windows-latest
needs: release
permissions:
contents: write
outputs:
hash: ${{ steps.sha256.outputs.hash }}
env:
gvsbuild_version: 2026.4.1
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: GTK binaries get from cache
uses: actions/cache@v4
id: cache
with:
path: C:\gtk\**
key: ${{ runner.os }}-gvsbuild-${{ env.gvsbuild_version }}
- name: Download Gvsbuild
if: steps.cache.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ github.token }}
run: |
$version = $env:gvsbuild_version
gh release download --repo wingtk/gvsbuild "$version" -p "GTK4_Gvsbuild_$($version)_x64.zip"
7z x "GTK4_Gvsbuild_$($version)_x64.zip" -oC:\gtk -y
- name: Set up GTK environment
run: |
Write-Output "C:\gtk\bin" >> $env:GITHUB_PATH
Write-Output "PKG_CONFIG=C:\gtk\bin\pkgconf.exe" >> $env:GITHUB_ENV
Write-Output "XDG_DATA_HOME=$HOME\.local\share" >> $env:GITHUB_ENV
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.14'
- name: Install Python dependencies
run: |
pip install --force-reinstall (Resolve-Path C:\gtk\wheels\PyGObject*.whl)
pip install --force-reinstall (Resolve-Path C:\gtk\wheels\pycairo*.whl)
pip install pyinstaller pyinstaller-hooks-contrib
- name: Verify gi module
run: |
python -c "import sys; print('Python:', sys.executable); print('Path:', sys.path)"
pip show PyGObject
python -c "import os; os.add_dll_directory(r'C:\gtk\bin'); import gi; gi.require_version('Gtk', '4.0'); gi.require_version('Adw', '1'); from gi.repository import Gtk, Adw; print('GTK', Gtk.get_major_version(), Gtk.get_minor_version()); print('Adw OK')"
- name: Convert icon to .ico
run: magick -background none data/icons/hicolor/scalable/apps/co.logonoff.awakeonlan.svg -define icon:auto-resize=256,128,64,48,32,16 awakeonlan.ico
- name: Prepare entry point
run: |
$version = "${{ needs.release.outputs.version }}"
(Get-Content src/awakeonlan.in) `
-replace '@PYTHON@','/usr/bin/python3' `
-replace '@VERSION@',$version `
-replace '@pkgdatadir@','.' `
-replace '@localedir@','./locale' |
Set-Content src/awakeonlan.in
- name: Compile GResources
run: |
Copy-Item data/co.logonoff.awakeonlan.metainfo.xml.in data/co.logonoff.awakeonlan.metainfo.xml
Push-Location src
glib-compile-resources --sourcedir=. --sourcedir=.. awakeonlan.gresource.xml --target=awakeonlan.gresource
Pop-Location
- name: Compile GSettings schemas
run: glib-compile-schemas data/
- name: Build with PyInstaller
run: pyinstaller awakeonlan.spec
- name: Bundle additional resources
run: |
# GSettings schemas: combine app + gvsbuild schemas
New-Item -ItemType Directory -Force dist/awakeonlan/share/glib-2.0/schemas
Copy-Item C:\gtk\share\glib-2.0\schemas\*.xml dist/awakeonlan/share/glib-2.0/schemas/
Copy-Item data/co.logonoff.awakeonlan.gschema.xml dist/awakeonlan/share/glib-2.0/schemas/
glib-compile-schemas dist/awakeonlan/share/glib-2.0/schemas/
# Icon themes
New-Item -ItemType Directory -Force dist/awakeonlan/share/icons
Copy-Item -Recurse C:\gtk\share\icons\Adwaita dist/awakeonlan/share/icons/
Copy-Item -Recurse C:\gtk\share\icons\hicolor dist/awakeonlan/share/icons/
# App icon
New-Item -ItemType Directory -Force dist/awakeonlan/share/icons/hicolor/scalable/apps
Copy-Item data/icons/hicolor/scalable/apps/co.logonoff.awakeonlan.svg dist/awakeonlan/share/icons/hicolor/scalable/apps/
New-Item -ItemType Directory -Force dist/awakeonlan/share/icons/hicolor/symbolic/apps
Copy-Item data/icons/hicolor/symbolic/apps/co.logonoff.awakeonlan-symbolic.svg dist/awakeonlan/share/icons/hicolor/symbolic/apps/
- name: Create ZIP archive
run: Compress-Archive -Path dist/awakeonlan -DestinationPath awakeonlan-${{ needs.release.outputs.version }}-windows-x86_64.zip
- name: Calculate SHA256
id: sha256
run: |
$hash = (Get-FileHash awakeonlan-${{ needs.release.outputs.version }}-windows-x86_64.zip -Algorithm SHA256).Hash.ToLower()
echo "hash=$hash" >> $env:GITHUB_OUTPUT
- name: Upload to release
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload ${{ needs.release.outputs.version }} awakeonlan-${{ needs.release.outputs.version }}-windows-x86_64.zip
update-manifests:
runs-on: ubuntu-latest
needs: [release, windows-build]
permissions:
contents: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Update manifests
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
VERSION=${{ needs.release.outputs.version }}
TARBALL_HASH=${{ needs.release.outputs.tarball-hash }}
WINDOWS_HASH=${{ needs.windows-build.outputs.hash }}
# Update Homebrew formula
sed -i "s/version \".*\"/version \"$VERSION\"/" Formula/awakeonlan.rb
sed -i "s/sha256 \".*\"/sha256 \"$TARBALL_HASH\"/" Formula/awakeonlan.rb
# Update Scoop manifest
sed -i "s/\"version\": \".*\"/\"version\": \"$VERSION\"/" bucket/awakeonlan.json
sed -i "s|download/.*/awakeonlan-.*-windows-x86_64.zip|download/${VERSION}/awakeonlan-${VERSION}-windows-x86_64.zip|" bucket/awakeonlan.json
sed -i "s/\"hash\": \".*\"/\"hash\": \"$WINDOWS_HASH\"/" bucket/awakeonlan.json
FORMULA_CONTENT=$(base64 -w 0 < Formula/awakeonlan.rb)
SCOOP_CONTENT=$(base64 -w 0 < bucket/awakeonlan.json)
MAIN_OID=$(gh api graphql -f query='{ repository(owner:"logonoff", name:"awake-on-lan") { ref(qualifiedName:"refs/heads/main") { target { oid } } } }' --jq '.data.repository.ref.target.oid')
jq -n \
--arg oid "$MAIN_OID" \
--arg formula "$FORMULA_CONTENT" \
--arg scoop "$SCOOP_CONTENT" \
--arg version "$VERSION" \
'{
query: "mutation($input: CreateCommitOnBranchInput!) { createCommitOnBranch(input: $input) { commit { oid } } }",
variables: {
input: {
branch: { repositoryNameWithOwner: "logonoff/awake-on-lan", branchName: "main" },
expectedHeadOid: $oid,
message: { headline: ("chore: update manifests to " + $version) },
fileChanges: { additions: [
{ path: "Formula/awakeonlan.rb", contents: $formula },
{ path: "bucket/awakeonlan.json", contents: $scoop }
] }
}
}
}'
# | gh api graphql --input -
# - name: Sync homebrew-bucket
# run: |
# gh api repos/logonoff/homebrew-bucket/dispatches \
# -f event_type=sync
# env:
# GH_TOKEN: ${{ secrets.BUCKET_PAT }}
- name: Check if next branch can be fast-forwarded
id: check-next
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if git ls-remote --exit-code origin next &>/dev/null; then
git fetch origin next main
if git merge-base --is-ancestor origin/next origin/main; then
echo "can_ff=true" >> "$GITHUB_OUTPUT"
fi
fi
- name: Fast-forward next branch
if: steps.check-next.outputs.can_ff == 'true'
run: git push origin origin/main:next
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}