Skip to content

Commit 65dd80d

Browse files
Merge pull request #11621 from sensei-hacker/update_release_guide
Update release guide with lessons from 9.1.0-RC1
2 parents b26d647 + 289dd88 commit 65dd80d

1 file changed

Lines changed: 84 additions & 21 deletions

File tree

docs/development/release-create.md

Lines changed: 84 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
This document describes the process for creating INAV firmware and configurator releases.
44

5-
> **Note:** This document is designed to be used with coding assistants (such as Claude Code) that can execute the commands and automate parts of the release process. Update this document with lessons learned after each release.
5+
> **Note:** This document is designed to be used with coding assistants (such as Claude Code) that can execute the commands and automate parts of the release process. Update this document with lessons learned after each release. Sensei has written more detailed guides for his process in the third-party repo https://github.com/sensei-hacker/inav-claude/tree/master/claude/release-manager
66
77
## CRITICAL PRINCIPLE: Verify Builds BEFORE Creating Tags
88

9-
**Never tag a commit that hasn't been proven to build successfully.**
9+
**Never tag a commit that hasn't been fully tested successfully.**
1010

1111
Order of operations:
1212
1. Merge all firmware PRs to the release branch
@@ -93,6 +93,22 @@ Version numbers are set in:
9393
- View: `jq -r .version package.json` (or `node -p "require('./package.json').version"`)
9494
- Update: `npm version <X.Y.Z> --no-git-tag-version`
9595

96+
## Version String Format (RC Releases)
97+
98+
**CRITICAL:** Establish the canonical version string before starting any release work.
99+
100+
RC version strings must use **lowercase `rc`** joined to the version with a **hyphen**:
101+
102+
| Correct | Wrong |
103+
|---------|-------|
104+
| `9.1.0-rc1` | `9.1.0-RC1` |
105+
| `9.1.0-rc2` | `9.1.0_RC2` |
106+
| `9.0.0-rc3` | `9.0.0-rc_3` |
107+
108+
The Configurator firmware flasher uses a case-sensitive regex to parse firmware filenames. Uppercase `RC` or underscore separators cause the target board name to be misread, making the firmware invisible in the flasher even after a successful release upload.
109+
110+
---
111+
96112
## Pre-Release Checklist
97113

98114
### Code Readiness
@@ -318,6 +334,20 @@ LAST_TAG=$(git describe --tags --abbrev=0)
318334
gh pr list --state merged --search "merged:>=$(git log -1 --format=%ai $LAST_TAG | cut -d' ' -f1)" --limit 100
319335
```
320336

337+
### Verify Each PR Is on the Correct Branch
338+
339+
**Before including a PR in release notes**, confirm it is actually merged into the release branch, not a future branch. `gh pr list` shows PRs by merge date regardless of target branch — a PR merged to `maintenance-10.x` will appear even though it's not in the current release.
340+
341+
```bash
342+
# Confirm a PR's merge commit exists on the release branch
343+
git log upstream/maintenance-9.x --oneline | grep <short-sha>
344+
345+
# Or check all recent merge commits on the branch
346+
git log upstream/maintenance-9.x --oneline --merges | head -30
347+
```
348+
349+
If a PR is not in that output, exclude it from the release notes.
350+
321351
### Using git log
322352

323353
```bash
@@ -403,15 +433,15 @@ make MATEKF405 MATEKF722
403433
Remove CI suffix and add RC number for RC releases:
404434

405435
```bash
406-
RC_NUM="RC2" # Empty for final releases
436+
RC_NUM="rc2" # Empty for final releases
407437

408438
# Check if any .hex files exist to avoid errors with the glob
409439
if compgen -G "*.hex" > /dev/null; then
410440
for f in *.hex; do
411441
target=$(echo "$f" | sed -E 's/inav_[0-9]+\.[0-9]+\.[0-9]+_(.*)_ci-.*/\1/')
412442
version=$(echo "$f" | sed -E 's/inav_([0-9]+\.[0-9]+\.[0-9]+)_.*/\1/')
413443
if [ -n "$RC_NUM" ]; then
414-
mv "$f" "inav_${version}_${RC_NUM}_${target}.hex"
444+
mv "$f" "inav_${version}-${RC_NUM}_${target}.hex"
415445
else
416446
mv "$f" "inav_${version}_${target}.hex"
417447
fi
@@ -429,29 +459,46 @@ Download from GitHub Actions CI:
429459
# List recent workflow runs
430460
gh run list --repo iNavFlight/inav-configurator --limit 10
431461

432-
# Download artifacts
462+
# Download artifacts (creates one subdirectory per platform artifact)
433463
gh run download <run-id> --repo iNavFlight/inav-configurator
434464

435-
# Flatten directory structure
436-
find . -mindepth 2 -type f -exec mv -t . {} +
437-
# Remove the now-empty subdirectories
438-
find . -mindepth 1 -type d -empty -delete
465+
# CRITICAL: Organize by platform — NEVER flatten all files into one directory.
466+
# Flattening can put Windows .exe files inside macOS DMGs (caused a 9.0.0 release incident).
467+
mkdir -p linux/ macos/ windows/
468+
mv INAV-Configurator_linux_*/* linux/
469+
mv INAV-Configurator_macOS*/* macos/
470+
mv INAV-Configurator_win_*/* windows/
471+
rmdir INAV-Configurator_*
439472
```
440473

