From 7127b5b851ed31ec205198928a9b09e8ba98f785 Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:00:15 +0000 Subject: [PATCH 1/6] feat(ci): add Windows desktop release builds for x64 and arm64 ## Summary - split desktop publishing into dedicated Linux and Windows jobs - add matrix builds for and - keep existing Linux release flow unchanged, including the portable AppImage flag ## Why - Windows release artefacts must be produced on Windows runners for reliable MSI/NSIS packaging - a separate Windows job avoids Linux container constraints and keeps platform responsibilities clear - targeting both x64 and arm64 aligns with native Windows-on-Arm support goals ## Behaviour Changes - now attaches Windows artefacts to the same GitHub release as Linux artefacts - manual release runs default to draft mode () - tag-triggered releases also stay draft unless explicitly promoted later ## Release Metadata Improvements - release creation now enables GitHub-generated release notes for first-pass changelog quality ## Notes - kept existing tag validation and release re-use logic to minimise migration risk --- .github/workflows/publish-desktop.yml | 98 ++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-desktop.yml b/.github/workflows/publish-desktop.yml index 05ea8be..a7465ee 100644 --- a/.github/workflows/publish-desktop.yml +++ b/.github/workflows/publish-desktop.yml @@ -10,7 +10,7 @@ on: release_draft: description: Create/keep this release as draft required: false - default: false + default: true type: boolean push: tags: @@ -59,7 +59,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.meta.outputs.tag_name }} RELEASE_NAME: ${{ steps.meta.outputs.release_name }} - RELEASE_DRAFT: ${{ github.event_name == 'workflow_dispatch' && inputs.release_draft || false }} + RELEASE_DRAFT: ${{ github.event_name == 'workflow_dispatch' ? inputs.release_draft : true }} run: | set -euo pipefail @@ -78,6 +78,7 @@ jobs: -f target_commitish="${GITHUB_SHA}" \ -f name="${RELEASE_NAME}" \ -f body='See assets below to download and install.' \ + -F generate_release_notes=true \ -F draft="${RELEASE_DRAFT}" \ -F prerelease=false \ --jq '.id' @@ -96,7 +97,7 @@ jobs: echo "release_id=${RELEASE_ID}" >> "${GITHUB_OUTPUT}" - publish-tauri: + publish-linux: needs: prepare-release permissions: contents: write @@ -164,3 +165,94 @@ jobs: releaseId: ${{ needs.prepare-release.outputs.release_id }} includeUpdaterJson: false tauriScript: "cargo tauri" + + publish-windows: + needs: prepare-release + permissions: + contents: write + + strategy: + fail-fast: false + matrix: + include: + - arch: x64 + target: x86_64-pc-windows-msvc + - arch: arm64 + target: aarch64-pc-windows-msvc + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v6 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: .node-version + cache: pnpm + + - name: Resolve Rust toolchain + id: rust_toolchain + shell: bash + run: | + set -euo pipefail + TOOLCHAIN="$(awk -F '\"' '/^[[:space:]]*channel[[:space:]]*=/ { print $2; exit }' rust-toolchain.toml)" + if [[ -z "${TOOLCHAIN}" ]]; then + echo "Unable to resolve Rust toolchain from rust-toolchain.toml" >&2 + exit 1 + fi + echo "toolchain=${TOOLCHAIN}" >> "${GITHUB_OUTPUT}" + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ steps.rust_toolchain.outputs.toolchain }} + targets: ${{ matrix.target }} + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: | + apps/desktop/src-tauri -> target + + - name: Install JS deps + run: pnpm run ci:install + + - name: Build + attach to GitHub Release + uses: tauri-apps/tauri-action@v0.6.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + projectPath: apps/desktop + releaseId: ${{ needs.prepare-release.outputs.release_id }} + includeUpdaterJson: false + tauriScript: "cargo tauri" + args: --target ${{ matrix.target }} + + - name: Generate Windows checksums + shell: pwsh + run: | + $bundleDir = "apps/desktop/src-tauri/target/${{ matrix.target }}/release/bundle" + $checksumPath = "apps/desktop/src-tauri/target/${{ matrix.target }}/release/checksums-windows-${{ matrix.arch }}.txt" + + $installerFiles = Get-ChildItem -Path $bundleDir -File -Recurse -Include *.msi,*setup*.exe + if ($installerFiles.Count -eq 0) { + throw "No Windows installers found in $bundleDir" + } + + $lines = foreach ($file in $installerFiles | Sort-Object FullName) { + $hash = (Get-FileHash -Path $file.FullName -Algorithm SHA256).Hash.ToLower() + "$hash $($file.Name)" + } + + $lines | Set-Content -Path $checksumPath -Encoding ASCII + + - name: Attach Windows checksums to release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ needs.prepare-release.outputs.tag_name }} + files: | + apps/desktop/src-tauri/target/${{ matrix.target }}/release/checksums-windows-${{ matrix.arch }}.txt From 646b40d7f40f93f1abe81f6d47544f70891d5aea Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:00:28 +0000 Subject: [PATCH 2/6] fix(ci): default desktop releases to published state ## Summary - set `workflow_dispatch` input `release_draft` default to `false` - set tag-triggered release default to non-draft while preserving manual draft override wiring ## Why - release policy is full publish by default - still retain manual control to force a draft when needed ## Behaviour - push tags matching `desktop-v*` now create or update published releases by default - manual runs can still set `release_draft: true` for historical/manual review flows --- .github/workflows/publish-desktop.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-desktop.yml b/.github/workflows/publish-desktop.yml index a7465ee..a46be9a 100644 --- a/.github/workflows/publish-desktop.yml +++ b/.github/workflows/publish-desktop.yml @@ -10,7 +10,7 @@ on: release_draft: description: Create/keep this release as draft required: false - default: true + default: false type: boolean push: tags: @@ -59,7 +59,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.meta.outputs.tag_name }} RELEASE_NAME: ${{ steps.meta.outputs.release_name }} - RELEASE_DRAFT: ${{ github.event_name == 'workflow_dispatch' ? inputs.release_draft : true }} + RELEASE_DRAFT: ${{ github.event_name == 'workflow_dispatch' ? inputs.release_draft : false }} run: | set -euo pipefail From 6cac816be01537765712ff4917ac5bb800c946a5 Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:01:06 +0000 Subject: [PATCH 3/6] docs(release): document Windows artefacts and checksum verification ## Summary - update desktop release documentation to include Windows x64 and arm64 CI targets - document default published-release behaviour with optional manual draft override - add unsigned Windows installer guidance and PowerShell checksum verification steps - update CI limitation notes to reflect current platform coverage ## Why - release docs must match the behaviour implemented in the desktop publish workflow - unsigned Windows installers require explicit user guidance and integrity verification instructions - clear release expectations reduce triage overhead during each tag cut ## Notes - checksum examples use PowerShell to match the Windows runner/tooling path used in CI - documentation keeps macOS and code-signing status explicit for future milestones --- docs/RELEASING.md | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 002f828..7f01743 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -44,15 +44,36 @@ This document describes the process for creating a new release of the desktop ap - Watch the build progress. It currently targets: - Linux x64 (Ubuntu 24.04) - Linux ARM64 (Ubuntu 24.04) + - Windows x64 (`x86_64-pc-windows-msvc`) + - Windows ARM64 (`aarch64-pc-windows-msvc`) -5. **Review Draft Release** - - Once the build completes, a **Draft** release will be created/updated on GitHub. +5. **Review Release** + - Once the build completes, a release will be created or updated on GitHub. - Go to the "Releases" section. - - Verify that the assets (AppImage, deb) are present. - - Add release notes to the body. + - Verify that Linux and Windows assets are present. + - Confirm the generated release notes look correct. + - If needed, edit the release text with additional context. -6. **Publish** - - When satisfied, click "Edit" on the release and "Publish release" to make it public. +6. **Optional Draft Mode** + - The default release path publishes immediately. + - For manual runs via `workflow_dispatch`, set `release_draft=true` to keep the release as a draft. + - This keeps historical/manual review workflows available without changing the default path. + +## Windows unsigned installer flow + +- Windows builds are currently unsigned and may trigger SmartScreen warnings. +- Installers are still deterministic build artefacts generated in CI. +- Each Windows CI job also uploads checksum assets to the release: + - `checksums-windows-x64.txt` + - `checksums-windows-arm64.txt` + +### Verify a downloaded installer on Windows (PowerShell) + +```powershell +Get-FileHash .\liminal-notes__x64_en-US.msi -Algorithm SHA256 +``` + +- Compare the printed hash with the matching checksum file attached to the release. ## Linux AppImage runtime @@ -61,5 +82,6 @@ This document describes the process for creating a new release of the desktop ap ## Current CI Limitations -- **Windows & macOS**: Currently skipped in the CI pipeline pending research on code signing and notarization. +- **macOS**: Not yet included in the desktop release pipeline. - **Linux ARM**: Builds are performed on `ubuntu-24.04-arm` runners. +- **Windows code signing**: Installer signing is not configured yet. From dd76f50579c6926c3b8b0cee2b5aaef83d5b5802 Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:01:16 +0000 Subject: [PATCH 4/6] docs(readme): add Windows SmartScreen and checksum guidance ## Summary - add a dedicated Windows installation section to the project README - document SmartScreen flow for unsigned installers - include SHA256 verification guidance using release checksum assets ## Why - Windows users need a clear install path when code signing is not enabled - checksum verification provides a simple integrity check for downloaded artefacts - keeping this in README improves discoverability compared with release docs alone ## Notes - command examples use PowerShell to match Windows defaults and CI checksum tooling --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index cc15376..42ed4f9 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,19 @@ The built artifacts will be available in `apps/desktop/src-tauri/target/release/ **Note:** Binaries are currently unsigned. You may see OS warnings when installing. +## Windows Installation + +Windows may show a SmartScreen warning because the installer is not currently code-signed. + +1. Select `More info`. +2. Select `Run anyway`. + +Before running the installer, verify its SHA256 hash against the release checksum assets (`checksums-windows-x64.txt` or `checksums-windows-arm64.txt`). + +```powershell +Get-FileHash .\liminal-notes__x64_en-US.msi -Algorithm SHA256 +``` + ### Linux AppImage (portable format) To fix `EGL_BAD_PARAMETER` blank-screen failures on Arch/Fedora/Steam Deck, build with Tauri’s experimental portable AppImage runtime: From 7a21ac8ebc261a65e70cd805ccb28a09518bc660 Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:01:53 +0000 Subject: [PATCH 5/6] fix(ci): quote release draft expression for YAML compatibility ## Summary - quote the `RELEASE_DRAFT` GitHub expression in workflow env configuration ## Why - unquoted ternary expressions with `:` break strict YAML parsers - quoting keeps GitHub Actions expression evaluation intact while restoring YAML validity ## Impact - no release-policy change - workflow remains publish-by-default with manual `release_draft` override preserved --- .github/workflows/publish-desktop.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-desktop.yml b/.github/workflows/publish-desktop.yml index a46be9a..18a8209 100644 --- a/.github/workflows/publish-desktop.yml +++ b/.github/workflows/publish-desktop.yml @@ -59,7 +59,7 @@ jobs: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAG_NAME: ${{ steps.meta.outputs.tag_name }} RELEASE_NAME: ${{ steps.meta.outputs.release_name }} - RELEASE_DRAFT: ${{ github.event_name == 'workflow_dispatch' ? inputs.release_draft : false }} + RELEASE_DRAFT: "${{ github.event_name == 'workflow_dispatch' ? inputs.release_draft : false }}" run: | set -euo pipefail From 1a290f9b57b45e69a2372a2fea84e86a2df1cd78 Mon Sep 17 00:00:00 2001 From: Scott Morris Date: Thu, 12 Feb 2026 07:02:22 +0000 Subject: [PATCH 6/6] feat(ci): categorise auto-generated GitHub release notes ## Summary - add `.github/release.yml` to shape GitHub auto-generated release-note sections - document the category config location in the desktop release guide ## Why - generated release notes are now enabled in CI, so category structure should be intentional - this gives immediate release-note quality improvements without introducing a full release-management system ## Behaviour - release notes are grouped into Features, Fixes, Documentation, CI and Build, and Other Changes - maintainers can tune categories later by updating `.github/release.yml` ## Scope - no versioning automation or semantic release flow added in this change - remains compatible with the existing tag-driven desktop release process --- .github/release.yml | 23 +++++++++++++++++++++++ docs/RELEASING.md | 1 + 2 files changed, 24 insertions(+) create mode 100644 .github/release.yml diff --git a/.github/release.yml b/.github/release.yml new file mode 100644 index 0000000..cdc4ea6 --- /dev/null +++ b/.github/release.yml @@ -0,0 +1,23 @@ +changelog: + categories: + - title: Features + labels: + - feat + - feature + - enhancement + - title: Fixes + labels: + - fix + - bug + - bugfix + - title: Documentation + labels: + - docs + - title: CI and Build + labels: + - ci + - build + - chore + - title: Other Changes + labels: + - "*" diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 7f01743..0a14f39 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -52,6 +52,7 @@ This document describes the process for creating a new release of the desktop ap - Go to the "Releases" section. - Verify that Linux and Windows assets are present. - Confirm the generated release notes look correct. + - Generated note categories are configured in `.github/release.yml`. - If needed, edit the release text with additional context. 6. **Optional Draft Mode**