Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
345 changes: 345 additions & 0 deletions docs/development/release-create.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High-level Suggestion

The new documentation outlines a complex manual release process. This process should be automated, for example via a GitHub Actions workflow, to improve reliability and reduce human error, using the new document as a blueprint. [High-level, importance: 9]

Solution Walkthrough:

Before:

# Manual process from docs/development/release-create.md

# 1. Manually update SITL binaries
curl -L -o /tmp/sitl-resources.zip ...
unzip ...
cp ...
git commit -m "Update SITL binaries for <version>"

# 2. Manually create tags in two repos
cd inav && git tag <version> && git push origin <version>
cd inav-configurator && git tag <version> && git push origin <version>

# 3. Manually generate changelog
gh pr list --state merged ...

# 4. Manually download, rename, and upload artifacts
gh release download <nightly-tag> ...
# ... manual renaming script ...
gh release create <version> --draft ...
gh release upload <version> *.hex

After:

# .github/workflows/create-release.yml
name: Create Release
on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Release version (e.g., 8.0.0)'
        required: true
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run Release Automation Script
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          VERSION: ${{ github.inputs.version }}
        run: |
          ./scripts/release.sh $VERSION
          # This script would perform all steps:
          # - Update SITL binaries
          # - Tag both repositories
          # - Generate changelog
          # - Download, rename, and prepare artifacts
          # - Create draft releases on GitHub with all assets

Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
# Creating INAV Releases

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

> **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.

## Overview

INAV releases include both firmware (for flight controllers) and the configurator application (for configuration). Both repositories must be tagged with matching version numbers.

**Repositories:**
- Firmware: https://github.com/iNavFlight/inav
- Configurator: https://github.com/iNavFlight/inav-configurator

## Version Numbering

INAV uses semantic versioning: `MAJOR.MINOR.PATCH`

- **MAJOR:** Breaking changes, major new features
- **MINOR:** New features, significant improvements
- **PATCH:** Bug fixes, minor improvements

Version numbers are set in:
- Firmware: in `CMakeLists.txt` via `project(INAV VERSION X.Y.Z)`
Verify/update:
- View: `grep -E 'project\\(INAV VERSION' CMakeLists.txt`
- Update: edit `CMakeLists.txt` to set the desired version
- Configurator: in `package.json` field `"version"`
Verify/update:
- View: `jq -r .version package.json` (or `node -p "require('./package.json').version"`)
- Update: `npm version <X.Y.Z> --no-git-tag-version`

## Pre-Release Checklist

### Code Readiness

- [ ] All planned PRs merged
- [ ] CI passing on master branch
- [ ] No critical open issues blocking release
- [ ] Version numbers updated in both repositories
- [ ] SITL binaries updated in configurator

### Documentation

- [ ] Release notes drafted
- [ ] Breaking changes documented
- [ ] New features documented

## Release Workflow

```
1. Verify release readiness
├── All PRs merged
├── CI passing
└── Version numbers updated

2. Update SITL binaries in Configurator
├── Download from nightly or build for each platform
└── Commit updated binaries to configurator repo

3. Create tags
├── inav: git tag <version>
└── inav-configurator: git tag <version>

4. Generate changelog
├── List PRs since last tag
├── Categorize changes
└── Format release notes

5. Download/build artifacts
├── Firmware: from nightly builds
└── Configurator: from CI artifacts

6. Create draft releases
├── Upload firmware artifacts
├── Upload configurator artifacts
└── Add release notes

7. Review and publish
├── Maintainer review
└── Publish releases
```

## Updating SITL Binaries

SITL binaries must be updated before tagging the configurator. They are stored in:
```
inav-configurator/resources/public/sitl/
├── linux/
│ ├── inav_SITL
│ └── arm64/inav_SITL
├── macos/
│ └── inav_SITL
└── windows/
├── inav_SITL.exe
└── cygwin1.dll
```

### Download from Nightly

```bash
# Find matching nightly release
gh release list --repo iNavFlight/inav-nightly --limit 5

# Download SITL resources
curl -L -o /tmp/sitl-resources.zip \
"https://github.com/iNavFlight/inav-nightly/releases/download/<tag>/sitl-resources.zip"
unzip /tmp/sitl-resources.zip -d /tmp/sitl-extract

# Copy to configurator
cd inav-configurator
cp /tmp/sitl-extract/resources/sitl/linux/inav_SITL resources/public/sitl/linux/
cp /tmp/sitl-extract/resources/sitl/linux/arm64/inav_SITL resources/public/sitl/linux/arm64/
cp /tmp/sitl-extract/resources/sitl/macos/inav_SITL resources/public/sitl/macos/
cp /tmp/sitl-extract/resources/sitl/windows/inav_SITL.exe resources/public/sitl/windows/

# Commit
git add resources/public/sitl/
git commit -m "Update SITL binaries for <version>"
```

## Tagging

### Check Latest Tags

```bash
# Firmware
cd inav
git fetch --tags
git tag --sort=-v:refname | head -10

# Configurator
cd inav-configurator
git fetch --tags
git tag --sort=-v:refname | head -10
```

### Create New Tags

```bash
# Firmware
cd inav
git checkout master && git pull
git tag -a <version> -m "INAV <version>"
git push origin <version>

# Configurator
cd inav-configurator
git checkout master && git pull
git tag -a <version> -m "INAV Configurator <version>"
git push origin <version>
```

## Changelog Generation

### List PRs Since Last Tag