441474
## Creating GitHub Releases
442475

443476
### Create Draft Release
444477

445-
```bash
446-
# Firmware
447-
cd inav
448-
gh release create <version> --draft --title "INAV <version>" --notes-file release-notes.md
449-
gh release upload <version> *.hex
478+
For RC releases, add `--prerelease` so GitHub marks them as pre-release and they don't appear as the latest stable release. Use `--target <commit-sha>` to tag a specific commit (safer than tagging the current HEAD, and works even when the local repo is locked).
450479

451-
# Configurator
452-
cd inav-configurator
453-
gh release create <version> --draft --title "INAV Configurator <version>" --notes-file release-notes.md
454-
gh release upload <version> *.zip *.dmg *.exe *.AppImage *.deb *.rpm *.msi
480+
```bash
481+
# Firmware (RC release)
482+
gh release create 9.1.0-rc1 \
483+
--repo iNavFlight/inav \
484+
--target <commit-sha> \
485+
--title "INAV 9.1.0-rc1 release candidate for testing" \
486+
--notes-file release-notes.md \
487+
--prerelease \
488+
--draft
489+
gh release upload 9.1.0-rc1 firmware-dir/*.hex --repo iNavFlight/inav
490+
491+
# Configurator (RC release)
492+
gh release create 9.1.0-rc1 \
493+
--repo iNavFlight/inav-configurator \
494+
--target <commit-sha> \
495+
--title "INAV Configurator 9.1.0-rc1 release candidate for testing" \
496+
--notes-file release-notes.md \
497+
--prerelease \
498+
--draft
499+
gh release upload 9.1.0-rc1 linux/* macos/* windows/* --repo iNavFlight/inav-configurator
500+
501+
# Final releases: same commands, omit --prerelease
455502
```
456503

457504
### Managing Release Assets
@@ -477,16 +524,32 @@ gh api -X DELETE "repos/iNavFlight/inav/releases/assets/ASSET_ID"
477524

478525
### Publish Release
479526

527+
**Publish firmware first, then verify the Configurator can see it before publishing the Configurator release.**
528+
529+
```bash
530+
# Step 1: Publish firmware release
531+
gh release edit <version> --repo iNavFlight/inav --draft=false
532+
```
533+
534+
**Step 2: Verify firmware appears in Configurator Firmware Flasher (human step)**
535+
536+
Open INAV Configurator → Firmware Flasher tab → enable "Show unstable releases". The new firmware version must appear in the release list. This confirms the GitHub release is properly formatted and the filename regex parsed correctly.
537+
538+
Also select a target whose name contains spaces (e.g., `MAMBAH743 2022B GYRO2`) and confirm it displays with spaces, not underscores — this validates that multi-word target names parsed correctly.
539+
540+
If the firmware does not appear: check that filenames follow `inav_<version>-rc<n>_<TARGET>.hex` exactly (lowercase `rc`, hyphen separator). See [Asset Naming Conventions](#asset-naming-conventions).
541+
480542
```bash
481-
gh release edit <version> --draft=false
543+
# Step 3: Publish configurator release (only after firmware verified in flasher)
544+
gh release edit <version> --repo iNavFlight/inav-configurator --draft=false
482545
```
483546

484547
## Asset Naming Conventions
485548

486-
**Firmware (RC releases):** `inav_<version>_RC<n>_<TARGET>.hex`
549+
**Firmware (RC releases):** `inav_<version>-rc<n>_<TARGET>.hex`
487550
**Firmware (final):** `inav_<version>_<TARGET>.hex`
488551

489-
**Configurator (RC releases):** `INAV-Configurator_<platform>_<version>_RC<n>.<ext>`
552+
**Configurator (RC releases):** `INAV-Configurator_<platform>_<version>-rc<n>.<ext>`
490553
**Configurator (final):** `INAV-Configurator_<platform>_<version>.<ext>`
491554

492555
## Maintenance Branches

0 commit comments

Comments
 (0)