mirror of
https://github.com/priyanshujain/margin-calendar.git
synced 2026-10-02 11:07:04 +00:00
Ported from margin's pipeline, with the platform list this app actually claims. Release is manual: it bumps tauri.conf.json, package.json and Cargo.toml together, tags, and then builds the tag rather than whatever main has drifted to by the time the runners pick it up. Nothing publishes until every platform lands. The last job downloads latest.json and refuses to take the release out of draft unless darwin-aarch64, darwin-x86_64 and linux-x86_64 are all present, because a half-populated manifest is worse than no release at all: the updater would offer an update to the platforms that made it and error on the ones that did not. Linux builds on Ubuntu 22.04 rather than latest. The bundle will not run on anything older than the glibc it was linked against, and 22.04 is the baseline docs/setup.md commits to. Windows is not built, matching the bundle targets and the README; adding it is a matrix entry, msi and nsis in the targets, and windows-x86_64 in the publish gate. The updater had a plugin, a capability and a menu item but no keypair and no endpoint, so releases would have produced artifacts nothing could verify. The public half is now in tauri.release.conf.json and the private half is a repository secret, alongside the Google OAuth client that build.rs embeds. Without that secret the build falls back to the example credentials and warns rather than failing, which yields an app that runs and then says Google Calendar is not set up. CI enforces the gate setup.md already names, the two test suites, and nothing more. cargo fmt --check and cargo clippy -D warnings both fail on the tree as it stands, and adopting either is a cleanup pass to decide on rather than something to bolt onto a new pipeline. justfile is the local equivalent of all this. `just install` builds for the machine it is run on and installs it, and is the same command whether or not the app is already there, so it doubles as the update. On macOS it asks a running copy to quit first, because replacing a bundle under a live process leaves it half old and half new.
62 lines
3.5 KiB
Markdown
62 lines
3.5 KiB
Markdown
# Releasing
|
|
|
|
## Installing locally
|
|
|
|
`just install` builds the app for whatever machine you are sitting at and puts it where that
|
|
machine expects to find applications: `/Applications` on macOS, or the package manager on Linux.
|
|
It is the same command whether or not the app is already installed, so it doubles as the update.
|
|
On macOS it asks a running copy to quit first, because replacing a bundle under a live process
|
|
leaves it half old and half new. `just uninstall` reverses it and leaves the data directory alone.
|
|
|
|
The local build skips the dmg and builds only the `.app`, since nothing about copying a bundle
|
|
into place needs a disk image and building one is the slowest part of a mac bundle. That makes a
|
|
locally installed app slightly different from a released one, in that it is ad-hoc signed and has
|
|
no updater artifacts. It will not update itself. Rerun `just install`.
|
|
|
|
## Cutting a release
|
|
|
|
Releases are manual: run the **Release** workflow from the Actions tab. Leave the version empty to
|
|
bump the patch number, or give one to set it. The workflow bumps `tauri.conf.json`, `package.json`
|
|
and `Cargo.toml` together, commits that to main, tags it, and builds the tag rather than whatever
|
|
main happens to be by then.
|
|
|
|
It builds a universal macOS bundle and an x86_64 Linux one, and it publishes nothing until both
|
|
have landed. The last job downloads `latest.json` and refuses to take the release out of draft
|
|
unless `darwin-aarch64`, `darwin-x86_64` and `linux-x86_64` are all in it. A half-populated
|
|
manifest is worse than no release: the updater would offer an update to the platforms that made it
|
|
and error on the ones that did not.
|
|
|
|
Linux builds on Ubuntu 22.04 on purpose. The bundle will not run on anything older than the glibc
|
|
it was linked against, and 22.04 is the baseline [setup.md](setup.md) commits to.
|
|
|
|
Windows is not built. The bundle targets in `tauri.conf.json` are the mac and Linux ones, and the
|
|
app has never claimed Windows. Adding it is a runner in the build matrix and `msi`/`nsis` in the
|
|
targets, at which point the publish gate wants `windows-x86_64` too.
|
|
|
|
Phones do not come from this pipeline at all. The store is their update channel, and what building
|
|
for one takes is in [mobile.md](mobile.md).
|
|
|
|
## What the build needs
|
|
|
|
Three repository secrets, all already set:
|
|
|
|
- `GOOGLE_CREDENTIALS`, the contents of the real `google-credentials.json`. The build writes it to
|
|
the repo root and `build.rs` embeds it. Without it the build quietly falls back to the example
|
|
file and warns, which produces an app that runs and then says Google Calendar is not set up.
|
|
- `TAURI_SIGNING_PRIVATE_KEY` and `TAURI_SIGNING_PRIVATE_KEY_PASSWORD`, which sign the updater
|
|
artifacts. The public half is in `tauri.release.conf.json` and is baked into every build, so the
|
|
private half can never be rotated without stranding everyone who has not updated yet. It lives
|
|
in `~/.tauri/margin_calendar_updater.key` next to margin's; that copy and the password beside it
|
|
are the only ones, so back them up somewhere that is not this machine.
|
|
|
|
The OAuth client secret ends up inside the shipped binary. That is how installed apps work and
|
|
Google does not treat it as confidential: an installed client cannot keep a secret, which is why
|
|
the flow uses PKCE and why the token exchange is safe without one.
|
|
|
|
## Updates
|
|
|
|
Installed copies check
|
|
`https://github.com/priyanshujain/margin-calendar/releases/latest/download/latest.json` and update
|
|
themselves from it. `--latest` on the publish step is what moves that pointer, so a release that
|
|
fails the manifest check stays a draft and no one is offered a broken update.
|