desktop-release
Desktop Regular Release
Perform a regular desktop release from the dev branch.
This workflow is now file-driven:
apps/desktop/changelog/next.mdis the human-edited changelog draft.apps/desktop/release-plan.jsonis the human-edited release intent.pnpm --dir apps/desktop bumpapplies both inputs, writesapps/desktop/release.json, resetsapps/desktop/release-plan.json, bumps the version, createsrelease/desktop/{NEW_VERSION}, pushes it, and opens the PR.
Important notes:
mainHashis still regenerated automatically, but it is not the OTA compatibility switch anymore. Do not use it as the release decision point.runtimeVersioninapps/desktop/package.jsonis the desktop OTA compatibility key.apps/desktop/scripts/apply-release-config.impl.tswrites it during bump.- This skill covers the normal
buildandotadesktop release flow. - Do not recommend or write any other mode. The current implementation only supports
buildandota.
Pre-flight checks
- Confirm the current branch is
dev. If not, abort with a warning. - Run
git pull --rebasein the repo root to ensure the local branch is up to date. - Read:
apps/desktop/package.jsonapps/desktop/release-plan.jsonapps/desktop/release.jsonapps/desktop/bump.config.ts
- Record the current:
versionruntimeVersionrelease-plan.jsoncontents
- Note that
pnpm --dir apps/desktop bumpwill push a branch and open a PR. Do not run it without explicit user approval.
Step 1: Gather changes since last desktop release
- Find the last desktop release tag:
git tag --sort=-creatordate | grep '^desktop/v' | head -1 - Get all commits since that tag on the current branch:
git log <last-tag>..HEAD --oneline --no-merges - Categorize commits into:
- Shiny new things
- Improvements
- No longer broken
- Thanks
Step 2: Update changelog draft
- Read
apps/desktop/changelog/next.md. - Draft the changelog content from the categorized commits.
- Present the draft to the user.
- Wait for user confirmation or edits before writing.
- Write the final content to
apps/desktop/changelog/next.mdusing the existing template structure. - Keep
NEXT_VERSIONas the placeholder.apps/desktop/scripts/apply-changelog.tsreplaces it during bump.
Step 3: Choose the desktop release mode
This replaces the old mainHash decision.
Inspect runtime-affecting changes since the last desktop tag:
git diff <last-tag>..HEAD --name-only -- \
apps/desktop/layer/main/ \
apps/desktop/layer/preload/ \
apps/desktop/forge.config.cts \
apps/desktop/resources/ \
apps/desktop/scripts/ \
apps/desktop/package.json
Use this decision table:
-
buildUse this when the release requires a new binary. Typical triggers:- main process changes
- preload or IPC changes
- updater flow changes
- Electron / Forge / packaging / signing changes
- native resource changes
- dependency or package changes that affect runtime behavior
-
otaUse this when the release is renderer-compatible with an already-installed binary. Typical triggers:- renderer UI changes
- web behavior changes
- shared frontend logic changes that do not require a new desktop binary
For
ota, you must choose:runtimeVersion: the newest installed desktop binary version that this renderer update is compatible withchannel: usuallystable
If you are unsure whether a change is binary-compatible, prefer
build.
Present the analysis to the user with:
- changed runtime-affecting files
- summary of what changed
- recommended mode:
buildorota - recommended
release-plan.json - explicit request for confirmation
Step 4: Update release inputs
- Edit
apps/desktop/changelog/next.md. - Edit
apps/desktop/release-plan.json. - Do not edit
apps/desktop/release.jsondirectly. It is generated during bump. - Because
nbumprequires a clean working tree, commit the release inputs before bump.
Stage the inputs:
git add apps/desktop/changelog/next.md apps/desktop/release-plan.json
Commit them on dev:
git commit -m "docs(desktop): prepare release inputs"
If there are no changes to commit, continue.
Step 5: Run the bump
Do not execute this step until the user explicitly approves pushing code.
Run:
pnpm --dir apps/desktop bump
This command currently does all of the following:
- pulls latest changes
- applies the changelog
- regenerates
mainHash - runs
apps/desktop/scripts/apply-release-config.ts ${NEW_VERSION} - writes
apps/desktop/release.json - updates
apps/desktop/package.jsonruntimeVersion - resets
apps/desktop/release-plan.jsonback to the defaultbuildtemplate - commits
release(desktop): release v{NEW_VERSION} - creates
release/desktop/{NEW_VERSION} - pushes the branch
- creates a PR to
main
Step 6: Verify the generated release state
After bump completes, verify:
- Current branch is
release/desktop/{NEW_VERSION}. apps/desktop/package.jsonhas the expected:versionruntimeVersion
apps/desktop/release.jsonmatches the intended mode and release settings.apps/desktop/release-plan.jsonwas reset to the default template.- The PR was created successfully.
Also note what will happen after merge:
- merging the PR to
maintriggers.github/workflows/tag.yml tag.ymlcreatesdesktop/v{NEW_VERSION}tag.ymldispatches.github/workflows/build-desktop.ymlbuild-desktop.ymlpublishes the desktop release draft
Expected release artifacts by mode:
-
buildpublishes binary artifacts and desktop binary metadata (ota-release.json) -
otapublishes binary artifacts, desktop binary metadata, and renderer OTA assets such as:apps/desktop/dist/manifest.ymlapps/desktop/dist/*.tar.gzapps/desktop/dist/ota-release.jsonapps/desktop/dist.tar.zst
Step 7: Report back to the user
Summarize:
- new version:
v{NEW_VERSION} - release mode:
buildorota runtimeVersion- renderer OTA included: yes or no
- release branch
- PR URL
- short changelog highlights
When mentioning mainHash, only describe it as "regenerated automatically", never as the release decision mechanism.
Reference
- Bump config:
apps/desktop/bump.config.ts - Changelog dir:
apps/desktop/changelog/ - Changelog template:
apps/desktop/changelog/next.template.md - Changelog apply script:
apps/desktop/scripts/apply-changelog.ts - Release plan input:
apps/desktop/release-plan.json - Generated release config:
apps/desktop/release.json - Release config apply script:
apps/desktop/scripts/apply-release-config.impl.ts - Desktop release config resolver:
.github/scripts/resolve-desktop-release-config.mjs - Desktop OTA metadata builder:
.github/scripts/build-ota-release.mjs - Desktop build workflow:
.github/workflows/build-desktop.yml - Tag orchestrator:
.github/workflows/tag.yml - Desktop hot updater:
apps/desktop/layer/main/src/updater/hot-updater.ts
More from rssnext/folo
update-deps
Update all dependencies across frontend and backend projects. Reads changelogs for breaking changes, checks affected code, runs tests, and provides a summary. Use when updating npm dependencies across the monorepo.
19mobile-self-test
Self-test a mobile feature change or bug fix after implementation in `apps/mobile`. Use this whenever the user asks to verify a mobile change, run simulator acceptance, smoke-test a mobile PR, or provide screenshot proof for a mobile fix. This skill decides between prod vs local API mode, starts the local follow-server when needed, builds a release app, uses Maestro only to bootstrap registration for non-auth work, then switches to screenshot-driven visual validation and returns screenshot evidence.
4mobile-release
Use when preparing a mobile release from the dev branch and deciding whether changes should ship through the app stores or through the OTA pipeline before creating the release PR to mobile-main.
3mobile-e2e
Run apps/mobile Maestro end-to-end tests in this repo. Use when an agent needs to validate mobile auth flows on iOS Simulator or Android Emulator. Current maintained coverage is register, sign out, and sign in.
3