Packaging
One code base, three platforms. packaging/release.sh builds the package
for the platform it runs on, into dist/, with a sha256 beside it and the
version's section of CHANGELOG.md as notes-vX.Y.Z.md. The version
lives once, in the workspace Cargo.toml.
| Platform | Package | What is in it |
|---|---|---|
| Linux | ecliptic-vX.Y.Z-<arch>-linux.tar.gz |
the binary, ecliptic.desktop (with StartupWMClass), the icon at every hicolor size (packaging/icons), install.sh, LICENSE, README, CHANGELOG |
| macOS | ecliptic-vX.Y.Z-macos.dmg |
ecliptic.app, a universal binary (aarch64 and x86_64, joined with lipo), Info.plist and the .icns from packaging/macos/, with an Applications link in the image |
| Windows | ecliptic-vX.Y.Z-x86_64-windows.zip and .msi |
the exe (its icon and version block from packaging/windows/ecliptic.rc, compiled by build.rs), LICENSE, README, CHANGELOG; the MSI (packaging/windows/ecliptic.wxs, WiX 3) installs per user under %LOCALAPPDATA%\Programs\ecliptic with a Start Menu shortcut |
The demo archive (packaging/demo.sh) is Linux only: its record.sh
needs Xvfb. It holds the demo build, demo/promo.tour (the tour it plays,
packaging/demo/README.md lists the steps) and record.sh.
The one-line installers
install.sh (POSIX sh, Linux and macOS) and install.ps1 (Windows) at the
root of the repository are what the README's one-liners fetch, and every
release carries a copy. They follow what rustup's, cargo-dist's and Deno's
installers do: options as flags (--version, --prefix, --apps,
--base-url, --help; -Version and -BaseUrl in PowerShell) and as
environment variables for the piped form; curl or wget, https only,
TLS 1.2 or newer, a few retries; the latest release from the redirect of
releases/latest (GitHub's API in PowerShell); the package verified
against its .sha256 with sha256sum, shasum or openssl
(Get-FileHash); a temporary directory removed on any exit; a refusal on
musl (the binary needs glibc), on Windows from a Unix shell, and on an
unknown processor; and a check that what was installed runs. PowerShell
forces TLS 1.2 for Windows PowerShell 5.1, silences the progress bar that
slows its downloads, reads the real processor from a 32-bit shell, treats
msiexec's 3010 as success, and puts the install folder on the session's
PATH so the command works at once. Installing is the same as by hand: the
tarball's own install.sh, ditto of the .app out of the mounted
.dmg (plus an ecliptic symlink in ~/.local/bin), msiexec /qn of
the MSI. Nothing needs sudo, and neither script edits a shell profile: it
says when the directory is not on PATH. The packaging jobs run both
scripts against the packages they just built (served from dist/ over
HTTP) and start what they installed, so a release is published only once
its installers have worked on each platform.
The release workflow
.github/workflows/ci.yml tests every push on Ubuntu, macOS and Windows
(the toolbox, Linux only, is tested on Ubuntu). On a vX.Y.Z tag it
checks the tag against Cargo.toml, runs release.sh on ubuntu-22.04,
ubuntu-22.04-arm, macos-latest and windows-latest, and a final job
attaches everything to the GitHub release with the notes and one
SHA256SUMS file. The Linux packages come from the oldest supported
Ubuntu on purpose: a binary runs only on a glibc at least as new as the
one it was built against, so building on 22.04 sets the floor at glibc
2.35 (Ubuntu 22.04, Debian 12, Fedora 36 and later). The binary also
loads fontconfig, freetype, expat, libpng, brotli, bzip2 and zlib, which
every desktop installation has.
To cut a release: set the version in Cargo.toml, move the changelog's
Unreleased section under ## [X.Y.Z] - date, commit, git tag -a vX.Y.Z,
push the branch and the tag.
Signing
- macOS:
release.shsigns the app ad hoc (codesign --sign -, no--deep, which is deprecated and unneeded for one executable) unlessAPPLE_SIGNING_IDENTITYnames a Developer ID certificate in the keychain, in which case it signs with the hardened runtime and a secure timestamp, as notarization requires. WithAPPLE_ID,APPLE_PASSWORD(an app-specific password) andAPPLE_TEAM_IDset as well, it notarizes the disk image withnotarytooland staples the ticket. Put those in the repository's secrets and export them in the macOS packaging job to ship a notarized build. Until then: Apple silicon runs nothing unsigned, which the ad hoc signature covers; a browser download is quarantined, and since macOS 15 (Sequoia) the only way past Gatekeeper for it is System Settings → Privacy & Security → Open Anyway after the first refused launch (control-click → Open no longer works); a curl download, which is whatinstall.shdoes, is not quarantined and opens at once. - Windows: nothing signs the exe or the MSI; SmartScreen warns once on
a browser download (
install.ps1unblocks the file it verified). A code-signing certificate would go in asigntoolstep afterrelease.sh.
Checking a platform without it
From Linux, cargo check -p ecliptic --tests --target x86_64-pc-windows-gnu
and --target aarch64-apple-darwin (after rustup target add) compile
the app for those platforms without linking, which catches a Linux
assumption. With MinGW installed, cargo build --release --target
x86_64-pc-windows-gnu links a real ecliptic.exe, and Wine runs it:
wine target/x86_64-pc-windows-gnu/release/ecliptic.exe --version, or
the whole window on a private X display.