Skip to content

Lemonade Release Process

This guide documents the end-to-end process of releasing Lemonade.

Quality

Lemonade has built its brand on quality and ease-of-use. Do not release a new Lemonade version if this is compromised in any way. Carefully monitor the state of the upcoming release using https://lemonade-server.ai/repo-manager.

Release Cadence

Lemonade operates on a weekly release cadence, with new releases coming out each Wednesday morning. Each release is managed by a core maintainer on a rotating basis.

It is highly recommended that any PR targeting a particular release be in a highly-reviewed state by Monday morning on the week of that release. Maintainers reserve the right to postpone merging any PR until after the release, in order to prioritize quality.

Step 1: Update the Version

The single source of truth for Lemonade's version number is near the top of CMakeLists.txt. This number must be updated prior to creating a release.

Version numbers should always have the format major.minor.patch.

Decide the new version number using these criteria: - major release: Must include either a feature that fundamentally changes how people see Lemonade or highly disruptive breaking changes (we try to avoid those now...) - Discuss with other core maintainers before changing the major version. - Examples of past major releases: changing from Python to C++, adding NPU support on Linux. - minor release: Includes at least one headlining feature with broad appeal. - Most releases are minor releases because code velocity on this project is high enough that a new headline feature lands every couple of days. - patch release: release only contains fixes or less-visible features. - patch releases are rare, and typically only happen if a serious bug needs to be fixed right after a major/minor release.

Step 2: Create the Release Branch

Each release is developed and tagged from a dedicated release branch, not from main. Create the branch from the tip of main once the release is ready to stabilize:

git checkout main
git pull
git checkout -b release-vX.Y.Z
git push origin release-vX.Y.Z

Managing the Release Branch

Two situations arise while the release branch is open:

Backport a fix from main to the release branch (most common — a fix merged to main that should also land in this release):

# Find the squash-merge commit SHA on main
git log main --oneline | head -10

git checkout release-vX.Y.Z
git cherry-pick <commit-sha>
git push origin release-vX.Y.Z

The release branch has no squash-merge PR requirement, so a direct push works fine.

Forward-port a commit from the release branch back to main (rare — a fix made directly on the release branch that was never on main):

Because main requires squash merges for PRs, do not use a PR — it would collapse the cherry-picked commit into a squash commit, destroying authorship and history. Push directly with an admin bypass instead:

git checkout main
git pull
git cherry-pick <commit-sha-from-release-branch>
git push origin main   # requires admin "bypass branch protections" permission

Confirm with the team before pushing directly to main.

Step 3: Push a Tag

Lemonade releases are automatically created by the cpp_server_build_test_release.yml workflow final step, which is triggered by pushing a tag that matches the v* pattern. The tag must match the pattern v<major>.<minor>.<patch>, i.e., the value from CMakeLists.txt with a leading v.

Let's say you're releasing v10.8.0, this will trigger the release action:

# Make sure you are tagging the right commit!
git checkout release-v10.8.0
git pull

git tag v10.8.0

git push origin v10.8.0

Example action from v10.7.0: https://github.com/lemonade-sdk/lemonade/actions/runs/27283434473/job/80590025966

Step 4: Windows Signing

Lemonade .msi artifacts are signed by SignPath.io under their SignPath Foundation program. Thank you SignPath!

Every release must be manually approved on SignPath. After the Windows installer is built by the release action, a job called Sign MSI Installers with SignPath will start.

Example from v10.7.0: https://github.com/lemonade-sdk/lemonade/actions/runs/27283434473/job/80587971984

The log will include a link like this:

You can view the signing request here: https://app.signpath.io/Web/8103545b-7814-4edc-86d6-a91dc2a2291b/SigningRequests/7eab3b1c-0ad2-4a65-93a5-683a8065e926

You must click the link, sign in, and press Approve.

Step 5: Release Action Finishes

Wait for the cpp_server_build_test_release.yml action to complete successfully. Sometimes it doesn't, because of a false negative on a test or because we renamed a workflow step or release artifact and forgot to update the release step.

If it fails, ideally you can press "rerun" on the job and get success.

If you need to fix the code, push the fix to the release branch. Then move the tag to the new head and force push it to origin:

git checkout release-vX.Y.Z
# ... make fix, commit ...
git push origin release-vX.Y.Z
git tag -f vX.Y.Z
git push origin vX.Y.Z --force

Step 6: Update the Release Notes

The release action auto-generates release notes that include the Headline and Breaking Changes sections pulled from the open GitHub issue titled vX.Y.Z release notes (exact match on the tag name, e.g. v10.8.0 release notes). The result looks like this: https://github.com/lemonade-sdk/lemonade/releases/tag/v10.7.0

You may need to manually edit the release to: - add co-author contributors who were missing - add deprecation notices - add/remove links to release artifacts that we forgot to update in the release workflow.

DO NOT add or replace release artifacts, as this would break the chain of custody for the release and damage our credibility with users.

Headline

The headline section starts with ## Headline and contains a single-depth bulleted list. The website at https://lemonade-server.ai parses this section, so the format must be preserved.

The list should be the 3-5 most noteworthy aspects of the release. Keep items concise; no special formatting or links, no shoutouts.

Breaking Changes

Bulleted list with one item per breaking change. Keep it concise, and link to a wiki article for migration if more details are needed.

Step 7: Discord Announcement

Each release gets a post in #announcements on the Lemonade Discord.

  • Major and Minor releases: @everyone
  • Patch releases: @release

This announcement should create excitement for the release and give shout outs to everyone who contributed

Suggested structure: - Introduction sentence - News (if any) - Breaking changes: copied from release notes - One section per headline from the release notes, with 1-2 sentences explaining it. - Additional Improvements section with a bulleted list, one bullet per notable contribution

Try to find an appealing narrative arc for the release, and implement it by combining contributions into sections/bullets. For example, if there were 3 contributions by 3 authors for LMX models, say "Authors X, Y, and Z teamed up to improve in LMX..."

Step 8: Social Media

Not required, but it is always good to promote the new release online.