```bash
cd inav
LAST_TAG=$(git describe --tags --abbrev=0)
gh pr list --state merged --search "merged:>=$(git log -1 --format=%ai $LAST_TAG | cut -d' ' -f1)" --limit 100
```

### Using git log

```bash
LAST_TAG=$(git describe --tags --abbrev=0)
git log $LAST_TAG..HEAD --oneline --merges
```

### Changelog Format

```markdown
## INAV <version> Release Notes

### Firmware Changes

#### New Features
- PR #1234: Description (@contributor)

#### Bug Fixes
- PR #1236: Description (@contributor)

#### Improvements
- PR #1237: Description (@contributor)

### Configurator Changes

#### New Features
- PR #100: Description (@contributor)

### Full Changelog
**Firmware:** https://github.com/iNavFlight/inav/compare/<prev-tag>...<new-tag>
**Configurator:** https://github.com/iNavFlight/inav-configurator/compare/<prev-tag>...<new-tag>
```

## Downloading Release Artifacts

### Firmware Hex Files

Firmware is available from the nightly build system:

```bash
# List recent nightlies
gh release list --repo iNavFlight/inav-nightly --limit 5

# Download hex files
gh release download <nightly-tag> --repo iNavFlight/inav-nightly --pattern "*.hex"
```

#### Renaming Firmware Files

Remove CI suffix and add RC number for RC releases:

```bash
RC_NUM="RC2" # Empty for final releases

# Check if any .hex files exist to avoid errors with the glob
if compgen -G "*.hex" > /dev/null; then
for f in *.hex; do
target=$(echo "$f" | sed -E 's/inav_[0-9]+\.[0-9]+\.[0-9]+_(.*)_ci-.*/\1/')
version=$(echo "$f" | sed -E 's/inav_([0-9]+\.[0-9]+\.[0-9]+)_.*/\1/')
if [ -n "$RC_NUM" ]; then
mv "$f" "inav_${version}_${RC_NUM}_${target}.hex"
else
mv "$f" "inav_${version}_${target}.hex"
fi
done
else
echo "No .hex files found to rename."
fi
```

### Configurator Builds

Download from GitHub Actions CI:

```bash
# List recent workflow runs
gh run list --repo iNavFlight/inav-configurator --limit 10

# Download artifacts
gh run download <run-id> --repo iNavFlight/inav-configurator

# Flatten directory structure
find . -mindepth 2 -type f -exec mv -t . {} +
# Remove the now-empty subdirectories
find . -mindepth 1 -type d -empty -delete
```

## Creating GitHub Releases

### Create Draft Release

```bash
# Firmware
cd inav
gh release create <version> --draft --title "INAV <version>" --notes-file release-notes.md
gh release upload <version> *.hex

# Configurator
cd inav-configurator
gh release create <version> --draft --title "INAV Configurator <version>" --notes-file release-notes.md
gh release upload <version> *.zip *.dmg *.exe *.AppImage *.deb *.rpm *.msi
```

### Managing Release Assets

#### Rename Assets via API

```bash
# Get release and asset IDs
gh api repos/iNavFlight/inav/releases --jq '.[] | select(.draft == true) | {id: .id, name: .name}'
gh api repos/iNavFlight/inav/releases/RELEASE_ID/assets --paginate --jq '.[] | "\(.id) \(.name)"'

# Rename an asset
gh api -X PATCH "repos/iNavFlight/inav/releases/assets/ASSET_ID" -f name="new-filename.hex"
```

#### Delete Outdated Assets from Draft Release

If a draft release has outdated assets that need to be replaced (e.g., from a previous upload attempt), delete them before uploading new ones:

```bash
gh api -X DELETE "repos/iNavFlight/inav/releases/assets/ASSET_ID"
```

### Publish Release

```bash
gh release edit <version> --draft=false
```

## Asset Naming Conventions

**Firmware (RC releases):** `inav_<version>_RC<n>_<TARGET>.hex`
**Firmware (final):** `inav_<version>_<TARGET>.hex`

**Configurator (RC releases):** `INAV-Configurator_<platform>_<version>_RC<n>.<ext>`
**Configurator (final):** `INAV-Configurator_<platform>_<version>.<ext>`

## Maintenance Branches

When releasing a new major version, create maintenance branches:

- **maintenance-X.x** - For bugfixes to version X
- **maintenance-(X+1).x** - For breaking changes targeting the next major version

### Creating Maintenance Branches

```bash
COMMIT_SHA="<full-40-char-sha>"

# inav
gh api repos/iNavFlight/inav/git/refs -f ref="refs/heads/maintenance-9.x" -f sha="$COMMIT_SHA"

# inav-configurator
gh api repos/iNavFlight/inav-configurator/git/refs -f ref="refs/heads/maintenance-9.x" -f sha="$COMMIT_SHA"
```

### Branch Usage

- **X.x bugfixes** → PR to maintenance-X.x
- **Breaking changes** → PR to maintenance-(X+1).x
- **Non-breaking features** → PR to master

Lower version branches are periodically merged into higher version branches (e.g., maintenance-9.x → maintenance-10.x → master).

## Hotfix Releases

For critical bugs discovered after release:

1. Create hotfix branch from release tag
2. Cherry-pick or create fix
3. Tag as `X.Y.Z+1` (patch increment)
4. Build and release following normal process
5. Document as hotfix in release notes

## Post-Release Tasks

- [ ] Announce release (Discord, forums, etc.)
- [ ] Update any pinned issues
- [ ] Monitor for critical bug reports
- [ ] Prepare hotfix if needed
- [ ] Update this document with any lessons learned