Skip to content

Commit 8099ece

Browse files
Merge pull request #11382 from iNavFlight/maintenance-9.x
Maintenance 9.x to master
2 parents da2a35c + 7cbd46a commit 8099ece

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+2264
-364
lines changed

.github/scripts/check-pg-versions.sh

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ check_file_for_pg_changes() {
5959
local file=$1
6060
local diff_output=$(git diff $BASE_COMMIT..$HEAD_COMMIT -- "$file")
6161

62-
# Check if file contains PG_REGISTER (in either old or new version)
63-
if ! echo "$diff_output" | grep -q "PG_REGISTER"; then
62+
# Check if file contains PG_REGISTER in current version
63+
if ! git show $HEAD_COMMIT:"$file" 2>/dev/null | grep -q "PG_REGISTER"; then
6464
return 0
6565
fi
6666

@@ -93,53 +93,75 @@ check_file_for_pg_changes() {
9393

9494
echo " 📋 Found: $struct_type (version $version)"
9595

96-
# Check if this struct's typedef was modified
96+
# Check if this struct's typedef was modified in ANY changed file
9797
local struct_pattern="typedef struct ${struct_type%_t}_s"
98-
# Isolate struct body from diff, remove comments and empty lines, then check for remaining changes
99-
local struct_body_diff=$(echo "$diff_output" | sed -n "/${struct_pattern}/,/\}.*${struct_type};/p")
98+
local struct_body_diff=""
99+
local struct_found_in=""
100+
101+
# Search all changed files for this struct definition
102+
while IFS= read -r changed_file; do
103+
[ -z "$changed_file" ] && continue
104+
105+
local file_diff=$(git diff $BASE_COMMIT..$HEAD_COMMIT -- "$changed_file")
106+
local struct_in_file=$(echo "$file_diff" | sed -n "/${struct_pattern}/,/\}.*${struct_type};/p")
107+
108+
if [ -n "$struct_in_file" ]; then
109+
struct_body_diff="$struct_in_file"
110+
struct_found_in="$changed_file"
111+
echo " 🔍 Found struct definition in $changed_file"
112+
break
113+
fi
114+
done <<< "$CHANGED_FILES"
115+
100116
local struct_changes=$(echo "$struct_body_diff" | grep -E "^[-+]" \
101117
| grep -v -E "^[-+]\s*(typedef struct|}|//|\*)" \
102118
| sed -E 's://.*$::' \
103119
| sed -E 's:/\*.*\*/::' \
104120
| tr -d '[:space:]')
105121

106122
if [ -n "$struct_changes" ]; then
107-
echo " ⚠️ Struct definition modified"
123+
echo " ⚠️ Struct definition modified in $struct_found_in"
108124

109-
# Check if version was incremented in this diff
125+
# Check if version was incremented in PG_REGISTER
110126
local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
111127
local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
112128

129+
# Find line number of PG_REGISTER for error reporting
130+
local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1)
131+
113132
if [ -n "$old_version" ] && [ -n "$new_version" ]; then
133+
# PG_REGISTER was modified - check if version increased
114134
if [ "$new_version" -le "$old_version" ]; then
115135
echo " ❌ Version NOT incremented ($old_version$new_version)"
116-
117-
# Find line number of PG_REGISTER
118-
local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1)
119-
120-
# Add to issues list
121136
cat >> $ISSUES_FILE << EOF
122137
### \`$struct_type\` ($file:$line_num)
123-
- **Struct modified:** Field changes detected
138+
- **Struct modified:** Field changes detected in $struct_found_in
124139
- **Version status:** ❌ Not incremented (version $version)
125-
- **Recommendation:** Review changes and increment version if needed
140+
- **Recommendation:** Increment version from $old_version to $(($old_version + 1))
126141
127142
EOF
128143
else
129144
echo " ✅ Version incremented ($old_version$new_version)"
130145
fi
131-
elif [ -z "$old_version" ] || [ -z "$new_version" ]; then
132-
# Couldn't determine version change, but struct was modified
133-
echo " ⚠️ Could not determine if version was incremented"
134-
135-
local line_num=$(git show $HEAD_COMMIT:"$file" | grep -n "PG_REGISTER.*$struct_type" | cut -d: -f1 | head -1)
146+
elif [ -z "$old_version" ] && [ -z "$new_version" ]; then
147+
# PG_REGISTER wasn't modified but struct was - THIS IS THE BUG!
148+
echo " ❌ PG_REGISTER not modified, version still $version"
149+
cat >> $ISSUES_FILE << EOF
150+
### \`$struct_type\` ($file:$line_num)
151+
- **Struct modified:** Field changes detected in $struct_found_in
152+
- **Version status:** ❌ Not incremented (still version $version)
153+
- **Recommendation:** Increment version to $(($version + 1)) in $file
136154
155+
EOF
156+
else
157+
# One exists but not the other - unusual edge case
158+
echo " ⚠️ Unusual version change pattern detected"
137159
cat >> $ISSUES_FILE << EOF
138160
### \`$struct_type\` ($file:$line_num)
139-
- **Struct modified:** Field changes detected
140-
- **Version status:** ⚠️ Unable to verify version increment
161+
- **Struct modified:** Field changes detected in $struct_found_in
162+
- **Version status:** ⚠️ Unusual change pattern (old: ${old_version:-none}, new: ${new_version:-none})
141163
- **Current version:** $version
142-
- **Recommendation:** Verify version was incremented if struct layout changed
164+
- **Recommendation:** Manually verify version increment
143165
144166
EOF
145167
fi
@@ -150,11 +172,46 @@ EOF
150172
done <<< "$pg_registers"
151173
}
152174

153-
# Check each changed file
175+
# Build list of files to check (changed files + companions with PG_REGISTER)
176+
echo "🔍 Building file list including companions with PG_REGISTER..."
177+
FILES_TO_CHECK=""
178+
ALREADY_ADDED=""
179+
154180
while IFS= read -r file; do
155-
check_file_for_pg_changes "$file"
181+
[ -z "$file" ] && continue
182+
183+
# Add this file to check list
184+
if ! echo "$ALREADY_ADDED" | grep -qw "$file"; then
185+
FILES_TO_CHECK="$FILES_TO_CHECK$file"$'\n'
186+
ALREADY_ADDED="$ALREADY_ADDED $file"
187+
fi
188+
189+
# Determine companion file (.c <-> .h)
190+
local companion=""
191+
if [[ "$file" == *.c ]]; then
192+
companion="${file%.c}.h"
193+
elif [[ "$file" == *.h ]]; then
194+
companion="${file%.h}.c"
195+
fi
196+
197+
# If companion exists and contains PG_REGISTER, add it to check list
198+
if [ -n "$companion" ]; then
199+
if git show $HEAD_COMMIT:"$companion" 2>/dev/null | grep -q "PG_REGISTER"; then
200+
if ! echo "$ALREADY_ADDED" | grep -qw "$companion"; then
201+
echo " 📎 Adding $companion (companion of $file with PG_REGISTER)"
202+
FILES_TO_CHECK="$FILES_TO_CHECK$companion"$'\n'
203+
ALREADY_ADDED="$ALREADY_ADDED $companion"
204+
fi
205+
fi
206+
fi
156207
done <<< "$CHANGED_FILES"
157208

209+
# Check each file (including companions)
210+
while IFS= read -r file; do
211+
[ -z "$file" ] && continue
212+
check_file_for_pg_changes "$file"
213+
done <<< "$FILES_TO_CHECK"
214+
158215
# Check if any issues were found
159216
if [ -s $ISSUES_FILE ]; then
160217
echo ""

.github/workflows/ci.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ jobs:
107107
with:
108108
name: targets
109109
path: targets.txt
110+
- name: Save PR number
111+
if: github.event_name == 'pull_request'
112+
run: echo "${{ github.event.pull_request.number }}" > pr_number.txt
113+
- name: Upload PR number
114+
if: github.event_name == 'pull_request'
115+
uses: actions/upload-artifact@v4
116+
with:
117+
name: pr-number
118+
path: pr_number.txt
119+
retention-days: 1
110120

111121
build-SITL-Linux-arm64:
112122
runs-on: ubuntu-22.04-arm
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: PR Test Builds
2+
3+
# Runs after "Build firmware" completes. Uses workflow_run (rather than
4+
# pull_request directly) so that secrets are available even for PRs from forks.
5+
#
6+
# Requires a repository secret PR_BUILDS_TOKEN with Contents: write access
7+
# to iNavFlight/pr-test-builds (fine-grained PAT or classic PAT with repo scope).
8+
on:
9+
workflow_run:
10+
workflows: ["Build firmware"]
11+
types: [completed]
12+
13+
jobs:
14+
publish:
15+
runs-on: ubuntu-latest
16+
# Only act on pull_request-triggered runs that succeeded.
17+
if: >
18+
github.event.workflow_run.event == 'pull_request' &&
19+
github.event.workflow_run.conclusion == 'success'
20+
# Prevent concurrent runs for the same PR branch racing on the
21+
# release delete/create cycle.
22+
concurrency:
23+
group: pr-test-build-${{ github.event.workflow_run.head_repository.full_name }}-${{ github.event.workflow_run.head_branch }}
24+
cancel-in-progress: true
25+
permissions:
26+
actions: read # to download artifacts from the triggering workflow run
27+
issues: write # github.rest.issues.* endpoints used to post PR comments
28+
pull-requests: write # to post the PR comment
29+
30+
steps:
31+
- name: Download PR number
32+
uses: actions/download-artifact@v4
33+
with:
34+
name: pr-number
35+
run-id: ${{ github.event.workflow_run.id }}
36+
github-token: ${{ secrets.GITHUB_TOKEN }}
37+
38+
- name: Read PR number
39+
id: pr
40+
run: |
41+
PR_NUM=$(tr -dc '0-9' < pr_number.txt)
42+
if [ -z "$PR_NUM" ]; then
43+
echo "::error::Invalid PR number in artifact"
44+
exit 1
45+
fi
46+
echo "number=${PR_NUM}" >> $GITHUB_OUTPUT
47+
48+
- name: Download firmware artifacts
49+
uses: actions/download-artifact@v4
50+
with:
51+
pattern: matrix-inav-*
52+
merge-multiple: true
53+
path: hexes
54+
run-id: ${{ github.event.workflow_run.id }}
55+
github-token: ${{ secrets.GITHUB_TOKEN }}
56+
57+
- name: Get build info
58+
id: info
59+
run: |
60+
COUNT=$(find hexes -name '*.hex' -type f | wc -l)
61+
if [ "$COUNT" -eq 0 ]; then
62+
echo "::error::No .hex files found in downloaded artifacts"
63+
exit 1
64+
fi
65+
echo "count=${COUNT}" >> $GITHUB_OUTPUT
66+
echo "short_sha=$(echo '${{ github.event.workflow_run.head_sha }}' | cut -c1-7)" >> $GITHUB_OUTPUT
67+
68+
# Delete the previous release for this PR (if any) so assets are replaced
69+
# cleanly on each new commit. --cleanup-tag removes the old tag so it is
70+
# recreated fresh pointing to the new commit.
71+
- name: Delete existing PR release
72+
env:
73+
GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }}
74+
run: |
75+
gh release delete "pr-${{ steps.pr.outputs.number }}" \
76+
--repo iNavFlight/pr-test-builds --cleanup-tag --yes 2>/dev/null || true
77+
78+
- name: Create PR release
79+
env:
80+
GH_TOKEN: ${{ secrets.PR_BUILDS_TOKEN }}
81+
run: |
82+
PR_NUMBER="${{ steps.pr.outputs.number }}"
83+
SHORT_SHA="${{ steps.info.outputs.short_sha }}"
84+
COUNT="${{ steps.info.outputs.count }}"
85+
PR_URL="https://github.com/${{ github.repository }}/pull/${PR_NUMBER}"
86+
87+
NOTES="Test build for [PR #${PR_NUMBER}](${PR_URL}) — commit \`${SHORT_SHA}\`
88+
89+
**${COUNT} targets built.** Find your board's \`.hex\` file by name (e.g. \`MATEKF405SE.hex\`).
90+
91+
> Development build for testing only. Use Full Chip Erase when flashing."
92+
93+
cd hexes
94+
gh release create "pr-${PR_NUMBER}" *.hex \
95+
--repo iNavFlight/pr-test-builds \
96+
--prerelease \
97+
--target "${{ github.event.workflow_run.head_sha }}" \
98+
--title "PR #${PR_NUMBER} (${SHORT_SHA})" \
99+
--notes "${NOTES}"
100+
101+
- name: Post or update PR comment
102+
uses: actions/github-script@v7
103+
env:
104+
PR_NUMBER: ${{ steps.pr.outputs.number }}
105+
SHORT_SHA: ${{ steps.info.outputs.short_sha }}
106+
HEX_COUNT: ${{ steps.info.outputs.count }}
107+
with:
108+
script: |
109+
const prNumber = parseInt(process.env.PR_NUMBER, 10);
110+
if (isNaN(prNumber)) throw new Error(`Invalid PR number: ${process.env.PR_NUMBER}`);
111+
const shortSha = process.env.SHORT_SHA;
112+
const count = process.env.HEX_COUNT;
113+
const releaseUrl = `https://github.com/iNavFlight/pr-test-builds/releases/tag/pr-${prNumber}`;
114+
115+
const body = [
116+
'<!-- pr-test-build -->',
117+
'**Test firmware build ready** — commit `' + shortSha + '`',
118+
'',
119+
`[Download firmware for PR #${prNumber}](${releaseUrl})`,
120+
'',
121+
`${count} targets built. Find your board's \`.hex\` file by name on that page ` +
122+
'(e.g. `MATEKF405SE.hex`). Files are individually downloadable — no GitHub login required.',
123+
'',
124+
'> Development build for testing only. Use Full Chip Erase when flashing.',
125+
].join('\n');
126+
127+
const comments = await github.paginate(
128+
github.rest.issues.listComments,
129+
{
130+
owner: context.repo.owner,
131+
repo: context.repo.repo,
132+
issue_number: prNumber,
133+
}
134+
);
135+
136+
const existing = comments.find(c =>
137+
c.user.type === 'Bot' && c.body.includes('<!-- pr-test-build -->')
138+
);
139+
140+
if (existing) {
141+
await github.rest.issues.updateComment({
142+
owner: context.repo.owner,
143+
repo: context.repo.repo,
144+
comment_id: existing.id,
145+
body,
146+
});
147+
} else {
148+
await github.rest.issues.createComment({
149+
owner: context.repo.owner,
150+
repo: context.repo.repo,
151+
issue_number: prNumber,
152+
body,
153+
});
154+
}

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ launch.json
4646
# Assitnow token and files for test script
4747
tokens.yaml
4848
*.ubx
49+
50+
# Local development files
51+
.semgrepignore
52+
build_sitl/

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ else()
5252
endif()
5353

5454

55-
project(INAV VERSION 9.0.0)
55+
project(INAV VERSION 9.0.1)
5656

5757

5858
enable_language(ASM)

cmake/pg_struct_sizes.reference.db

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
adcChannelConfig_t 4 0
2+
armingConfig_t 6 3
3+
barometerConfig_t 8 5
4+
batteryMetersConfig_t 24 2
5+
beeperConfig_t 12 2
6+
blackboxConfig_t 16 4
7+
compassConfig_t 24 6
8+
displayConfig_t 1 0
9+
djiOsdConfig_t 6 3
10+
escSensorConfig_t 4 1
11+
ezTuneSettings_t 12 1
12+
failsafeConfig_t 22 3
13+
featureConfig_t 4 0
14+
generalSettings_t 1 0
15+
geozone_config_t 20 0
16+
gimbalConfig_t 10 1
17+
gimbalSerialConfig_t 1 0
18+
gpsConfig_t 11 5
19+
gyroConfig_t 64 12
20+
headTrackerConfig_t 16 1
21+
imuConfig_t 16 2
22+
ledPinConfig_t 1 0
23+
logConfig_t 8 0
24+
modeActivationOperatorConfig_t 1 0
25+
motorConfig_t 10 11
26+
navConfig_t 156 7
27+
navFwAutolandConfig_t 16 0
28+
opticalFlowConfig_t 8 2
29+
osdCommonConfig_t 1 0
30+
osdConfig_t 160 15
31+
osdJoystickConfig_t 6 0
32+
pidAutotuneConfig_t 10 2
33+
pidProfile_t 292 11
34+
pitotmeterConfig_t 8 2
35+
positionEstimationConfig_t 72 8
36+
powerLimitsConfig_t 8 1
37+
rangefinderConfig_t 2 3
38+
rcControlsConfig_t 10 4
39+
reversibleMotorsConfig_t 6 0
40+
rpmFilterConfig_t 10 1
41+
rxConfig_t 36 13
42+
servoConfig_t 12 3
43+
smartportMasterConfig_t 2 0
44+
statsConfig_t 20 2
45+
systemConfig_t 40 7
46+
telemetryConfig_t 58 8
47+
timeConfig_t 4 1
48+
vtxConfig_t 55 4
49+
vtxSettingsConfig_t 12 2

0 commit comments

Comments
 (0)