Sync inav to Gitea
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
Make sure docs are updated / settings_md (push) Canceled after 0s
Build firmware / test (push) Canceled after 0s
Build firmware / build-SITL-Windows (push) Canceled after 0s
Build firmware / build-SITL-Mac (push) Canceled after 0s
Build firmware / build-SITL-Linux (push) Canceled after 0s
Build firmware / build-SITL-Linux-arm64 (push) Canceled after 0s
Build firmware / upload-artifacts (push) Canceled after 0s
Build firmware / build-single-target (push) Canceled after 0s
Build firmware / build (9) (push) Canceled after 0s
Build firmware / build (8) (push) Canceled after 0s
Build firmware / build (7) (push) Canceled after 0s
Build firmware / build (6) (push) Canceled after 0s
Build firmware / build (5) (push) Canceled after 0s
Build firmware / build (4) (push) Canceled after 0s
Build firmware / build (3) (push) Canceled after 0s
Build firmware / build (2) (push) Canceled after 0s
Build firmware / build (14) (push) Canceled after 0s
Build firmware / build (13) (push) Canceled after 0s
Build firmware / build (12) (push) Canceled after 0s
Build firmware / build (11) (push) Canceled after 0s
Build firmware / build (10) (push) Canceled after 0s
Build firmware / build (1) (push) Canceled after 0s
Build firmware / build (0) (push) Canceled after 0s
Build firmware / detect (push) Canceled after 0s
Build pre-release / build (push) Canceled after 0s
Build pre-release / Release (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
---
|
||||
name: "\U0001F41B Bug report"
|
||||
about: Report an issue to help make INAV better
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**PLEASE MAKE SURE YOU READ AND UNDERSTAND THE SOCIAL MEDIA SUPPORT CHANNELS. QUESTIONS ABOUT FLASHING, CONFIGURING, PILOTING MAY BE CLOSED WITHOUT FURTHER INTERACTION.**
|
||||
|
||||
* [INAV Discord Server](https://discord.gg/peg2hhbYwN)
|
||||
* [INAV Official on Facebook](https://www.facebook.com/groups/INAVOfficial)
|
||||
* [INAV Official on Telegram](https://t.me/INAVFlight)
|
||||
|
||||
**Please double-check that nobody reported the issue before by using search in this bug tracker.**
|
||||
**For Bug-Reports, please use the following template and provide as much information as possible. Bug-Reports that don't follow the template, might be closed unanswered. If you are not sure if you found a bug, ask for further input in the community channels or open a Github discussion.**
|
||||
|
||||
**PLEASE DELETE THE TEXT ABOVE AFTER READING AND UNDERSTANDING IT**
|
||||
|
||||
****
|
||||
|
||||
|
||||
## Current Behavior
|
||||
<!-- If applicable, add screenshots, videos and blackbox logs to help explain your problem. -->
|
||||
|
||||
## Steps to Reproduce
|
||||
<!-- Steps to reproduce the behavior: -->
|
||||
1.
|
||||
2.
|
||||
3.
|
||||
4.
|
||||
|
||||
## Expected behavior
|
||||
<!-- A clear and concise description of what you expected to happen. -->
|
||||
|
||||
## Suggested solution(s)
|
||||
<!-- How could we solve this issue? What changes would need to made to INAV? -->
|
||||
|
||||
## Additional context
|
||||
<!-- Add any other context about the problem here. -->
|
||||
<!-- Go to CLI, execute `diff` command copy its output to [PasteBin](https://pastebin.com) and provide a link to a paste here -->
|
||||
|
||||
---
|
||||
<!-- PLEASE FILL THIS OUT -->
|
||||
<!-- Use CLI 'version' command to get version string -->
|
||||
|
||||
- FC Board name and vendor:
|
||||
- INAV version string:
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: "\U0001F680Feature request"
|
||||
about: Suggest a new feature for INAV
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
## Current Behavior
|
||||
<!-- A clear and concise description of what is the current behavior / usecase. -->
|
||||
|
||||
## Desired Behavior
|
||||
<!-- A clear and concise description of what you want to happen. -->
|
||||
|
||||
## Suggested Solution
|
||||
<!-- Suggest a solution that the community/maintainers/you may take to enable the desired behavior -->
|
||||
<!-- NOTE: Feature Requests without suggested solutions may not be addressed with the same level of urgency as those that have suggested solutions -->
|
||||
|
||||
## Who does this impact? Who is this for?
|
||||
<!-- Who is this for? All users? Airplane users? Beginners? Advanced? Yourself? People using X, Y, Z, etc.? -->
|
||||
|
||||
## Additional context
|
||||
<!-- Add any other context or links about the feature request here. -->
|
||||
@@ -0,0 +1,38 @@
|
||||
This pull requests adds support for ``$TARGET_NAME``
|
||||
|
||||
* [ ] Target complies with ``docs/policies/NEW_HARDWARE_POLICY.md``
|
||||
|
||||
The following items have been checked and confirmed working by an INAV developer on actual hardware: (feel free to remove non-relevant items)
|
||||
|
||||
* [ ] Samples received
|
||||
* [ ] Flash firmware
|
||||
* [ ] Calibrate
|
||||
* [ ] Orientation matches
|
||||
* [ ] Gyro working
|
||||
* [ ] Accel working
|
||||
* [ ] Voltage correct
|
||||
* [ ] Current correct
|
||||
* [ ] Baro working
|
||||
* [ ] Mag I2C Bus
|
||||
* [ ] Additional I2C2 Buses (Airspeed/other accessories)
|
||||
* [ ] UART1
|
||||
* [ ] UART2
|
||||
* [ ] UART3
|
||||
* [ ] UART4
|
||||
* [ ] UART5
|
||||
* [ ] UART6
|
||||
* [ ] UART7
|
||||
* [ ] UART8
|
||||
* [ ] Analog Camera working
|
||||
* [ ] Video Out working
|
||||
* [ ] OSD working
|
||||
* [ ] LEDs working
|
||||
* [ ] Buzzer working
|
||||
* [ ] Motor outputs
|
||||
* [ ] DShot support on m1-4
|
||||
* [ ] Servo outputs
|
||||
* [ ] Blackbox
|
||||
* [ ] PINIO1
|
||||
* [ ] PINIO2
|
||||
* [ ] PINIO3
|
||||
* [ ] PINIO4
|
||||
@@ -0,0 +1,4 @@
|
||||
label-alias:
|
||||
bug: 'BUG'
|
||||
feature_request: 'Feature request'
|
||||
question: 'Support'
|
||||
@@ -0,0 +1,12 @@
|
||||
# Configuration for probot-no-response - https://github.com/probot/no-response
|
||||
|
||||
# Number of days of inactivity before an Issue is closed for lack of response
|
||||
daysUntilClose: 3
|
||||
# Label requiring a response
|
||||
responseRequiredLabel: Missing Information
|
||||
# Comment to post when closing an Issue for lack of response. Set to `false` to disable
|
||||
closeComment: >
|
||||
This issue has been automatically closed because the information we asked
|
||||
to be provided when opening it was not supplied by the original author.
|
||||
With only the information that is currently in the issue, we don't have
|
||||
enough information to take action.
|
||||
Executable
+226
@@ -0,0 +1,226 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Check if parameter group struct modifications include version increments
|
||||
# This prevents settings corruption when struct layout changes without version bump
|
||||
#
|
||||
# Exit codes:
|
||||
# 0 - No issues found
|
||||
# 1 - Potential issues detected (will post comment)
|
||||
# 2 - Script error
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Output file for issues found
|
||||
ISSUES_FILE=$(mktemp)
|
||||
trap "rm -f $ISSUES_FILE" EXIT
|
||||
|
||||
# Color output for local testing
|
||||
if [ -t 1 ]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
else
|
||||
RED=''
|
||||
GREEN=''
|
||||
YELLOW=''
|
||||
NC=''
|
||||
fi
|
||||
|
||||
echo "🔍 Checking for Parameter Group version updates..."
|
||||
|
||||
# Get base and head commits
|
||||
BASE_REF=${GITHUB_BASE_REF:-}
|
||||
HEAD_REF=${GITHUB_HEAD_REF:-}
|
||||
|
||||
if [ -z "$BASE_REF" ] || [ -z "$HEAD_REF" ]; then
|
||||
echo "⚠️ Warning: Not running in GitHub Actions PR context"
|
||||
echo "Using git diff against HEAD~1 for local testing"
|
||||
BASE_COMMIT="HEAD~1"
|
||||
HEAD_COMMIT="HEAD"
|
||||
else
|
||||
BASE_COMMIT="origin/$BASE_REF"
|
||||
HEAD_COMMIT="HEAD"
|
||||
fi
|
||||
|
||||
# Get list of changed files
|
||||
CHANGED_FILES=$(git diff --name-only $BASE_COMMIT..$HEAD_COMMIT | grep -E '\.(c|h)$' || true)
|
||||
|
||||
if [ -z "$CHANGED_FILES" ]; then
|
||||
echo "✅ No C/H files changed"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "📁 Changed files:"
|
||||
echo "$CHANGED_FILES" | sed 's/^/ /'
|
||||
|
||||
# Function to extract PG info from a file
|
||||
check_file_for_pg_changes() {
|
||||
local file=$1
|
||||
local diff_output=$(git diff $BASE_COMMIT..$HEAD_COMMIT -- "$file")
|
||||
|
||||
# Check if file contains PG_REGISTER in current version
|
||||
if ! git show $HEAD_COMMIT:"$file" 2>/dev/null | grep -q "PG_REGISTER"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo " 🔎 Checking $file (contains PG_REGISTER)"
|
||||
|
||||
# Extract all PG_REGISTER lines from the diff (both old and new)
|
||||
local pg_registers=$(echo "$diff_output" | grep -E "^[-+].*PG_REGISTER" || true)
|
||||
|
||||
if [ -z "$pg_registers" ]; then
|
||||
# PG_REGISTER exists but wasn't changed
|
||||
# Still need to check if the struct changed
|
||||
pg_registers=$(git show $HEAD_COMMIT:"$file" | grep "PG_REGISTER" || true)
|
||||
fi
|
||||
|
||||
# Process each PG registration
|
||||
while IFS= read -r pg_line; do
|
||||
[ -z "$pg_line" ] && continue
|
||||
|
||||
# Extract struct name and version
|
||||
# Pattern: PG_REGISTER.*\((\w+),\s*(\w+),\s*PG_\w+,\s*(\d+)\)
|
||||
if [[ $pg_line =~ PG_REGISTER[^(]*\(([^,]+),([^,]+),([^,]+),([^)]+)\) ]]; then
|
||||
local struct_type="${BASH_REMATCH[1]}"
|
||||
local pg_name="${BASH_REMATCH[2]}"
|
||||
local pg_id="${BASH_REMATCH[3]}"
|
||||
local version="${BASH_REMATCH[4]}"
|
||||
|
||||
# Clean up whitespace
|
||||
struct_type=$(echo "$struct_type" | xargs)
|
||||
version=$(echo "$version" | xargs)
|
||||
|
||||
echo " 📋 Found: $struct_type (version $version)"
|
||||
|
||||
# Check if this struct's typedef was modified in ANY changed file
|
||||
local struct_pattern="typedef struct ${struct_type%_t}_s"
|
||||
local struct_body_diff=""
|
||||
local struct_found_in=""
|
||||
|
||||
# Search all changed files for this struct definition
|
||||
while IFS= read -r changed_file; do
|
||||
[ -z "$changed_file" ] && continue
|
||||
|
||||
local file_diff=$(git diff $BASE_COMMIT..$HEAD_COMMIT -- "$changed_file")
|
||||
local struct_in_file=$(echo "$file_diff" | sed -n "/${struct_pattern}/,/\}.*${struct_type};/p")
|
||||
|
||||
if [ -n "$struct_in_file" ]; then
|
||||
struct_body_diff="$struct_in_file"
|
||||
struct_found_in="$changed_file"
|
||||
echo " 🔍 Found struct definition in $changed_file"
|
||||
break
|
||||
fi
|
||||
done <<< "$CHANGED_FILES"
|
||||
|
||||
local struct_changes=$(echo "$struct_body_diff" | grep -E "^[-+]" \
|
||||
| grep -v -E "^[-+]\s*(typedef struct|}|//|\*)" \
|
||||
| sed -E 's://.*$::' \
|
||||
| sed -E 's:/\*.*\*/::' \
|
||||
| tr -d '[:space:]')
|
||||
|
||||
if [ -n "$struct_changes" ]; then
|
||||
echo " ⚠️ Struct definition modified in $struct_found_in"
|
||||
|
||||
# Check if version was incremented in PG_REGISTER
|
||||
local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
|
||||
local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
|
||||
|
||||
# Find line number of PG_REGISTER for error reporting
|
||||
local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1)
|
||||
|
||||
if [ -n "$old_version" ] && [ -n "$new_version" ]; then
|
||||
# PG_REGISTER was modified - check if version increased
|
||||
if [ "$new_version" -le "$old_version" ]; then
|
||||
echo " ❌ Version NOT incremented ($old_version → $new_version)"
|
||||
cat >> $ISSUES_FILE << EOF
|
||||
### \`$struct_type\` ($file:$line_num)
|
||||
- **Struct modified:** Field changes detected in $struct_found_in
|
||||
- **Version status:** ❌ Not incremented (version $version)
|
||||
- **Recommendation:** Increment version from $old_version to $(($old_version + 1))
|
||||
|
||||
EOF
|
||||
else
|
||||
echo " ✅ Version incremented ($old_version → $new_version)"
|
||||
fi
|
||||
elif [ -z "$old_version" ] && [ -z "$new_version" ]; then
|
||||
# PG_REGISTER wasn't modified but struct was - THIS IS THE BUG!
|
||||
echo " ❌ PG_REGISTER not modified, version still $version"
|
||||
cat >> $ISSUES_FILE << EOF
|
||||
### \`$struct_type\` ($file:$line_num)
|
||||
- **Struct modified:** Field changes detected in $struct_found_in
|
||||
- **Version status:** ❌ Not incremented (still version $version)
|
||||
- **Recommendation:** Increment version to $(($version + 1)) in $file
|
||||
|
||||
EOF
|
||||
else
|
||||
# One exists but not the other - unusual edge case
|
||||
echo " ⚠️ Unusual version change pattern detected"
|
||||
cat >> $ISSUES_FILE << EOF
|
||||
### \`$struct_type\` ($file:$line_num)
|
||||
- **Struct modified:** Field changes detected in $struct_found_in
|
||||
- **Version status:** ⚠️ Unusual change pattern (old: ${old_version:-none}, new: ${new_version:-none})
|
||||
- **Current version:** $version
|
||||
- **Recommendation:** Manually verify version increment
|
||||
|
||||
EOF
|
||||
fi
|
||||
else
|
||||
echo " ✅ Struct unchanged"
|
||||
fi
|
||||
fi
|
||||
done <<< "$pg_registers"
|
||||
}
|
||||
|
||||
# Build list of files to check (changed files + companions with PG_REGISTER)
|
||||
echo "🔍 Building file list including companions with PG_REGISTER..."
|
||||
FILES_TO_CHECK=""
|
||||
ALREADY_ADDED=""
|
||||
|
||||
while IFS= read -r file; do
|
||||
[ -z "$file" ] && continue
|
||||
|
||||
# Add this file to check list
|
||||
if ! echo "$ALREADY_ADDED" | grep -qw "$file"; then
|
||||
FILES_TO_CHECK="$FILES_TO_CHECK$file"$'\n'
|
||||
ALREADY_ADDED="$ALREADY_ADDED $file"
|
||||
fi
|
||||
|
||||
# Determine companion file (.c <-> .h)
|
||||
local companion=""
|
||||
if [[ "$file" == *.c ]]; then
|
||||
companion="${file%.c}.h"
|
||||
elif [[ "$file" == *.h ]]; then
|
||||
companion="${file%.h}.c"
|
||||
fi
|
||||
|
||||
# If companion exists and contains PG_REGISTER, add it to check list
|
||||
if [ -n "$companion" ]; then
|
||||
if git show $HEAD_COMMIT:"$companion" 2>/dev/null | grep -q "PG_REGISTER"; then
|
||||
if ! echo "$ALREADY_ADDED" | grep -qw "$companion"; then
|
||||
echo " 📎 Adding $companion (companion of $file with PG_REGISTER)"
|
||||
FILES_TO_CHECK="$FILES_TO_CHECK$companion"$'\n'
|
||||
ALREADY_ADDED="$ALREADY_ADDED $companion"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done <<< "$CHANGED_FILES"
|
||||
|
||||
# Check each file (including companions)
|
||||
while IFS= read -r file; do
|
||||
[ -z "$file" ] && continue
|
||||
check_file_for_pg_changes "$file"
|
||||
done <<< "$FILES_TO_CHECK"
|
||||
|
||||
# Check if any issues were found
|
||||
if [ -s $ISSUES_FILE ]; then
|
||||
echo ""
|
||||
echo "${YELLOW}⚠️ Potential PG version issues detected${NC}"
|
||||
echo "Output saved to: $ISSUES_FILE"
|
||||
cat $ISSUES_FILE
|
||||
exit 1
|
||||
else
|
||||
echo ""
|
||||
echo "${GREEN}✅ No PG version issues detected${NC}"
|
||||
exit 0
|
||||
fi
|
||||
@@ -0,0 +1,58 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
|
||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||
daysUntilStale: 60
|
||||
|
||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||
daysUntilClose: 14
|
||||
|
||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
||||
exemptLabels:
|
||||
- BUG
|
||||
- Feature Request
|
||||
- Pinned
|
||||
|
||||
# Set to true to ignore issues in a project (defaults to false)
|
||||
exemptProjects: false
|
||||
|
||||
# Set to true to ignore issues in a milestone (defaults to false)
|
||||
exemptMilestones: true
|
||||
|
||||
# Label to use when marking as stale
|
||||
staleLabel: Inactive
|
||||
|
||||
# Comment to post when marking as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue / pull request has been automatically marked as stale because it
|
||||
has not had any activity in 60 days. The resources of the INAV team are limited,
|
||||
and so we are asking for your help.
|
||||
|
||||
This issue / pull request will be closed if no further activity occurs within two weeks.
|
||||
|
||||
|
||||
# Comment to post when removing the stale label.
|
||||
# unmarkComment: >
|
||||
# Your comment here.
|
||||
|
||||
# Comment to post when closing a stale Issue or Pull Request.
|
||||
closeComment: >
|
||||
Automatically closing as inactive.
|
||||
|
||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||
limitPerRun: 30
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
||||
# pulls:
|
||||
# daysUntilStale: 30
|
||||
# markComment: >
|
||||
# This pull request has been automatically marked as stale because it has not had
|
||||
# recent activity. It will be closed if no further activity occurs. Thank you
|
||||
# for your contributions.
|
||||
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - confirmed
|
||||
@@ -0,0 +1,127 @@
|
||||
# GitHub Actions Workflows
|
||||
|
||||
This directory contains automated CI/CD workflows for the INAV project.
|
||||
|
||||
## Active Workflows
|
||||
|
||||
### Build and Test
|
||||
|
||||
#### `ci.yml` - Build Firmware
|
||||
**Triggers:** Pull requests, pushes to maintenance branches
|
||||
**Purpose:** Compiles INAV firmware for all targets to verify builds succeed
|
||||
**Matrix:** 15 parallel build jobs for faster CI
|
||||
|
||||
#### `nightly-build.yml` - Nightly Builds
|
||||
**Triggers:** Scheduled nightly
|
||||
**Purpose:** Creates nightly development builds for testing
|
||||
|
||||
### Documentation
|
||||
|
||||
#### `docs.yml` - Documentation Build
|
||||
**Triggers:** Pull requests affecting documentation
|
||||
**Purpose:** Validates documentation builds correctly
|
||||
|
||||
### Code Quality
|
||||
|
||||
#### `pg-version-check.yml` - Parameter Group Version Check
|
||||
**Triggers:** Pull requests to maintenance-9.x and maintenance-10.x
|
||||
**Purpose:** Detects parameter group struct modifications and verifies version increments
|
||||
**Why:** Prevents settings corruption when struct layout changes without version bump
|
||||
|
||||
**How it works:**
|
||||
1. Scans changed .c/.h files for `PG_REGISTER` entries
|
||||
2. Detects if associated struct typedefs were modified
|
||||
3. Checks if the PG version parameter was incremented
|
||||
4. Posts helpful comment if version not incremented
|
||||
|
||||
**Reference:** See `docs/development/parameter_groups/` for PG system documentation
|
||||
|
||||
**Script:** `.github/scripts/check-pg-versions.sh`
|
||||
|
||||
**When to increment PG versions:**
|
||||
- ✅ Adding/removing fields from struct
|
||||
- ✅ Changing field types or sizes
|
||||
- ✅ Reordering fields
|
||||
- ✅ Adding/removing packing attributes
|
||||
- ❌ Only changing `PG_RESET_TEMPLATE` default values
|
||||
- ❌ Only changing comments
|
||||
|
||||
### Pull Request Helpers
|
||||
|
||||
#### `pr-branch-suggestion.yml` - Branch Targeting Suggestion
|
||||
**Triggers:** PRs targeting master branch
|
||||
**Purpose:** Suggests using maintenance-9.x or maintenance-10.x instead
|
||||
|
||||
#### `non-code-change.yaml` - Non-Code Change Detection
|
||||
**Triggers:** Pull requests
|
||||
**Purpose:** Detects PRs with only documentation/formatting changes
|
||||
|
||||
## Configuration Files
|
||||
|
||||
- `../.github/stale.yml` - Stale issue/PR management
|
||||
- `../.github/no-response.yml` - Auto-close issues without response
|
||||
- `../.github/issue_label_bot.yaml` - Automatic issue labeling
|
||||
|
||||
## Adding New Workflows
|
||||
|
||||
When adding workflows:
|
||||
|
||||
1. **Use descriptive names** - Make purpose clear from filename
|
||||
2. **Document in this README** - Add entry above with purpose and triggers
|
||||
3. **Set appropriate permissions** - Principle of least privilege
|
||||
4. **Test in fork first** - Verify before submitting to main repo
|
||||
5. **Handle errors gracefully** - Don't block CI unnecessarily
|
||||
|
||||
### Common Patterns
|
||||
|
||||
**Checkout with history:**
|
||||
```yaml
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
```
|
||||
|
||||
**Post PR comments:**
|
||||
```yaml
|
||||
- uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: 'Comment text'
|
||||
});
|
||||
```
|
||||
|
||||
**Run bash scripts:**
|
||||
```yaml
|
||||
- run: bash .github/scripts/script-name.sh
|
||||
env:
|
||||
GITHUB_BASE_REF: ${{ github.base_ref }}
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
Workflows use GitHub's fine-grained permissions:
|
||||
|
||||
- `contents: read` - Read repository code
|
||||
- `pull-requests: write` - Post/update PR comments
|
||||
- `actions: read` - Read workflow run data
|
||||
|
||||
## Local Testing
|
||||
|
||||
Scripts in `.github/scripts/` can be run locally:
|
||||
|
||||
```bash
|
||||
cd inav
|
||||
export GITHUB_BASE_REF=maintenance-9.x
|
||||
export GITHUB_HEAD_REF=feature-branch
|
||||
bash .github/scripts/check-pg-versions.sh
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
|
||||
- [Workflow Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)
|
||||
- [GitHub Script Action](https://github.com/actions/github-script)
|
||||
@@ -0,0 +1,382 @@
|
||||
name: Build firmware
|
||||
# Don't enable CI on push, just on PR. If you
|
||||
# are working on the main repo and want to trigger
|
||||
# a CI build submit a draft PR.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '!maintenance-8.x.x'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
- 'cmake/**'
|
||||
- 'lib/**'
|
||||
- 'docs/Settings.md'
|
||||
- 'CMakeLists.txt'
|
||||
- '*.sh'
|
||||
|
||||
workflow_call:
|
||||
#inputs:
|
||||
# release_build:
|
||||
# description: 'Specifies if it is a build that should include commit hash in hex file names or not'
|
||||
# default: false
|
||||
# required: false
|
||||
# type: boolean
|
||||
|
||||
|
||||
jobs:
|
||||
detect:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
single_target: ${{ steps.check.outputs.single_target }}
|
||||
target_names: ${{ steps.check.outputs.target_names }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Detect single-target PR
|
||||
id: check
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" != "pull_request" ]; then
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
|
||||
|
||||
if [ -z "$CHANGED" ]; then
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Fail fast if any changed file is outside src/main/target/<dir>/
|
||||
NON_TARGET=$(echo "$CHANGED" | grep -Ev '^src/main/target/[^/]+/.+' | head -1)
|
||||
if [ -n "$NON_TARGET" ]; then
|
||||
echo "Non-target file changed: $NON_TARGET — full build required"
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Count how many distinct target directories were touched
|
||||
TARGET_DIRS=$(echo "$CHANGED" | sed -n 's|^src/main/target/\([^/]*\)/.*|\1|p' | sort -u)
|
||||
DIR_COUNT=$(echo "$TARGET_DIRS" | wc -l)
|
||||
if [ "$DIR_COUNT" != "1" ]; then
|
||||
echo "$DIR_COUNT target directories changed — full build required"
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARGET_DIR="$TARGET_DIRS"
|
||||
CMAKE="src/main/target/${TARGET_DIR}/CMakeLists.txt"
|
||||
if [ ! -f "$CMAKE" ]; then
|
||||
echo "No CMakeLists.txt for $TARGET_DIR — full build required"
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARGET_NAMES=$(grep -oP '(?<=\()[^)]+' "$CMAKE" | tr '\n' ' ' | xargs)
|
||||
if [ -z "$TARGET_NAMES" ]; then
|
||||
echo "No target names in CMakeLists.txt — full build required"
|
||||
echo "single_target=false" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Single-target PR: building $TARGET_NAMES"
|
||||
echo "single_target=true" >> $GITHUB_OUTPUT
|
||||
echo "target_names=$TARGET_NAMES" >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
needs: [detect]
|
||||
if: needs.detect.outputs.single_target != 'true'
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
id: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: ${{ runner.os }}-downloads-${{ hashFiles('CMakeLists.txt') }}-${{ hashFiles('**/cmake/*')}}
|
||||
- name: Build targets (${{ matrix.id }})
|
||||
run: mkdir -p build && cd build && cmake -DWARNINGS_AS_ERRORS=ON -DCI_JOB_INDEX=${{ matrix.id }} -DCI_JOB_COUNT=${{ strategy.job-total }} -DBUILD_SUFFIX=${{ env.BUILD_SUFFIX }} -DMAIN_COMPILE_OPTIONS=-pipe -G Ninja .. && ninja -j${{ env.NUM_CORES }} ci
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: matrix-${{ env.BUILD_NAME }}.${{ matrix.id }}
|
||||
path: ./build/*.hex
|
||||
retention-days: 1
|
||||
|
||||
build-single-target:
|
||||
needs: [detect]
|
||||
if: needs.detect.outputs.single_target == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
path: downloads
|
||||
key: ${{ runner.os }}-downloads-${{ hashFiles('CMakeLists.txt') }}-${{ hashFiles('**/cmake/*')}}
|
||||
- name: Build targets (${{ needs.detect.outputs.target_names }})
|
||||
run: mkdir -p build && cd build && cmake -DWARNINGS_AS_ERRORS=ON -DBUILD_SUFFIX=${{ env.BUILD_SUFFIX }} -DMAIN_COMPILE_OPTIONS=-pipe -G Ninja .. && ninja -j${{ env.NUM_CORES }} ${{ needs.detect.outputs.target_names }}
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: matrix-${{ env.BUILD_NAME }}.single
|
||||
path: ./build/*.hex
|
||||
retention-days: 1
|
||||
|
||||
upload-artifacts:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [build, build-single-target]
|
||||
if: always() && !cancelled() && (needs.build.result == 'success' || needs.build-single-target.result == 'success')
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- name: Download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: matrix-inav-*
|
||||
merge-multiple: true
|
||||
path: binaries
|
||||
- name: Build target list
|
||||
run: |
|
||||
ls -1 binaries/*.hex | cut -d/ -f2 > targets.txt
|
||||
- name: Upload firmware images
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.BUILD_NAME }}
|
||||
path: binaries/*.hex
|
||||
- name: Upload firmware images
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: targets
|
||||
path: targets.txt
|
||||
- name: Save PR number
|
||||
if: github.event_name == 'pull_request'
|
||||
run: echo "${{ github.event.pull_request.number }}" > pr_number.txt
|
||||
- name: Upload PR number
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-number
|
||||
path: pr_number.txt
|
||||
retention-days: 1
|
||||
|
||||
build-SITL-Linux-arm64:
|
||||
runs-on: ubuntu-22.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- name: Build SITL
|
||||
run: mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j${{ env.NUM_CORES }}
|
||||
- name: Strip version number
|
||||
run: |
|
||||
for f in build_SITL/*_SITL; do
|
||||
mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//')
|
||||
done
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.BUILD_NAME }}_SITL-Linux-aarch64
|
||||
path: ./build_SITL/*_SITL
|
||||
|
||||
build-SITL-Linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- name: Build SITL
|
||||
run: mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j${{ env.NUM_CORES }}
|
||||
- name: Strip version number
|
||||
run: |
|
||||
for f in build_SITL/*_SITL; do
|
||||
mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//')
|
||||
done
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.BUILD_NAME }}_SITL-Linux
|
||||
path: ./build_SITL/*_SITL
|
||||
|
||||
build-SITL-Mac:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install ruby
|
||||
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }')
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "NUM_CORES=$(grep processor /proc/cpuinfo | wc -l)" >> $GITHUB_ENV
|
||||
- name: Build SITL
|
||||
run: |
|
||||
mkdir -p build_SITL && cd build_SITL
|
||||
cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -G Ninja ..
|
||||
ninja -j4
|
||||
- name: Strip version number
|
||||
run: |
|
||||
for f in build_SITL/*_SITL; do
|
||||
mv -v $f $(echo $f | sed -Ee 's/_[0-9]+\.[0-9]+\.[0-9]+//')
|
||||
done
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.BUILD_NAME }}_SITL-MacOS
|
||||
path: ./build_SITL/*_SITL
|
||||
|
||||
build-SITL-Windows:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: C:\tools\cygwin\bin\bash.exe -o igncr '{0}'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Cygwin
|
||||
uses: egor-tensin/setup-cygwin@v4
|
||||
with:
|
||||
packages: cmake ruby ninja gcc-g++ rubygems
|
||||
- name: Setup environment
|
||||
env:
|
||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
|
||||
run: |
|
||||
# This is the hash of the commit for the PR
|
||||
# when the action is triggered by PR, empty otherwise
|
||||
COMMIT_ID=${{ github.event.pull_request.head.sha }}
|
||||
# This is the hash of the commit when triggered by push
|
||||
# but the hash of refs/pull/<n>/merge, which is different
|
||||
# from the hash of the latest commit in the PR, that's
|
||||
# why we try github.event.pull_request.head.sha first
|
||||
COMMIT_ID=${COMMIT_ID:-${{ github.sha }}}
|
||||
BUILD_SUFFIX=ci-$(date '+%Y%m%d')-$(git rev-parse --short ${COMMIT_ID})
|
||||
VERSION=$( grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t)]/, "", $2); print $2 }' )
|
||||
echo "BUILD_SUFFIX=${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
echo "BUILD_NAME=inav-${VERSION}-${BUILD_SUFFIX}" >> $GITHUB_ENV
|
||||
|
||||
- name: Build SITL
|
||||
run: gem install getoptlong && mkdir -p build_SITL && cd build_SITL && cmake -DSITL=ON -DWARNINGS_AS_ERRORS=ON -G Ninja .. && ninja -j4
|
||||
- name: Strip version number
|
||||
run: |
|
||||
for f in ./build_SITL/*_SITL.exe; do
|
||||
mv $f $(echo $f | sed -e 's/_[0-9]\+\.[0-9]\+\.[0-9]\+//')
|
||||
done
|
||||
- name: Copy cygwin1.dll
|
||||
run: cp /bin/cygwin1.dll ./build_SITL/
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ env.BUILD_NAME }}_SITL-WIN
|
||||
path: |
|
||||
./build_SITL/*.exe
|
||||
./build_SITL/cygwin1.dll
|
||||
|
||||
test:
|
||||
#needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Run Tests
|
||||
run: mkdir -p build && cd build && cmake -DTOOLCHAIN=none -G Ninja .. && ninja check
|
||||
@@ -0,0 +1,27 @@
|
||||
name: Make sure docs are updated
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- src/main/fc/settings.yaml
|
||||
- docs/Settings.md
|
||||
push:
|
||||
paths:
|
||||
- src/main/fc/settings.yaml
|
||||
- docs/Settings.md
|
||||
|
||||
jobs:
|
||||
settings_md:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install python3-yaml
|
||||
- name: Check that Settings.md is up to date
|
||||
run: |
|
||||
cp docs/Settings.md{,.ci}
|
||||
python3 src/utils/update_cli_docs.py -q
|
||||
if ! diff -q docs/Settings.md{,.ci} >/dev/null; then
|
||||
echo "::error ::\"docs/Settings.md\" is not up to date, please run \"src/utils/update_cli_docs.py\""
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,105 @@
|
||||
name: Build pre-release
|
||||
# Don't enable CI on push, just on PR. If you
|
||||
# are working on the main repo and want to trigger
|
||||
# a CI build submit a draft PR.
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- maintenance-8.x.x
|
||||
- maintenance-9.x
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
- 'cmake/**'
|
||||
- 'lib/**'
|
||||
- 'docs/Settings.md'
|
||||
- 'CMakeLists.txt'
|
||||
- '*.sh'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build
|
||||
uses: ./.github/workflows/ci.yml
|
||||
|
||||
release:
|
||||
name: Release
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get version
|
||||
id: version
|
||||
run: |
|
||||
VERSION=$(grep project CMakeLists.txt|awk -F VERSION '{ gsub(/[ \t\)]/, "", $2); print $2 }')
|
||||
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: echo "today=$(date '+%Y%m%d')" >> $GITHUB_OUTPUT
|
||||
- name: download artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: hexes
|
||||
pattern: matrix-inav-*
|
||||
merge-multiple: true
|
||||
- name: download sitl linux
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: resources/sitl/linux
|
||||
pattern: inav-*SITL-Linux
|
||||
merge-multiple: true
|
||||
- name: download sitl linux aarch64
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: resources/sitl/linux/arm64
|
||||
pattern: inav-*SITL-Linux-aarch64
|
||||
merge-multiple: true
|
||||
- name: download sitl windows
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: resources/sitl/windows
|
||||
pattern: inav-*SITL-WIN
|
||||
merge-multiple: true
|
||||
- name: download sitl mac
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
path: resources/sitl/macos
|
||||
pattern: inav-*SITL-MacOS
|
||||
merge-multiple: true
|
||||
- name: Consolidate sitl files
|
||||
run: |
|
||||
zip -r -9 sitl-resources.zip resources/
|
||||
- name: Upload release artifacts
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: inav-${{ steps.version.outputs.version }}-dev-${{ steps.date.outputs.today }}-${{ github.run_number }}-${{ github.sha }}
|
||||
tag_name: v${{ steps.version.outputs.version }}-${{ steps.date.outputs.today }}.${{ github.run_number }}
|
||||
# To create release on a different repo, we need a token setup
|
||||
token: ${{ secrets.NIGHTLY_TOKEN }}
|
||||
repository: iNavFlight/inav-nightly
|
||||
prerelease: true
|
||||
draft: false
|
||||
#generate_release_notes: true
|
||||
make_latest: false
|
||||
files: |
|
||||
hexes/*.hex
|
||||
sitl-resources.zip
|
||||
body: |
|
||||
${{ steps.notes.outputs.notes }}
|
||||
|
||||
### Flashing
|
||||
These are nightly builds and configuration settings can be added and removed often. Flashing with Full chip erase is strongly recommended to avoid issues.
|
||||
Firmware related issues should be opened in the iNavflight/inav repository, not in inav-nightly.
|
||||
|
||||
### Repository:
|
||||
${{ github.repository }} ([link](${{ github.event.repository.html_url }}))
|
||||
|
||||
### Branch:
|
||||
${{ github.ref_name }} ([link](${{ github.event.repository.html_url }}/tree/${{ github.ref_name }}))
|
||||
|
||||
### Latest changeset:
|
||||
${{ github.event.head_commit.id }} ([link](${{ github.event.head_commit.url }}))
|
||||
|
||||
### Changes:
|
||||
${{ github.event.head_commit.message }}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
name: Build firmware
|
||||
# Don't enable CI on push, just on PR. If you
|
||||
# are working on the main repo and want to trigger
|
||||
# a CI build submit a draft PR.
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'src/**'
|
||||
- '.github/**'
|
||||
- 'cmake/**'
|
||||
- 'lib/**'
|
||||
- 'docs/Settings.md'
|
||||
- 'CMakeLists.txt'
|
||||
- '*.sh'
|
||||
|
||||
jobs:
|
||||
test:
|
||||
#needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: sudo apt-get update && sudo apt-get -y install ninja-build
|
||||
- name: Run Tests
|
||||
run: mkdir -p build && cd build && cmake -DTOOLCHAIN=none -G Ninja .. && ninja check
|
||||
@@ -0,0 +1,128 @@
|
||||
name: Parameter Group Version Check
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- maintenance-9.x
|
||||
- maintenance-10.x
|
||||
paths:
|
||||
- 'src/**/*.c'
|
||||
- 'src/**/*.h'
|
||||
|
||||
jobs:
|
||||
check-pg-versions:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout PR code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Need full history to compare with base branch
|
||||
|
||||
- name: Fetch base branch
|
||||
run: |
|
||||
git fetch origin ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}
|
||||
|
||||
- name: Run PG version check script
|
||||
id: pg_check
|
||||
run: |
|
||||
set +e # Don't fail the workflow, just capture exit code
|
||||
# Run script and capture output. Exit code 1 is expected for issues.
|
||||
# The output is captured and encoded to be passed between steps.
|
||||
output=$(bash .github/scripts/check-pg-versions.sh 2>&1)
|
||||
exit_code=$?
|
||||
echo "exit_code=${exit_code}" >> $GITHUB_OUTPUT
|
||||
echo "output<<EOF" >> $GITHUB_OUTPUT
|
||||
echo "$output" >> $GITHUB_OUTPUT
|
||||
echo "EOF" >> $GITHUB_OUTPUT
|
||||
env:
|
||||
GITHUB_BASE_REF: ${{ github.base_ref }}
|
||||
GITHUB_HEAD_REF: ${{ github.head_ref }}
|
||||
|
||||
- name: Post comment if issues found
|
||||
if: steps.pg_check.outputs.exit_code == '1'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
// Use the captured output from the previous step
|
||||
const output = '${{ steps.pg_check.outputs.output }}';
|
||||
let issuesContent = '';
|
||||
|
||||
try {
|
||||
// Extract issues from output (everything after the warning line)
|
||||
const lines = output.split('\n');
|
||||
let capturing = false;
|
||||
let issues = [];
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.includes('###')) {
|
||||
capturing = true;
|
||||
}
|
||||
if (capturing) {
|
||||
issues.push(line);
|
||||
}
|
||||
}
|
||||
|
||||
issuesContent = issues.join('\n');
|
||||
} catch (err) {
|
||||
console.log('Error capturing issues:', err);
|
||||
issuesContent = '*Unable to extract detailed issues*';
|
||||
}
|
||||
|
||||
const commentBody = '## ⚠️ Parameter Group Version Check\n\n' +
|
||||
'The following parameter groups may need version increments:\n\n' +
|
||||
issuesContent + '\n\n' +
|
||||
'**Why this matters:**\n' +
|
||||
'Modifying PG struct fields without incrementing the version can cause settings corruption when users flash new firmware. The `pgLoad()` function validates versions and will use defaults if there\'s a mismatch, preventing corruption.\n\n' +
|
||||
'**When to increment the version:**\n' +
|
||||
'- ✅ Adding/removing fields\n' +
|
||||
'- ✅ Changing field types or sizes\n' +
|
||||
'- ✅ Reordering fields\n' +
|
||||
'- ✅ Adding/removing packing attributes\n' +
|
||||
'- ❌ Only changing default values in `PG_RESET_TEMPLATE`\n' +
|
||||
'- ❌ Only changing comments\n\n' +
|
||||
'**Reference:**\n' +
|
||||
'- [Parameter Group Documentation](../docs/development/parameter_groups/)\n' +
|
||||
'- Example: [PR #11236](https://github.com/iNavFlight/inav/pull/11236) (field removal requiring version increment)\n\n' +
|
||||
'---\n' +
|
||||
'*This is an automated check. False positives are possible. If you believe the version increment is not needed, please explain in a comment.*';
|
||||
|
||||
try {
|
||||
// Check if we already commented
|
||||
const { data: comments } = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
});
|
||||
|
||||
const botComment = comments.find(comment =>
|
||||
comment.user.login === 'github-actions[bot]' &&
|
||||
comment.body.includes('Parameter Group Version Check')
|
||||
);
|
||||
|
||||
if (botComment) {
|
||||
// Update existing comment
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: botComment.id,
|
||||
body: commentBody
|
||||
});
|
||||
console.log('Updated existing PG version check comment');
|
||||
} else {
|
||||
// Post new comment
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: commentBody
|
||||
});
|
||||
console.log('Posted new PG version check comment');
|
||||
}
|
||||
} catch (err) {
|
||||
core.setFailed(`Failed to post comment: ${err}`);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
name: PR Branch Suggestion
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
suggest-branch:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Suggest maintenance branch
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const comment = `### Branch Targeting Suggestion
|
||||
|
||||
You've targeted the \`master\` branch with this PR. Please consider if a version branch might be more appropriate:
|
||||
|
||||
- **\`maintenance-9.x\`** - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.
|
||||
|
||||
- **\`maintenance-10.x\`** - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x
|
||||
|
||||
If \`master\` is the correct target for this change, no action is needed.
|
||||
|
||||
---
|
||||
*This is an automated suggestion to help route contributions to the appropriate branch.*`;
|
||||
|
||||
try {
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
});
|
||||
} catch (err) {
|
||||
core.setFailed(`Failed to post suggestion comment: ${err}`);
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
name: PR Test Builds
|
||||
|
||||
# Runs after "Build firmware" completes. Uses workflow_run (rather than
|
||||
# pull_request directly) so that secrets are available even for PRs from forks.
|
||||
#
|
||||
# Requires a repository secret PR_BUILDS_TOKEN with Contents: write access
|
||||
# to iNavFlight/pr-test-builds (fine-grained PAT or classic PAT with repo scope).
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build firmware"]
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
# Only act on pull_request-triggered runs that succeeded.
|
||||
if: >
|
||||
github.event.workflow_run.event == 'pull_request' &&
|
||||
github.event.workflow_run.conclusion == 'success'
|
||||
# Prevent concurrent runs for the same PR branch racing on the
|
||||
# release delete/create cycle.
|
||||
concurrency:
|
||||
group: pr-test-build-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
actions: read # to download artifacts from the triggering workflow run
|
||||
issues: write # github.rest.issues.* endpoints used to post PR comments
|
||||
pull-requests: write # to post the PR comment
|
||||
|
||||
steps:
|
||||
- name: Download PR number
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: pr-number
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Read PR number
|
||||
id: pr
|
||||
run: |
|
||||
PR_NUM=$(tr -dc '0-9' < pr_number.txt)
|
||||
if [ -z "$PR_NUM" ]; then
|
||||
echo "::error::Invalid PR number in artifact"
|
||||
exit 1
|
||||
fi
|
||||
echo "number=${PR_NUM}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Download firmware artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: matrix-inav-*
|
||||
merge-multiple: true
|
||||
path: hexes
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Get build info
|
||||
id: info
|
||||
run: |
|
||||
COUNT=$(find hexes -name '*.hex' -type f | wc -l)
|
||||
if [ "$COUNT" -eq 0 ]; then
|
||||
echo "::error::No .hex files found in downloaded artifacts"
|
||||
exit 1
|
||||
fi
|
||||
echo "count=${COUNT}" >> $GITHUB_OUTPUT
|
||||
echo "short_sha=$(echo '${{ github.event.workflow_run.head_sha }}' | cut -c1-7)" >> $GITHUB_OUTPUT
|
||||
|
||||
# Delete the previous release for this PR (if any) so assets are replaced
|
||||
# cleanly on each new commit. --cleanup-tag removes the old tag so it is
|
||||
# recreated fresh pointing to the new commit.
|
||||
- name: Delete existing PR release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }}
|
||||
run: |
|
||||
gh release delete "pr-${{ steps.pr.outputs.number }}" \
|
||||
--repo iNavFlight/pr-test-builds --cleanup-tag --yes 2>/dev/null || true
|
||||
|
||||
- name: Create PR release
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }}
|
||||
PR_NUMBER: ${{ steps.pr.outputs.number }}
|
||||
SHORT_SHA: ${{ steps.info.outputs.short_sha }}
|
||||
HEX_COUNT: ${{ steps.info.outputs.count }}
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
PR_URL="https://github.com/${REPO}/pull/${PR_NUMBER}"
|
||||
printf '%s\n\n%s\n\n%s\n' \
|
||||
"Test build for [PR #${PR_NUMBER}](${PR_URL}) — commit \`${SHORT_SHA}\`" \
|
||||
"**${HEX_COUNT} targets built.** Find your board's \`.hex\` file by name (e.g. \`MATEKF405SE.hex\`)." \
|
||||
"> Development build for testing only. Use Full Chip Erase when flashing." \
|
||||
> release-notes.md
|
||||
gh release create "pr-${PR_NUMBER}" hexes/*.hex \
|
||||
--repo iNavFlight/pr-test-builds \
|
||||
--prerelease \
|
||||
--title "PR #${PR_NUMBER} (${SHORT_SHA})" \
|
||||
--notes-file release-notes.md
|
||||
|
||||
- name: Post or update PR comment
|
||||
uses: actions/github-script@v7
|
||||
env:
|
||||
PR_NUMBER: ${{ steps.pr.outputs.number }}
|
||||
SHORT_SHA: ${{ steps.info.outputs.short_sha }}
|
||||
HEX_COUNT: ${{ steps.info.outputs.count }}
|
||||
with:
|
||||
script: |
|
||||
const prNumber = parseInt(process.env.PR_NUMBER, 10);
|
||||
if (isNaN(prNumber)) throw new Error(`Invalid PR number: ${process.env.PR_NUMBER}`);
|
||||
const shortSha = process.env.SHORT_SHA;
|
||||
const count = process.env.HEX_COUNT;
|
||||
const releaseUrl = `https://github.com/iNavFlight/pr-test-builds/releases/tag/pr-${prNumber}`;
|
||||
|
||||
const body = [
|
||||
'<!-- pr-test-build -->',
|
||||
'**Test firmware build ready** — commit `' + shortSha + '`',
|
||||
'',
|
||||
`[Download firmware for PR #${prNumber}](${releaseUrl})`,
|
||||
'',
|
||||
`${count} targets built. Find your board's \`.hex\` file by name on that page ` +
|
||||
'(e.g. `MATEKF405SE.hex`). Files are individually downloadable — no GitHub login required.',
|
||||
'',
|
||||
'> Development build for testing only. Use Full Chip Erase when flashing.',
|
||||
].join('\n');
|
||||
|
||||
const comments = await github.paginate(
|
||||
github.rest.issues.listComments,
|
||||
{
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
}
|
||||
);
|
||||
|
||||
const existing = comments.find(c =>
|
||||
c.user.type === 'Bot' && c.body.includes('<!-- pr-test-build -->')
|
||||
);
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
comment_id: existing.id,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: prNumber,
|
||||
body,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user