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/.github/workflows/publish-desktop.yml b/.github/workflows/publish-desktop.yml index 05ea8be..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 @@ -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 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: diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 002f828..0a14f39 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -44,15 +44,37 @@ 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. + - Generated note categories are configured in `.github/release.yml`. + - 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 +83,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.