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
96 changes: 68 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
name: release

# Build a Windows portable .exe and publish it as a GitHub Release whenever a
# v* tag is pushed. Example: `git tag v0.1.0 && git push --tags`.
# Build portable desktop binaries for Windows, macOS, and Linux and publish them
# as a single GitHub Release whenever a v* tag is pushed.
# Example: `git tag v0.1.0 && git push --tags`.
#
# Each OS builds on its own native runner (no native deps to cross-rebuild — the
# app uses node:sqlite), uploads its binaries as workflow artifacts, and a final
# `publish` job collects them, writes one combined SHA256SUMS.txt, and publishes.

on:
push:
Expand All @@ -14,8 +19,19 @@ permissions:
contents: write

jobs:
build-windows:
runs-on: windows-latest
build:
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
name: windows
- os: macos-latest
name: macos
- os: ubuntu-latest
name: linux

runs-on: ${{ matrix.os }}

steps:
- name: Checkout
Expand Down Expand Up @@ -44,7 +60,7 @@ jobs:
- name: Build shared package
run: pnpm -C packages/shared build

# Gate the release on a green build: never publish a .exe that fails
# Gate the release on a green build: never publish a binary that fails
# typecheck or tests. Runs after services/shared are built so the desktop
# typecheck can resolve their emitted .d.ts.
- name: Typecheck (all packages)
Expand All @@ -53,42 +69,66 @@ jobs:
- name: Test (all packages)
run: pnpm -r test

- name: Package portable .exe (electron-vite + electron-builder)
- name: Package desktop app (electron-vite + electron-builder)
env:
# No code signing on v0.1 — SmartScreen warning is documented in the README.
# No code signing — SmartScreen (Windows) / Gatekeeper (macOS) warnings
# are documented in the README. electron-builder targets the host OS.
CSC_IDENTITY_AUTO_DISCOVERY: 'false'
# --publish never: electron-builder only BUILDS the .exe. Publishing to
# the GitHub Release is done by the softprops step below. Without this,
# a defined tag makes electron-builder try to self-publish and fail on
# repository detection.
# --publish never: electron-builder only BUILDS the binaries. Publishing
# to the GitHub Release is the dedicated `publish` job below. Without this,
# a defined tag makes electron-builder try to self-publish and fail.
run: pnpm -C apps/desktop exec electron-vite build && pnpm -C apps/desktop exec electron-builder --publish never

