Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
name: Release

# Manual, because the version lives in tauri.conf.json and a release is a decision, not a
# consequence of merging. Bump it in a pull request, then run this.
on:
workflow_dispatch:

permissions:
contents: write

jobs:
windows:
name: Installer
runs-on: windows-latest

steps:
- uses: actions/checkout@v5
with:
ref: main
fetch-depth: 0

- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm

- uses: dtolnay/rust-toolchain@stable
with:
targets: x86_64-pc-windows-msvc

- uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri

- run: npm ci

# The same gate as CI. A release that skips it is the one build nobody checked.
- run: npm run check
- run: npm test
- run: cargo test --manifest-path src-tauri/Cargo.toml

- name: Read the version, and refuse a tag that exists
id: version
shell: pwsh
run: |
$version = (Get-Content src-tauri/tauri.conf.json -Raw | ConvertFrom-Json).version
if (-not $version) { Write-Error 'No version in src-tauri/tauri.conf.json'; exit 1 }
# Checked here rather than at `git tag` half an hour later, once the installer is built.
if (git tag -l "v$version") { Write-Error "v$version is already tagged"; exit 1 }
"version=$version" >> $env:GITHUB_OUTPUT

- name: Build the installer
run: npx tauri build

- name: Collect it
id: artifact
shell: pwsh
run: |
New-Item -ItemType Directory -Force artifacts | Out-Null
$setup = Get-ChildItem src-tauri/target/release/bundle/nsis/*-setup.exe | Select-Object -First 1
if (-not $setup) { Write-Error 'tauri build produced no NSIS installer'; exit 1 }
Copy-Item $setup.FullName artifacts/
Get-ChildItem artifacts | Format-Table Name, Length

- name: Tag it
shell: pwsh
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}"
git push origin "v${{ steps.version.outputs.version }}"

# Notes from release-notes/v<version>.md when it is there, and GitHub's own summary of the
# commits when it is not — a missing file should not lose a built installer.
- name: Publish
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
name: OpenThemeGenerator ${{ steps.version.outputs.version }}
body_path: release-notes/v${{ steps.version.outputs.version }}.md
generate_release_notes: true
fail_on_unmatched_files: true
files: artifacts/*-setup.exe
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ npm run start
The workflow runs the table above — lint, types, tests and build on Linux, and `cargo fmt`,
`clippy` and the host's tests on Windows, where the app actually ships.

Releases are manual. Bump `version` in `src-tauri/tauri.conf.json` in a pull request, then run the
**Release** workflow: it runs the same gate, builds the NSIS installer, tags `v<version>` and
publishes it. Notes come from `release-notes/v<version>.md` if you wrote one, and from GitHub's
summary of the commits if you did not.

Two things the tests care about more than style:

- **Every theme this app derives clears 4.5:1** on every surface/label pair, in both modes. So does
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,8 @@
"vite": "^8.2.0",
"vitest": "^4.1.10",
"zod": "^4.4.3"
},
"overrides": {
"cookie": "^0.7.2"
}
}