Releasing
How to cut a palmimo-devkit release: a SemVer tag and one GitHub Release.
A release marks a validated SDK revision with human-readable notes — it
carries no asset, and it does not push anything to any device. If you have
a clone of this repository, you update by fetching and checking out the
tag (or by pulling main), not by downloading anything from the release
page.
Palmimo Portal is a separate product, maintained in its own repository; it self-updates from there, independently of this repository’s releases.
1. Versioning
Section titled “1. Versioning”- Tags are SemVer:
vX.Y.Z, optionally with a pre-release suffix likevX.Y.Z-rc1. - One tag = one GitHub Release.
- Never delete or move a published tag — publish a newer tag instead of correcting an old one in place.
- A tag with a
-suffix (e.g.v1.2.0-rc1) is created as a GitHub pre-release automatically (see What CI does below).GET repos/{repo}/releases/latestignores both drafts and pre-releases, so a pre-release build can never become “the latest release” by accident.
2. Before tagging
Section titled “2. Before tagging”-
Bump
versioninpyproject.tomlandpackages/palmimo_sdk/pyproject.toml. -
Regenerate both lockfiles so they record the new versions – CI’s
lockandintegration-lerobotjobs check them and fail on a bare pyproject bump:Terminal window uv lockcd integrations/lerobot && uv lock -
Put all four files (the two
pyproject.tomls and the twouv.locks) in one pull request. Merge it, and confirm CI is green onmain. -
Walk raspberry-pi-setup.md end to end from a blank card before tagging, and record the board, image, and result in the release notes.
-
Tag the merged commit:
Terminal window git tag -a vX.Y.Z -m "vX.Y.Z"git push origin vX.Y.Z
Who may do this: every member of the GitHub organization has write access
to this repository, and write access is all it takes to push a tag, run
the release workflow, and publish the resulting draft. There is no
separate release role on purpose. The workflow refuses a tag that is not
on main, and the human gate is section 4 (Publish) below — reading the draft before
publishing it.
3. What CI does
Section titled “3. What CI does”Pushing a v* tag triggers .github/workflows/release.yml:
- Verifies the tagged commit is actually an ancestor of
main— refuses to build a release from a tag pushed at a stray commit. - Creates the release as a draft, with GitHub’s auto-generated notes
(shaped by
.github/release.yml— see Labels below). If the tag name contains a-(a pre-release build), the release is created with--prereleaseso it can never surface asreleases/latest.
Re-running the workflow for a tag that already has a release does nothing if that release already exists — draft or published. Re-running it for a tag whose release has already been published still refuses to touch it: cut a new tag instead.
4. Publish
Section titled “4. Publish”- Open the draft release on GitHub.
- Review the generated notes against the template below, and paste in the hand-written top block.
- For a real release (not a pre-release), tick “Set as the latest release”.
- Publish.
5. Labels that drive the notes
Section titled “5. Labels that drive the notes”Label a pull request with one of these before merging so
.github/release.yml files it under the right heading:
| Label | Heading |
|---|---|
breaking-change |
Breaking changes |
sdk, motion |
SDK & motions |
example, integration |
Examples & integrations |
bug |
Fixes |
documentation |
Documentation |
skip-changelog |
excluded entirely |
dependencies |
excluded entirely |
| (none of the above) | Other changes |
6. Verifying a release
Section titled “6. Verifying a release”gh release view vX.Y.ZRelease notes template
Section titled “Release notes template”GitHub has no free-form release-template file — .github/release.yml only
shapes the auto-generated “What’s Changed” section. Paste this hand-written
block above it when publishing:
## Highlights
- 2-4 bullets on what this release is for
## Upgrade notes
- Anything a user must do or expect when updating a clone to this tag
## Known issues
- Anything shipped with a known gap, and its workaround if any
<!-- GitHub's generated "What's Changed" section follows below -->
