Skip to content

Build and upload to latest release #17

Build and upload to latest release

Build and upload to latest release #17

name: Build and upload to latest release
on:
workflow_dispatch:
permissions:
contents: write
jobs:
test:
uses: ./.github/workflows/tests.yml
build:
needs: test
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
platform: Windows
- os: macos-latest
platform: macOS
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: '3.14'
update-environment: true
cache: 'pipenv'
- name: Install dependencies with pipenv
shell: bash
run: |
python -m pip install --upgrade pip pipenv
pipenv --python 3.14
pipenv install --dev
- name: Build the primary GUI application
run: pipenv run ui_build
- name: Read version info
shell: bash
run: |
python - <<'PY'
import json
import os
from datetime import datetime, timedelta, timezone
with open("version.json", encoding="utf-8") as file:
info = json.load(file)
if not info.get("name") or not info.get("version"):
raise SystemExit("version.json must contain name and version")
timestamp = datetime.now(timezone(timedelta(hours=8))).strftime("%Y%m%d-%H%M%S")
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as file:
file.write(
f"name={info['name']}\nversion={info['version']}\nzip_ts={timestamp}\n"
)
PY
- name: Package Windows application
if: runner.os == 'Windows'
shell: pwsh
run: |
$bundle = Join-Path $PWD "dist\$env:name-GUI-v$env:version"
if (-not (Test-Path $bundle)) {
Write-Error "Windows application directory not found: $bundle"
exit 1
}
New-Item -ItemType Directory -Path artifacts -Force | Out-Null
$asset = "$env:name-GUI-Windows-$env:RUNNER_ARCH-v$env:version-$env:zip_ts.zip"
Compress-Archive -Path $bundle -DestinationPath (Join-Path $PWD "artifacts\$asset")
- name: Package macOS application
if: runner.os == 'macOS'
shell: bash
run: |
app_path="dist/${name}-GUI-v${version}.app"
if [[ ! -d "$app_path" ]]; then
echo "macOS application bundle not found: $app_path" >&2
exit 1
fi
mkdir -p artifacts
asset="${name}-GUI-macOS-${RUNNER_ARCH}-v${version}-${zip_ts}.zip"
ditto -c -k --sequesterRsrc --keepParent "$app_path" "artifacts/$asset"
- name: Upload GUI artifact
uses: actions/upload-artifact@v4
with:
name: gui-${{ matrix.platform }}-${{ runner.arch }}
path: artifacts/*.zip
if-no-files-found: error
upload:
needs: build
runs-on: ubuntu-latest
steps:
- name: Download GUI artifacts
uses: actions/download-artifact@v4
with:
pattern: gui-*
path: release-assets
merge-multiple: true
- name: Upload assets to latest release
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
$tag = gh release view --repo $env:GITHUB_REPOSITORY --json tagName --jq '.tagName'
if (-not $tag) {
Write-Error 'Latest release was not found.'
exit 1
}
$assets = @(Get-ChildItem release-assets -Filter '*.zip' | Select-Object -ExpandProperty FullName)
if ($assets.Count -ne 2) {
Write-Error "Expected two desktop assets, found $($assets.Count)."
exit 1
}
$checksums = Join-Path $PWD 'release-assets/SHA256SUMS.txt'
$assets | ForEach-Object {
$hash = (Get-FileHash -LiteralPath $_ -Algorithm SHA256).Hash.ToLower()
"$hash $(Split-Path $_ -Leaf)"
} | Set-Content -Path $checksums -Encoding utf8NoBOM
foreach ($asset in $assets) {
gh release upload $tag $asset --clobber --repo $env:GITHUB_REPOSITORY
}
gh release upload $tag $checksums --clobber --repo $env:GITHUB_REPOSITORY
- name: Confirm upload
shell: pwsh
run: Write-Host 'Uploaded Windows and macOS desktop assets to the latest release.'