Skip to content

Commit f4dc128

Browse files
Merge pull request #11272 from sensei-hacker/ci/pg-version-check-action
Add GitHub Action to detect Parameter Group version increment issues
2 parents 8edf2de + 41cfcfb commit f4dc128

File tree

3 files changed

+430
-0
lines changed

3 files changed

+430
-0
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
#!/bin/bash
2+
#
3+
# Check if parameter group struct modifications include version increments
4+
# This prevents settings corruption when struct layout changes without version bump
5+
#
6+
# Exit codes:
7+
# 0 - No issues found
8+
# 1 - Potential issues detected (will post comment)
9+
# 2 - Script error
10+
11+
set -euo pipefail
12+
13+
# Output file for issues found
14+
ISSUES_FILE=$(mktemp)
15+
trap "rm -f $ISSUES_FILE" EXIT
16+
17+
# Color output for local testing
18+
if [ -t 1 ]; then
19+
RED='\033[0;31m'
20+
GREEN='\033[0;32m'
21+
YELLOW='\033[1;33m'
22+
NC='\033[0m' # No Color
23+
else
24+
RED=''
25+
GREEN=''
26+
YELLOW=''
27+
NC=''
28+
fi
29+
30+
echo "🔍 Checking for Parameter Group version updates..."
31+
32+
# Get base and head commits
33+
BASE_REF=${GITHUB_BASE_REF:-}
34+
HEAD_REF=${GITHUB_HEAD_REF:-}
35+
36+
if [ -z "$BASE_REF" ] || [ -z "$HEAD_REF" ]; then
37+
echo "⚠️ Warning: Not running in GitHub Actions PR context"
38+
echo "Using git diff against HEAD~1 for local testing"
39+
BASE_COMMIT="HEAD~1"
40+
HEAD_COMMIT="HEAD"
41+
else
42+
BASE_COMMIT="origin/$BASE_REF"
43+
HEAD_COMMIT="HEAD"
44+
fi
45+
46+
# Get list of changed files
47+
CHANGED_FILES=$(git diff --name-only $BASE_COMMIT..$HEAD_COMMIT | grep -E '\.(c|h)$' || true)
48+
49+
if [ -z "$CHANGED_FILES" ]; then
50+
echo "✅ No C/H files changed"
51+
exit 0
52+
fi
53+
54+
echo "📁 Changed files:"
55+
echo "$CHANGED_FILES" | sed 's/^/ /'
56+
57+
# Function to extract PG info from a file
58+
check_file_for_pg_changes() {
59+
local file=$1
60+
local diff_output=$(git diff $BASE_COMMIT..$HEAD_COMMIT -- "$file")
61+
62+
# Check if file contains PG_REGISTER (in either old or new version)
63+
if ! echo "$diff_output" | grep -q "PG_REGISTER"; then
64+
return 0
65+
fi
66+
67+
echo " 🔎 Checking $file (contains PG_REGISTER)"
68+
69+
# Extract all PG_REGISTER lines from the diff (both old and new)
70+
local pg_registers=$(echo "$diff_output" | grep -E "^[-+].*PG_REGISTER" || true)
71+
72+
if [ -z "$pg_registers" ]; then
73+
# PG_REGISTER exists but wasn't changed
74+
# Still need to check if the struct changed
75+
pg_registers=$(git show $HEAD_COMMIT:"$file" | grep "PG_REGISTER" || true)
76+
fi
77+
78+
# Process each PG registration
79+
while IFS= read -r pg_line; do
80+
[ -z "$pg_line" ] && continue
81+
82+
# Extract struct name and version
83+
# Pattern: PG_REGISTER.*\((\w+),\s*(\w+),\s*PG_\w+,\s*(\d+)\)
84+
if [[ $pg_line =~ PG_REGISTER[^(]*\(([^,]+),([^,]+),([^,]+),([^)]+)\) ]]; then
85+
local struct_type="${BASH_REMATCH[1]}"
86+
local pg_name="${BASH_REMATCH[2]}"
87+
local pg_id="${BASH_REMATCH[3]}"
88+
local version="${BASH_REMATCH[4]}"
89+
90+
# Clean up whitespace
91+
struct_type=$(echo "$struct_type" | xargs)
92+
version=$(echo "$version" | xargs)
93+
94+
echo " 📋 Found: $struct_type (version $version)"
95+
96+
# Check if this struct's typedef was modified
97+
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")
100+
local struct_changes=$(echo "$struct_body_diff" | grep -E "^[-+]" \
101+
| grep -v -E "^[-+]\s*(typedef struct|}|//|\*)" \
102+
| sed -E 's://.*$::' \
103+
| sed -E 's:/\*.*\*/::' \
104+
| tr -d '[:space:]')
105+
106+
if [ -n "$struct_changes" ]; then
107+
echo " ⚠️ Struct definition modified"
108+
109+
# Check if version was incremented in this diff
110+
local old_version=$(echo "$diff_output" | grep "^-.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
111+
local new_version=$(echo "$diff_output" | grep "^+.*PG_REGISTER.*$struct_type" | grep -oP ',\s*\K\d+(?=\s*\))' || echo "")
112+
113+
if [ -n "$old_version" ] && [ -n "$new_version" ]; then
114+
if [ "$new_version" -le "$old_version" ]; then
115+
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
121+
cat >> $ISSUES_FILE << EOF
122+
### \`$struct_type\` ($file:$line_num)
123+
- **Struct modified:** Field changes detected
124+
- **Version status:** ❌ Not incremented (version $version)
125+
- **Recommendation:** Review changes and increment version if needed
126+
127+
EOF
128+
else
129+
echo " ✅ Version incremented ($old_version$new_version)"
130+
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)
136+
137+
cat >> $ISSUES_FILE << EOF
138+
### \`$struct_type\` ($file:$line_num)
139+
- **Struct modified:** Field changes detected
140+
- **Version status:** ⚠️ Unable to verify version increment
141+
- **Current version:** $version
142+
- **Recommendation:** Verify version was incremented if struct layout changed
143+
144+
EOF
145+
fi
146+
else
147+
echo " ✅ Struct unchanged"
148+
fi
149+
fi
150+
done <<< "$pg_registers"
151+
}
152+
153+
# Check each changed file
154+
while IFS= read -r file; do
155+
check_file_for_pg_changes "$file"
156+
done <<< "$CHANGED_FILES"
157+
158+
# Check if any issues were found
159+
if [ -s $ISSUES_FILE ]; then
160+
echo ""
161+
echo "${YELLOW}⚠️ Potential PG version issues detected${NC}"
162+
echo "Output saved to: $ISSUES_FILE"
163+
cat $ISSUES_FILE
164+
exit 1
165+
else
166+
echo ""
167+
echo "${GREEN}✅ No PG version issues detected${NC}"
168+
exit 0
169+
fi

.github/workflows/README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# GitHub Actions Workflows
2+
3+
This directory contains automated CI/CD workflows for the INAV project.
4+
5+
## Active Workflows
6+
7+
### Build and Test
8+
9+
#### `ci.yml` - Build Firmware
10+
**Triggers:** Pull requests, pushes to maintenance branches
11+
**Purpose:** Compiles INAV firmware for all targets to verify builds succeed
12+
**Matrix:** 15 parallel build jobs for faster CI
13+
14+
#### `nightly-build.yml` - Nightly Builds
15+
**Triggers:** Scheduled nightly
16+
**Purpose:** Creates nightly development builds for testing
17+
18+
### Documentation
19+
20+
#### `docs.yml` - Documentation Build
21+
**Triggers:** Pull requests affecting documentation
22+
**Purpose:** Validates documentation builds correctly
23+
24+
### Code Quality
25+
26+
#### `pg-version-check.yml` - Parameter Group Version Check
27+
**Triggers:** Pull requests to maintenance-9.x and maintenance-10.x
28+
**Purpose:** Detects parameter group struct modifications and verifies version increments
29+
**Why:** Prevents settings corruption when struct layout changes without version bump
30+
31+
**How it works:**
32+
1. Scans changed .c/.h files for `PG_REGISTER` entries
33+
2. Detects if associated struct typedefs were modified
34+
3. Checks if the PG version parameter was incremented
35+
4. Posts helpful comment if version not incremented
36+
37+
**Reference:** See `docs/development/parameter_groups/` for PG system documentation
38+
39+
**Script:** `.github/scripts/check-pg-versions.sh`
40+
41+
**When to increment PG versions:**
42+
- ✅ Adding/removing fields from struct
43+
- ✅ Changing field types or sizes
44+
- ✅ Reordering fields
45+
- ✅ Adding/removing packing attributes
46+
- ❌ Only changing `PG_RESET_TEMPLATE` default values
47+
- ❌ Only changing comments
48+
49+
### Pull Request Helpers
50+
51+
#### `pr-branch-suggestion.yml` - Branch Targeting Suggestion
52+
**Triggers:** PRs targeting master branch
53+
**Purpose:** Suggests using maintenance-9.x or maintenance-10.x instead
54+
55+
#### `non-code-change.yaml` - Non-Code Change Detection
56+
**Triggers:** Pull requests
57+
**Purpose:** Detects PRs with only documentation/formatting changes
58+
59+
## Configuration Files
60+
61+
- `../.github/stale.yml` - Stale issue/PR management
62+
- `../.github/no-response.yml` - Auto-close issues without response
63+
- `../.github/issue_label_bot.yaml` - Automatic issue labeling
64+
65+
## Adding New Workflows
66+
67+
When adding workflows:
68+
69+
1. **Use descriptive names** - Make purpose clear from filename
70+
2. **Document in this README** - Add entry above with purpose and triggers
71+
3. **Set appropriate permissions** - Principle of least privilege
72+
4. **Test in fork first** - Verify before submitting to main repo
73+
5. **Handle errors gracefully** - Don't block CI unnecessarily
74+
75+
### Common Patterns
76+
77+
**Checkout with history:**
78+
```yaml
79+
- uses: actions/checkout@v4
80+
with:
81+
fetch-depth: 0
82+
```
83+
84+
**Post PR comments:**
85+
```yaml
86+
- uses: actions/github-script@v7
87+
with:
88+
script: |
89+
await github.rest.issues.createComment({
90+
owner: context.repo.owner,
91+
repo: context.repo.repo,
92+
issue_number: context.issue.number,
93+
body: 'Comment text'
94+
});
95+
```
96+
97+
**Run bash scripts:**
98+
```yaml
99+
- run: bash .github/scripts/script-name.sh
100+
env:
101+
GITHUB_BASE_REF: ${{ github.base_ref }}
102+
```
103+
104+
## Permissions
105+
106+
Workflows use GitHub's fine-grained permissions:
107+
108+
- `contents: read` - Read repository code
109+
- `pull-requests: write` - Post/update PR comments
110+
- `actions: read` - Read workflow run data
111+
112+
## Local Testing
113+
114+
Scripts in `.github/scripts/` can be run locally:
115+
116+
```bash
117+
cd inav
118+
export GITHUB_BASE_REF=maintenance-9.x
119+
export GITHUB_HEAD_REF=feature-branch
120+
bash .github/scripts/check-pg-versions.sh
121+
```
122+
123+
## References
124+
125+
- [GitHub Actions Documentation](https://docs.github.com/en/actions)
126+
- [Workflow Syntax](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)
127+
- [GitHub Script Action](https://github.com/actions/github-script)

0 commit comments

Comments
 (0)