Skip to content

Releasing

Jeremiah edited this page Oct 22, 2026 · 1 revision

Releasing

This page describes the coordinated macOS and Windows release process, artifact checks and update-feed publication order.

ChemDraft releases both platforms from the same commit under one version number. The release contains a macOS DMG and a Windows NSIS installer, with separate ## macOS and ## Windows sections in its body. A successful build on one platform does not complete a release.

This is a public overview of the checked-in procedures in docs/releasing/macos-updates.md, windows-updates.md and windows-signing.md. Signing credentials remain outside public documentation and source control. Follow the owner's approved signing procedure for the actual signing operations.

Prepare the reviewed source

  1. Land the release changes through a pull request with all CI hosts green.
  2. Increase the app version in apps/desktop/src-tauri/tauri.conf.json; never reuse a published version. Keep desktop package and Rust crate version metadata aligned with the intended app release.
  3. Prepare release notes that distinguish platform changes and known limitations. Do not imply that tests or signing checks ran unless their results exist.
  4. Resolve redistribution blockers in NOTICE and the dependency inventory. The recorded InChI 1.07.3 licensing caveat is a real gate, not something a release tag clears.
  5. Build both platform artifacts from that reviewed commit, using each host's own OPSIN Java runtime and correct native sidecar.

Stable builds use org.chemdraft.desktop. Release automation on a tag uses CHEMDRAFT_STABLE_BUILD=1; ordinary branch builds remain ChemDraft (dev) with a different identifier. Check the stable title, product name, version and frontend commit stamp before staging artifacts.

macOS artifact and Sparkle feed

The macOS package uses Sparkle. Its public update configuration is in Info.plist and root appcast.xml. A production artifact must pass Developer ID signing, notarization and stapling checks; a locally ad-hoc-signed bundle cannot establish the production trust chain.

The package build stages the pinned Sparkle framework and signs the bundled OPSIN runtime before sealing the outer app when release signing is configured. Nested executable code matters: successful development launches do not prove the signed JVM will run under the hardened runtime.

After producing and validating the final DMG:

  1. Place that DMG and its optional same-basename Markdown notes in a clean staging directory.
  2. Include the current appcast.xml so feed generation retains earlier entries.
  3. Use apps/desktop/src-tauri/sparkle-bin/generate_appcast with the approved Sparkle signing setup and the release's download URL prefix.
  4. Upload the exact DMG named by the generated enclosure. Do not modify its bytes afterward.
  5. Publish the generated appcast through the normal repository review path only after the release asset is publicly reachable.

Never hand-edit a generated signed entry or replace the signing key casually: installed clients depend on the configured trust chain.

Windows artifact and two signatures

The current public Windows installer is not Authenticode-signed, so SmartScreen can warn on manual downloads. The repository includes a SignPath-capable workflow; that capability is not evidence that account approval or a signed production release has occurred.

There are two independent signature checks:

Signature Purpose Order
Authenticode Windows publisher verification for the installer Apply first, when configured
Tauri updater signature Verify the final installer bytes downloaded by the app Apply after all byte-changing steps

.github/workflows/windows-release.yml is manually dispatched. Select the release tag as the workflow ref and provide the same tag as its ref input. Optional upload_to_release targets an existing draft release; optional notes_file must name a tracked repository file. Mismatched source/workflow commits and fork runs are refused.

The workflow builds the host-native OPSIN runtime and stable x64 NSIS installer, optionally obtains Authenticode signing, verifies the signer, then creates and verifies the updater signature. It generates latest.json and checksums from the final files. The windows-release artifact contains the final installer, .exe.sig, feed and SHA256SUMS.txt; windows-nsis-unsigned is signing input.

Missing credentials produce explicit dry-run warnings. Default release upload requires both signatures verified. allow_unsigned_upload is a draft dry-run override, not a production-signing claim. The workflow uploads only to an existing draft and neither publishes the release nor updates the feed on main.

The existing Windows VM build path remains documented. Its updater signature alone does not supply Authenticode. Generate its feed with pnpm -s release:windows-manifest, using the final installer's version and signature; the tool refuses a development installer or missing signature.

Publish and prove the update

Keep the release draft while reviewing both artifacts. Once both pass, publish the joint release, confirm public download URLs and only then land generated appcast.xml and latest.json updates. A feed published early sends users to missing assets.

End-to-end checks need older and newer stable builds. On macOS, verify the Sparkle offer, install, relaunch and retained plugins. On Windows, verify the offer, signature, session save before the passive installer exits the process, relaunch and restored drawing. A failed save must stop the update. Tampered installers must fail without installing.

Report each platform's actual result separately. The feeds and signatures describe artifacts; they do not replace a real installation and update test.

See also

Clone this wiki locally