Packaging and Releases¶
Packaging targets¶
Open Cowork packages desktop artifacts with Electron Builder.
Current release targets:
macOS¶
.zip.dmgx64arm64
Linux¶
.AppImage.debx64
Windows¶
Windows packaging is not part of the v0.x preview release matrix. Add a Windows Electron Builder target, signing policy, and smoke test before claiming Windows support for a stable release.
Local packaging¶
From the repository root:
Artifacts are written to:
CI workflow¶
The repository includes:
ci.yml- lint
- tests
- desktop Electron smoke tests on macOS
- packaged desktop smoke tests on macOS
- Linux packaging validation
- typecheck
- perf gate
- dependency audit at
highseverity -
docs build
-
docs.yml - builds MkDocs with
--strict - uploads the built static site as a GitHub Pages artifact
-
deploys the published docs site on pushes to
master -
release.yml - builds release artifacts for macOS and Linux
- creates GitHub Releases automatically for version tags
- publishes
SHA256SUMS.txt -
attaches GitHub build provenance attestation metadata
-
monthly-maintenance.yml - runs on the first day of each month
- checks dependency audit state, outdated packages, and paired OpenCode SDK/runtime drift
- exists to catch maintenance issues without a noisy nightly signal
Verify a download¶
Release assets include SHA256SUMS.txt. After downloading an artifact from GitHub Releases, place it in the same directory as the checksum file and run:
GitHub build provenance is attached to the release artifacts. With the GitHub CLI installed, verify an artifact against this repository:
Replace the filename with the artifact you downloaded.
Linux .AppImage and .deb artifacts do not carry detached GPG signatures in v0.0.0. Verify Linux downloads with SHA256SUMS.txt and the GitHub build provenance attestation above.
Build output¶
pnpm build is expected to complete without Vite/Rolldown warnings. The large Mermaid renderer is intentionally isolated behind a lazy chunk, so the Vite chunk-size threshold is set high enough to avoid warning on that known path while still catching accidental multi-megabyte growth.
Electron Builder may surface Node's DEP0190 warning from an upstream shell invocation during local packaging. That warning is reviewed and accepted for v0.0.0. It does not affect the release gates; lint, typecheck, unit tests, smoke tests, packaged smoke, perf, audit, and strict docs builds must still pass.
Documentation deployment¶
The docs site is built from docs/ using MkDocs Material and deployed through GitHub Pages. The deploy workflow does not push a generated branch back into the repo; it uploads the built site/ directory as a Pages artifact and lets GitHub handle the publish step. That keeps the release repo cleaner and makes docs deploys easier to reason about in CI.
Release flow¶
Recommended release flow:
- Merge validated changes to
master - Create and push a version tag like
v0.2.0 - Let
release.ymlbuild platform artifacts - Verify the resulting GitHub Release includes checksums and provenance
- Smoke-test at least one macOS build and one Linux build before announcing it
Signing and notarization¶
The release workflow no longer silently publishes unsigned macOS artifacts. A tagged release now does one of two things:
- builds signed/notarized-capable macOS artifacts when the required secrets are present, then publishes the GitHub Release
- fails unless the
OPEN_COWORK_ALLOW_UNSIGNED_RELEASESrepository variable is explicitly enabled for a preview-only unsignedv0.xbuild; in that mode the workflow can publish a GitHub Release, and the release notes / README must clearly mark the artifacts as unsigned public-preview builds
That keeps public production releases honest while still leaving a deliberate escape hatch for the initial unsigned public preview.
Signing gate inputs¶
.github/scripts/release-signing-mode.mjs is the release gate that decides whether a tagged build is allowed to proceed as a signed public release or an unsigned preview. It requires all of these runtime environment variables:
| Runtime env var | GitHub secret or variable used upstream | Purpose |
|---|---|---|
CSC_LINK | MAC_CERTIFICATE_P12_BASE64 secret | Base64-encoded Apple Developer ID Application certificate exported as a .p12 |
CSC_KEY_PASSWORD | MAC_CERTIFICATE_PASSWORD secret | Password for the .p12 signing certificate |
APPLE_ID | APPLE_ID secret | Apple ID used for notarization |
APPLE_APP_SPECIFIC_PASSWORD | APPLE_APP_SPECIFIC_PASSWORD secret | App-specific password for the Apple ID |
APPLE_TEAM_ID | APPLE_TEAM_ID secret | Apple Developer Team ID |
OPEN_COWORK_ALLOW_UNSIGNED_RELEASES | repository variable | Preview-only escape hatch for unsigned v0.x tag dry runs |
For signed releases, leave OPEN_COWORK_ALLOW_UNSIGNED_RELEASES unset or false. If any signing value is missing, the workflow fails before a GitHub Release can be published. For v0.x preview releases only, the override permits unsigned publication with explicit warning text. For v1.0.0 and later, the release policy fails unless macOS signing and notarization are configured. Treat the unsigned override as a temporary per-tag switch: enable it only for the preview release run, then unset it as soon as the GitHub Release has been verified.
Signing pointers for downstream¶
electron-builder reads the standard signing environment variables. A typical macOS release job sets:
env:
CSC_LINK: ${{ secrets.MAC_CERTIFICATE_P12_BASE64 }}
CSC_KEY_PASSWORD: ${{ secrets.MAC_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
The upstream release workflow checks for that full set before the macOS build starts. If any value is missing, the tag build fails unless the unsigned preview override is explicitly enabled. With those Apple notarization credentials present, electron-builder runs its notarization integration for the packaged macOS app. electron-builder's own documentation — in particular Code Signing and Notarization — is the authoritative reference for the full set of knobs.
For a genuinely production-grade public release, treat signing and notarization as a release requirement, not an optional polish item.
Notes¶
The packaged app bundles: - the desktop renderer and main/preload code - Open Cowork config and schema - bundled skills - bundled MCP packages - the OpenCode CLI/runtime dependency needed by the desktop app
Chart rendering in packaged builds is sandboxed in the main process. If a downstream distribution needs to support unusually heavy Vega/Vega-Lite specs, it can raise the render timeout with OPEN_COWORK_CHART_TIMEOUT_MS.
The packaged macOS smoke lane can be run locally after packaging with: