secubox-openwrt/.github/workflows/test-validate.yml
CyberMind-FR 3cd072382a fix: also remove routing feed to prevent indexing errors
Extended the feed removal to also exclude the routing feed, which was
causing the same indexing error during make defconfig.

Now removing both telephony and routing feeds from feeds.conf.default
before updating feeds in all three workflows.

This ensures only base, packages, and luci feeds are used.
2025-12-23 22:53:35 +01:00

388 lines
12 KiB
YAML

name: Test & Validate Packages
on:
push:
branches: [main, master, develop]
pull_request:
branches: [main, master]
jobs:
# ============================================
# Lint and validate package structure
# ============================================
lint:
runs-on: ubuntu-latest
name: Lint & Validate
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install validators
run: |
sudo apt-get update
sudo apt-get install -y shellcheck jq
- name: Validate Makefile structure
run: |
echo "📋 Validating Makefile structure..."
ERRORS=0
for makefile in luci-app-*/Makefile; do
if [[ -f "$makefile" ]]; then
PKG=$(dirname "$makefile")
echo " 🔍 Checking $PKG..."
# Required fields
REQUIRED_FIELDS=(
"PKG_NAME"
"PKG_VERSION"
"PKG_RELEASE"
"PKG_LICENSE"
)
for field in "${REQUIRED_FIELDS[@]}"; do
if ! grep -q "^${field}:=" "$makefile"; then
echo " ❌ Missing: $field"
ERRORS=$((ERRORS + 1))
fi
done
# Check for include statements
if ! grep -q "include.*luci.mk\|include.*package.mk" "$makefile"; then
echo " ❌ Missing include statement (luci.mk or package.mk)"
ERRORS=$((ERRORS + 1))
fi
fi
done
if [[ $ERRORS -gt 0 ]]; then
echo "❌ Found $ERRORS errors"
exit 1
fi
echo "✅ All Makefiles valid"
- name: Validate JSON files
run: |
echo "📋 Validating JSON files..."
ERRORS=0
while IFS= read -r jsonfile; do
echo " 🔍 Checking $jsonfile..."
if ! jq empty "$jsonfile" 2>/dev/null; then
echo " ❌ Invalid JSON"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.json" -type f)
if [[ $ERRORS -gt 0 ]]; then
echo "❌ Found $ERRORS JSON errors"
exit 1
fi
echo "✅ All JSON files valid"
- name: Validate JavaScript syntax
run: |
echo "📋 Validating JavaScript files..."
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
ERRORS=0
while IFS= read -r jsfile; do
echo " 🔍 Checking $jsfile..."
if ! node --check "$jsfile" 2>/dev/null; then
echo " ❌ Syntax error"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.js" -type f ! -path "*/node_modules/*")
if [[ $ERRORS -gt 0 ]]; then
echo "❌ Found $ERRORS JavaScript errors"
exit 1
fi
echo "✅ All JavaScript files valid"
- name: Validate shell scripts
run: |
echo "📋 Validating shell scripts..."
WARNINGS=0
# Check RPCD scripts
while IFS= read -r script; do
echo " 🔍 Checking $script..."
shellcheck -s sh "$script" || WARNINGS=$((WARNINGS + 1))
done < <(find . -path "*/rpcd/*" -type f 2>/dev/null)
# Check init scripts
while IFS= read -r script; do
echo " 🔍 Checking $script..."
shellcheck -s sh "$script" || WARNINGS=$((WARNINGS + 1))
done < <(find . -path "*/init.d/*" -type f 2>/dev/null)
if [[ $WARNINGS -gt 0 ]]; then
echo "⚠️ Found $WARNINGS shellcheck warnings (non-blocking)"
fi
echo "✅ Shell script validation complete"
- name: Check file permissions
run: |
echo "📋 Checking file permissions..."
ERRORS=0
# RPCD scripts should be executable
while IFS= read -r script; do
if [[ ! -x "$script" ]]; then
echo " ❌ Not executable: $script"
chmod +x "$script"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -path "*/usr/libexec/rpcd/*" -type f 2>/dev/null)
# Init scripts should be executable
while IFS= read -r script; do
if [[ ! -x "$script" ]]; then
echo " ❌ Not executable: $script"
chmod +x "$script"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -path "*/etc/init.d/*" -type f 2>/dev/null)
if [[ $ERRORS -gt 0 ]]; then
echo "⚠️ Fixed $ERRORS permission issues"
fi
echo "✅ File permissions checked"
- name: Validate package structure
run: |
echo "📋 Validating package structure..."
for pkg in luci-app-*/; do
if [[ -d "$pkg" ]]; then
echo " 📦 Checking $pkg..."
# Required
if [[ ! -f "${pkg}Makefile" ]]; then
echo " ❌ Missing required: Makefile"
exit 1
fi
# Recommended
RECOMMENDED=(
"htdocs/luci-static/resources"
"root/usr/share/luci/menu.d"
"root/usr/share/rpcd/acl.d"
)
for rec in "${RECOMMENDED[@]}"; do
if [[ ! -e "${pkg}${rec}" ]]; then
echo " ⚠️ Missing recommended: $rec"
fi
done
fi
done
echo "✅ Package structure valid"
# ============================================
# Quick build test on x86_64
# ============================================
test-build:
runs-on: ubuntu-latest
name: Test Build (x86_64)
needs: lint
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential clang flex bison g++ gawk \
gcc-multilib g++-multilib gettext git libncurses5-dev \
libssl-dev python3-setuptools python3-dev rsync unzip zlib1g-dev wget
- name: Cache OpenWrt SDK
uses: actions/cache@v4
id: cache-sdk
with:
path: ~/sdk
key: openwrt-sdk-23.05.5-x86-64-test-v2
- name: Download OpenWrt SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
SDK_URL="https://downloads.openwrt.org/releases/23.05.5/targets/x86/64"
SDK_FILE=$(curl -sL "$SDK_URL/" | grep -oP 'openwrt-sdk[^"]+\.tar\.xz' | head -1)
wget -q "${SDK_URL}/${SDK_FILE}" -O /tmp/sdk.tar.xz
mkdir -p ~/sdk
tar -xf /tmp/sdk.tar.xz -C ~/sdk --strip-components=1
- name: Prepare SDK
run: |
cd ~/sdk
# Remove unwanted feeds from feeds.conf.default BEFORE updating feeds
if [[ -f "feeds.conf.default" ]]; then
sed -i '/telephony/d' feeds.conf.default
sed -i '/routing/d' feeds.conf.default
echo "✅ Removed telephony and routing from feeds.conf.default"
fi
./scripts/feeds update -a
./scripts/feeds install -a
# Final cleanup of unwanted feeds
rm -f feeds/telephony.index feeds/routing.index 2>/dev/null || true
rm -rf feeds/telephony feeds/routing 2>/dev/null || true
make defconfig
- name: Copy packages
run: |
# IMPORTANT: Copy packages DIRECTLY into package/, not into a subdirectory
for pkg in luci-app-*/; do
if [[ -d "$pkg" && -f "${pkg}Makefile" ]]; then
PKG_NAME=$(basename "$pkg")
echo "📦 Copying $PKG_NAME..."
cp -r "$pkg" ~/sdk/package/
fi
done
echo ""
echo "📋 Packages in SDK:"
ls -d ~/sdk/package/luci-app-*/ 2>/dev/null || echo "No packages found"
- name: Configure packages
run: |
cd ~/sdk
# Enable packages
for pkg in ~/sdk/package/luci-app-*/; do
if [[ -d "$pkg" ]]; then
PKG_NAME=$(basename "$pkg")
echo "CONFIG_PACKAGE_${PKG_NAME}=m" >> .config
echo "✅ Enabled: $PKG_NAME"
fi
done
# Final cleanup before defconfig
rm -f feeds/telephony.index feeds/routing.index 2>/dev/null || true
rm -rf feeds/telephony feeds/routing 2>/dev/null || true
make defconfig
- name: Build packages
run: |
cd ~/sdk
echo "🔨 Building packages..."
BUILT=0
FAILED=0
# Build each package individually with timeout
for pkg in ~/sdk/package/luci-app-*/; do
if [[ -d "$pkg" ]]; then
PKG_NAME=$(basename "$pkg")
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Building: $PKG_NAME"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Build with 5 minute timeout per package
if timeout 5m make package/${PKG_NAME}/compile V=s -j$(nproc) 2>&1; then
echo "✅ Built: $PKG_NAME"
BUILT=$((BUILT + 1))
else
echo "❌ Failed: $PKG_NAME"
FAILED=$((FAILED + 1))
fi
fi
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Build Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Built: $BUILT packages"
echo "Failed: $FAILED packages"
if [[ $BUILT -eq 0 ]]; then
echo "❌ No packages were built!"
exit 1
fi
- name: Verify output
run: |
echo "📋 Built packages:"
find ~/sdk/bin -name "luci-app-*.ipk" -exec ls -la {} \;
PKG_COUNT=$(find ~/sdk/bin -name "luci-app-*.ipk" | wc -l)
echo ""
echo "📦 Total packages built: $PKG_COUNT"
if [[ $PKG_COUNT -eq 0 ]]; then
echo "❌ No packages were built!"
exit 1
fi
echo "✅ Build test passed"
# ============================================
# Generate documentation
# ============================================
docs:
runs-on: ubuntu-latest
name: Generate Docs
needs: lint
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate package list
run: |
echo "# SecuBox Packages" > PACKAGES.md
echo "" >> PACKAGES.md
echo "Auto-generated package documentation." >> PACKAGES.md
echo "" >> PACKAGES.md
echo "| Package | Version | Description |" >> PACKAGES.md
echo "|---------|---------|-------------|" >> PACKAGES.md
for makefile in luci-app-*/Makefile; do
if [[ -f "$makefile" ]]; then
PKG_NAME=$(grep "^PKG_NAME:=" "$makefile" | cut -d'=' -f2)
PKG_VERSION=$(grep "^PKG_VERSION:=" "$makefile" | cut -d'=' -f2)
PKG_TITLE=$(grep "^LUCI_TITLE:=" "$makefile" | cut -d'=' -f2- | sed 's/^[[:space:]]*//')
# Fallback if LUCI_TITLE not found
if [[ -z "$PKG_TITLE" ]]; then
PKG_TITLE=$(grep "TITLE:=" "$makefile" | head -1 | cut -d'=' -f2- | sed 's/^[[:space:]]*//')
fi
echo "| $PKG_NAME | $PKG_VERSION | $PKG_TITLE |" >> PACKAGES.md
fi
done
echo "" >> PACKAGES.md
echo "---" >> PACKAGES.md
echo "Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)" >> PACKAGES.md
echo "📋 Generated PACKAGES.md:"
cat PACKAGES.md
- name: Upload docs
uses: actions/upload-artifact@v4
with:
name: documentation
path: PACKAGES.md