# Publish a checksum file so users can verify the unsigned download's
# integrity (`Get-FileHash file.exe -Algorithm SHA256` and compare).
- name: Generate SHA-256 checksums
shell: pwsh
run: |
$lines = Get-ChildItem apps/desktop/dist/*.exe | ForEach-Object {
"$((Get-FileHash $_.FullName -Algorithm SHA256).Hash.ToLower()) $($_.Name)"
}
$lines | Set-Content -Encoding ascii apps/desktop/dist/SHA256SUMS.txt
Get-Content apps/desktop/dist/SHA256SUMS.txt

- name: Upload build artifact (for manual workflow_dispatch runs)
if: github.event_name == 'workflow_dispatch'
# Hand the freshly built binaries off to the publish job. Distributables
# only (electron-builder also drops blockmaps / unpacked dirs we don't ship).
- name: Upload build artifacts
uses: actions/upload-artifact@v7
with:
name: StarcallOS-portable-windows
path: apps/desktop/dist/*.exe
name: dist-${{ matrix.name }}
path: |
apps/desktop/dist/*.exe
apps/desktop/dist/*.dmg
apps/desktop/dist/*.zip
apps/desktop/dist/*.AppImage
if-no-files-found: error

publish:
needs: build
runs-on: ubuntu-latest

steps:
- name: Download all platform artifacts
uses: actions/download-artifact@v5
with:
# All dist-* artifacts flattened into one directory.
pattern: dist-*
merge-multiple: true
path: dist

- name: List collected artifacts
run: ls -lh dist

# One combined checksum file across every platform so users can verify
# the unsigned download's integrity (e.g. `shasum -a 256 -c SHA256SUMS.txt`
# on macOS/Linux, or `Get-FileHash` on Windows).
- name: Generate SHA-256 checksums
run: |
cd dist
# Exclude the output file itself from the glob (no spaces in artifact names).
files=$(ls | grep -v '^SHA256SUMS.txt$')
sha256sum $files > SHA256SUMS.txt
cat SHA256SUMS.txt

- name: Publish to GitHub Release (for tag pushes)
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v3
with:
files: |
apps/desktop/dist/*.exe
apps/desktop/dist/SHA256SUMS.txt
dist/*.exe
dist/*.dmg
dist/*.zip
dist/*.AppImage
dist/SHA256SUMS.txt
generate_release_notes: true
draft: false
prerelease: false
34 changes: 28 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,32 @@ clinical guidelines, language grammars, internal docs.

## Download

Get the latest build from the **[Releases page](https://github.com/ericckzhou/StarcallOS/releases/latest)** — a single portable `.exe` (Windows x64) that runs without installation.
Get the latest build from the **[Releases page](https://github.com/ericckzhou/StarcallOS/releases/latest)** — a portable download for each platform that runs without installation:

> Because the build is unsigned, Windows may show a *"Windows protected your PC"* SmartScreen dialog on first launch. Click **More info → Run anyway**.
| Platform | File | Notes |
| --- | --- | --- |
| **Windows** (x64) | `StarcallOS-*-portable-x64.exe` | self-extracting portable `.exe` |
| **macOS** (Apple Silicon / Intel) | `StarcallOS-*-arm64.dmg` / `StarcallOS-*-x64.dmg` | also a `.zip` of the `.app` if you prefer no disk image |
| **Linux** (x64) | `StarcallOS-*-x86_64.AppImage` | `chmod +x` and run |

**Verify your download (optional).** Each release ships a `SHA256SUMS.txt`. Confirm the `.exe` wasn't corrupted or tampered with in transit:
> **Windows** — because the build is unsigned, Windows may show a *"Windows protected your PC"* SmartScreen dialog on first launch. Click **More info → Run anyway**.

> **macOS** — the app is unsigned and un-notarized, so Gatekeeper blocks it on first launch (*"StarcallOS can't be opened"*). Right-click the app → **Open** → **Open**, or clear the quarantine flag: `xattr -dr com.apple.quarantine /Applications/StarcallOS.app`.

> **Linux** — make the AppImage executable (`chmod +x StarcallOS-*-x86_64.AppImage`) then run it. If it won't start, your distro may lack FUSE; extract and run with `./StarcallOS-*-x86_64.AppImage --appimage-extract-and-run`.

**Verify your download (optional).** Each release ships a `SHA256SUMS.txt` covering every platform's binaries. Confirm your download wasn't corrupted or tampered with in transit:

```powershell
# Windows (PowerShell)
Get-FileHash StarcallOS-*-portable-x64.exe -Algorithm SHA256
```

```sh
# macOS / Linux
shasum -a 256 -c SHA256SUMS.txt # checks every file listed
```

Compare the printed hash against the matching line in `SHA256SUMS.txt` — they should be identical.

Add an LLM key in **Settings** if you want enrichment and grading (or skip — extraction works with zero keys), drop a PDF in, promote a candidate.
Expand Down Expand Up @@ -216,7 +232,7 @@ Each layer has a single responsibility and a single direction of dependency. See

## Build from source

If you don't want to download the prebuilt `.exe`, you can run the dev shell or
If you don't want to download a prebuilt binary, you can run the dev shell or
produce your own portable build:

```sh
Expand All @@ -225,14 +241,20 @@ pnpm install
pnpm -C packages/shared build && pnpm -C packages/services build
pnpm -C apps/desktop dev # hot-reload dev shell
# or
pnpm -C apps/desktop dist # produces apps/desktop/dist/StarcallOS-*-portable-x64.exe
pnpm -C apps/desktop dist # packages for your current OS into apps/desktop/dist/
```

`dist` builds for whichever OS you run it on: a portable `.exe` on Windows, a
`.dmg` + `.zip` on macOS, an `.AppImage` on Linux. (There are no native
dependencies — the app uses `node:sqlite` — so packaging is just bundling the
matching Electron binary; no per-platform native rebuild.)

Requirements: Node **22.5+**, pnpm 11+. The app uses the built-in `node:sqlite`
module (no native bindings), which is experimental and only available on Node
22.5 or newer — older Node versions cannot run it. On Windows, packaging a portable `.exe`
locally needs either an elevated shell or Developer Mode enabled (electron-builder
unpacks signing tooling with symlinks). Otherwise let CI build it for you on tag push.
unpacks signing tooling with symlinks). The tagged-release CI builds all three
platforms on their native runners and publishes them to one GitHub Release.

## Contributing

Expand Down
36 changes: 34 additions & 2 deletions apps/desktop/electron-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,37 @@ win:
- x64
artifactName: ${productName}-${version}-portable-${arch}.${ext}

# v0.1 ships unsigned — the SmartScreen warning is documented in the README.
# To sign later, set CSC_LINK + CSC_KEY_PASSWORD env vars at build time.
# macOS: ship a .dmg (drag-to-install) and a .zip (true portable .app) for both
# Intel (x64) and Apple Silicon (arm64). No native deps means electron-builder
# can cross-pack both arches from a single arm64 runner. Unsigned/un-notarized —
# Gatekeeper workaround is documented in the README. icon.png (512x512+) is
# auto-converted to .icns.
mac:
icon: build/icon.png
category: public.app-category.education
target:
- target: dmg
arch:
- x64
- arm64
- target: zip
arch:
- x64
- arm64
artifactName: ${productName}-${version}-${arch}.${ext}

# Linux: AppImage is the single-file portable analog of the Windows portable
# .exe — chmod +x and run, no install. x64 only for now.
linux:
icon: build/icon.png
category: Education
maintainer: Eric Zhou <ericckzhou@gmail.com>
target:
- target: AppImage
arch:
- x64
artifactName: ${productName}-${version}-${arch}.${ext}

# v0.1 ships unsigned on all platforms — the SmartScreen (Windows) and Gatekeeper
# (macOS) warnings are documented in the README. To sign later, set
# CSC_LINK + CSC_KEY_PASSWORD (and Apple notarization creds) at build time.
Loading