secubox-openwrt/.github/workflows/build-openwrt-packages.yml
CyberMind-FR d562b64c49 fix: remove telephony feed from defconfig to prevent indexing errors
The telephony feed was causing 'Collecting package info' failures during
make defconfig. This fix removes the telephony feed directory and references
from feeds.conf.default before running defconfig in all workflows.

Fixes applied to:
- build-openwrt-packages.yml
- build-secubox-images.yml
- test-validate.yml
2025-12-23 22:19:29 +01:00

729 lines
25 KiB
YAML

name: Build OpenWrt Packages
on:
push:
branches: [main, master, develop]
tags:
- 'v*'
pull_request:
branches: [main, master]
workflow_dispatch:
inputs:
package_name:
description: 'Package to build (leave empty for all packages)'
required: false
type: choice
options:
- ''
- 'luci-app-secubox'
- 'luci-app-crowdsec-dashboard'
- 'luci-app-netdata-dashboard'
- 'luci-app-netifyd-dashboard'
- 'luci-app-wireguard-dashboard'
- 'luci-app-network-modes'
- 'luci-app-client-guardian'
- 'luci-app-system-hub'
- 'luci-app-bandwidth-manager'
- 'luci-app-auth-guardian'
- 'luci-app-media-flow'
- 'luci-app-vhost-manager'
- 'luci-app-cdn-cache'
openwrt_version:
description: 'OpenWrt version'
required: true
default: '23.05.5'
type: choice
options:
- '23.05.5'
- '23.05.4'
- '24.10.0'
- 'SNAPSHOT'
architectures:
description: 'Architectures (comma-separated or "all")'
required: false
default: 'x86-64'
env:
OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version || '23.05.5' }}
permissions:
contents: write
jobs:
# ============================================
# Setup and determine build matrix
# ============================================
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Determine version
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
VERSION="${{ github.ref_name }}"
else
VERSION="0.0.0-$(git rev-parse --short HEAD)"
fi
echo "version=${VERSION#v}" >> $GITHUB_OUTPUT
echo "📦 Package version: ${VERSION#v}"
PACKAGE_NAME="${{ github.event.inputs.package_name }}"
if [[ -n "$PACKAGE_NAME" ]]; then
echo "🎯 Building single package: $PACKAGE_NAME"
else
echo "📦 Building all packages"
fi
- name: Set build matrix
id: set-matrix
run: |
cat > /tmp/matrix.json << 'EOF'
{
"include": [
{
"target": "x86-64",
"arch": "x86_64",
"sdk_path": "x86/64",
"description": "x86 64-bit (PC, VM)"
},
{
"target": "aarch64-cortex-a53",
"arch": "aarch64_cortex-a53",
"sdk_path": "mvebu/cortexa53",
"description": "ARM Cortex-A53 (ESPRESSObin)"
},
{
"target": "aarch64-cortex-a72",
"arch": "aarch64_cortex-a72",
"sdk_path": "mvebu/cortexa72",
"description": "ARM Cortex-A72 (MOCHAbin)"
},
{
"target": "aarch64-generic",
"arch": "aarch64_generic",
"sdk_path": "armsr/armv8",
"description": "ARM 64-bit generic"
},
{
"target": "mips-24kc",
"arch": "mips_24kc",
"sdk_path": "ath79/generic",
"description": "MIPS 24Kc (TP-Link)"
},
{
"target": "mipsel-24kc",
"arch": "mipsel_24kc",
"sdk_path": "ramips/mt7621",
"description": "MIPS LE (Xiaomi, GL.iNet)"
},
{
"target": "mediatek-filogic",
"arch": "aarch64_cortex-a53",
"sdk_path": "mediatek/filogic",
"description": "MediaTek Filogic"
},
{
"target": "rockchip-armv8",
"arch": "aarch64_generic",
"sdk_path": "rockchip/armv8",
"description": "Rockchip (NanoPi R4S)"
},
{
"target": "bcm27xx-bcm2711",
"arch": "aarch64_cortex-a72",
"sdk_path": "bcm27xx/bcm2711",
"description": "Raspberry Pi 4"
}
]
}
EOF
INPUT_ARCHS="${{ github.event.inputs.architectures }}"
if [[ -z "$INPUT_ARCHS" || "$INPUT_ARCHS" == "all" ]]; then
MATRIX=$(cat /tmp/matrix.json)
else
MATRIX=$(jq -c --arg archs "$INPUT_ARCHS" '
.include |= map(select(.target as $t | $archs | split(",") | map(gsub("^\\s+|\\s+$";"")) | any(. == $t)))
' /tmp/matrix.json)
fi
echo "matrix<<EOF" >> $GITHUB_OUTPUT
echo "$MATRIX" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "📋 Build matrix:"
echo "$MATRIX" | jq '.'
# ============================================
# Build packages
# ============================================
build:
needs: setup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: Build ${{ matrix.target }}
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Free disk space
run: |
echo "🧹 Cleaning up disk space..."
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
df -h
- 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 \
swig unzip zlib1g-dev file wget curl jq
- name: Cache OpenWrt SDK
uses: actions/cache@v4
id: cache-sdk
with:
path: sdk
key: openwrt-sdk-${{ env.OPENWRT_VERSION }}-${{ matrix.target }}-v4
- name: Download OpenWrt SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
echo "📥 Downloading SDK for ${{ matrix.description }}..."
BASE_URL="https://downloads.openwrt.org/releases/${{ env.OPENWRT_VERSION }}/targets/${{ matrix.sdk_path }}"
# Find SDK filename with retry
for attempt in 1 2 3; do
echo "Attempt $attempt: Fetching SDK list..."
SDK_FILE=$(curl -sL --retry 3 --retry-delay 5 "$BASE_URL/" | grep -oP 'openwrt-sdk[^"<>]+\.tar\.(xz|zst)' | head -1) && break
sleep 10
done
if [[ -z "$SDK_FILE" ]]; then
echo "❌ Could not find SDK"
exit 1
fi
echo "📥 Downloading: $SDK_FILE"
# Download with retry
for attempt in 1 2 3; do
echo "Download attempt $attempt..."
wget -q --retry-connrefused --waitretry=5 --timeout=60 \
"${BASE_URL}/${SDK_FILE}" -O /tmp/sdk.tar.xz && break
sleep 15
done
# Extract
mkdir -p sdk
tar -xf /tmp/sdk.tar.xz -C sdk --strip-components=1
rm -f /tmp/sdk.tar.xz
echo "✅ SDK extracted"
- name: Setup SDK feeds (GitHub mirrors)
run: |
cd sdk
echo "📝 Configuring feeds with GitHub mirrors..."
# Use GitHub mirrors - only essential feeds (no telephony)
cat > feeds.conf << 'FEEDS'
src-git base https://github.com/openwrt/openwrt.git;openwrt-23.05
src-git packages https://github.com/openwrt/packages.git;openwrt-23.05
src-git luci https://github.com/openwrt/luci.git;openwrt-23.05
FEEDS
echo "📋 feeds.conf:"
cat feeds.conf
# Update feeds individually with error handling
echo ""
echo "🔄 Updating feeds..."
FEEDS_OK=0
for feed in base packages luci; do
echo "Updating feed: $feed"
for attempt in 1 2 3; do
if ./scripts/feeds update $feed 2>&1; then
echo " ✅ $feed updated"
FEEDS_OK=$((FEEDS_OK + 1))
break
fi
echo " ⚠️ Attempt $attempt failed, retrying..."
sleep $((10 * attempt))
done
done
echo ""
echo "📊 Feeds updated: $FEEDS_OK/3"
# Install feeds
echo ""
echo "📦 Installing feeds..."
./scripts/feeds install -a 2>&1 || true
# Verify luci.mk exists
if [[ -f "feeds/luci/luci.mk" ]]; then
echo "✅ luci.mk found"
else
echo "⚠️ Creating fallback luci.mk..."
mkdir -p feeds/luci
cat > feeds/luci/luci.mk << 'LUCI_MK'
# Minimal LuCI build system fallback
LUCI_PKGARCH:=all
define Package/Default
SECTION:=luci
CATEGORY:=LuCI
SUBMENU:=3. Applications
PKGARCH:=all
endef
LUCI_MK
fi
# Clean up any stale feed references
rm -f feeds/telephony.index 2>/dev/null || true
rm -rf feeds/telephony 2>/dev/null || true
# Remove telephony from feeds.conf.default if it exists
if [[ -f "feeds.conf.default" ]]; then
sed -i '/telephony/d' feeds.conf.default
echo "✅ Removed telephony from feeds.conf.default"
fi
make defconfig
echo "✅ SDK configured"
- name: Copy packages to SDK
run: |
VERSION="${{ needs.setup.outputs.version }}"
PACKAGE_NAME="${{ github.event.inputs.package_name }}"
if [[ -n "$PACKAGE_NAME" ]]; then
echo "📦 Copying single package: $PACKAGE_NAME (version: $VERSION)..."
if [[ -d "$PACKAGE_NAME" && -f "${PACKAGE_NAME}/Makefile" ]]; then
echo " 📁 $PACKAGE_NAME"
cp -r "$PACKAGE_NAME" sdk/package/
# Update version
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" "sdk/package/${PACKAGE_NAME}/Makefile"
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" "sdk/package/${PACKAGE_NAME}/Makefile"
else
echo "❌ Package $PACKAGE_NAME not found or missing Makefile"
exit 1
fi
else
echo "📦 Copying all packages (version: $VERSION)..."
for pkg in luci-app-*/; do
if [[ -d "$pkg" && -f "${pkg}Makefile" ]]; then
PKG_NAME=$(basename "$pkg")
echo " 📁 $PKG_NAME"
cp -r "$pkg" sdk/package/
# Update version
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" "sdk/package/${PKG_NAME}/Makefile"
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" "sdk/package/${PKG_NAME}/Makefile"
fi
done
fi
echo ""
echo "📋 Packages in SDK:"
ls -d sdk/package/luci-app-*/ 2>/dev/null || echo "None"
- name: Configure packages
run: |
cd sdk
echo "⚙️ Enabling packages..."
for pkg in package/luci-app-*/; do
if [[ -d "$pkg" ]]; then
PKG_NAME=$(basename "$pkg")
echo "CONFIG_PACKAGE_${PKG_NAME}=m" >> .config
echo " ✅ $PKG_NAME"
fi
done
make defconfig
- name: Build packages
run: |
cd sdk
echo "🔨 Building SecuBox packages..."
echo ""
BUILT=0
FAILED=0
BUILT_LIST=""
FAILED_LIST=""
for pkg in package/luci-app-*/; do
[[ -d "$pkg" ]] || continue
PKG_NAME=$(basename "$pkg")
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Building: $PKG_NAME"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Show package contents for debugging
echo "📁 Package contents:"
ls -la "$pkg"
# Verify Makefile syntax
if ! grep -q "BuildPackage" "${pkg}Makefile"; then
echo "⚠️ WARNING: Makefile missing BuildPackage call"
fi
# Build with timeout (10 minutes per package)
BUILD_LOG="/tmp/build-${PKG_NAME}.log"
if timeout 600 make package/${PKG_NAME}/compile V=s -j$(nproc) > "$BUILD_LOG" 2>&1; then
# Check if .ipk was created
IPK_FILE=$(find bin -name "${PKG_NAME}*.ipk" 2>/dev/null | head -1)
if [[ -n "$IPK_FILE" ]]; then
echo "✅ Built: $PKG_NAME"
echo " → $IPK_FILE"
BUILT=$((BUILT + 1))
BUILT_LIST="${BUILT_LIST}${PKG_NAME},"
else
echo "⚠️ No .ipk generated for $PKG_NAME"
echo "📋 Last 50 lines of build log:"
tail -50 "$BUILD_LOG"
FAILED=$((FAILED + 1))
FAILED_LIST="${FAILED_LIST}${PKG_NAME},"
fi
else
echo "❌ Build failed: $PKG_NAME"
echo "📋 Last 100 lines of build log:"
tail -100 "$BUILD_LOG"
FAILED=$((FAILED + 1))
FAILED_LIST="${FAILED_LIST}${PKG_NAME},"
fi
echo ""
done
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 Build Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Built: $BUILT packages"
echo "❌ Failed: $FAILED packages"
echo ""
echo "Built: $BUILT_LIST"
if [[ -n "$FAILED_LIST" ]]; then
echo "Failed: $FAILED_LIST"
fi
- name: Collect artifacts
id: collect
run: |
echo "📦 Collecting artifacts..."
mkdir -p artifacts/${{ matrix.target }}
# Find and copy .ipk files
find sdk/bin -name "luci-app-*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
# Also collect any SecuBox related packages
find sdk/bin -name "*secubox*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
# Count
PKG_COUNT=$(find artifacts/${{ matrix.target }} -name "*.ipk" 2>/dev/null | wc -l)
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
echo ""
echo "📋 Built packages for ${{ matrix.target }}:"
ls -la artifacts/${{ matrix.target }}/ 2>/dev/null || echo "No packages"
# Create checksums
if [[ $PKG_COUNT -gt 0 ]]; then
cd artifacts/${{ matrix.target }}
sha256sum *.ipk > SHA256SUMS
fi
echo ""
echo "📦 Total: $PKG_COUNT packages"
- name: Upload artifacts
uses: actions/upload-artifact@v4
if: steps.collect.outputs.pkg_count > 0
with:
name: packages-${{ matrix.target }}
path: artifacts/${{ matrix.target }}/
retention-days: 30
- name: Build Summary
run: |
PKG_COUNT="${{ steps.collect.outputs.pkg_count }}"
echo "## 📦 Build Results: ${{ matrix.target }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Target | ${{ matrix.description }} |" >> $GITHUB_STEP_SUMMARY
echo "| Architecture | ${{ matrix.arch }} |" >> $GITHUB_STEP_SUMMARY
echo "| SDK Path | ${{ matrix.sdk_path }} |" >> $GITHUB_STEP_SUMMARY
echo "| Packages Built | $PKG_COUNT |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ "$PKG_COUNT" -gt 0 ]]; then
echo "### Built Packages" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
ls artifacts/${{ matrix.target }}/*.ipk 2>/dev/null | xargs -I{} basename {} | sort
echo '```' >> $GITHUB_STEP_SUMMARY
fi
# ============================================
# Publish combined artifacts (always)
# ============================================
publish-artifacts:
needs: [setup, build]
runs-on: ubuntu-latest
if: always() && needs.build.result == 'success'
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: packages
pattern: packages-*
- name: Create combined archives
run: |
VERSION="${{ needs.setup.outputs.version }}"
PACKAGE_NAME="${{ github.event.inputs.package_name }}"
mkdir -p release
# Determine prefix for archives
if [[ -n "$PACKAGE_NAME" ]]; then
PREFIX="${PACKAGE_NAME}"
echo "📁 Creating archives for single package: $PACKAGE_NAME..."
else
PREFIX="secubox"
echo "📁 Creating combined archives..."
fi
# Per-architecture archives
for dir in packages/packages-*/; do
[[ -d "$dir" ]] || continue
ARCH=$(basename "$dir" | sed 's/packages-//')
echo "📦 $ARCH"
# Copy .ipk files to release
mkdir -p "release/${ARCH}"
cp "$dir"/*.ipk "release/${ARCH}/" 2>/dev/null || true
# Create archive
if ls "release/${ARCH}"/*.ipk >/dev/null 2>&1; then
tar -czf "release/${PREFIX}-${VERSION}-${ARCH}.tar.gz" -C "release/${ARCH}" .
fi
done
# Create all-in-one archive
tar -czf "release/${PREFIX}-${VERSION}-all-architectures.tar.gz" -C packages .
# Checksums
cd release
sha256sum *.tar.gz > SHA256SUMS 2>/dev/null || true
echo ""
echo "📋 Release contents:"
ls -la
echo ""
echo "📊 Package count per architecture:"
for dir in */; do
[[ -d "$dir" ]] || continue
COUNT=$(ls "$dir"/*.ipk 2>/dev/null | wc -l)
echo " ${dir%/}: $COUNT packages"
done
- name: Upload combined release
uses: actions/upload-artifact@v4
with:
name: secubox-release-${{ needs.setup.outputs.version }}
path: |
release/*.tar.gz
release/SHA256SUMS
retention-days: 90
- name: Upload individual .ipk files
uses: actions/upload-artifact@v4
with:
name: secubox-all-ipk-${{ needs.setup.outputs.version }}
path: release/*/*.ipk
retention-days: 90
# ============================================
# Create GitHub Release (on tags or manual)
# ============================================
release:
needs: [setup, build, publish-artifacts]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download release artifact
uses: actions/download-artifact@v4
with:
name: secubox-release-${{ needs.setup.outputs.version }}
path: release
- name: Download all .ipk files
uses: actions/download-artifact@v4
with:
name: secubox-all-ipk-${{ needs.setup.outputs.version }}
path: ipk-files
continue-on-error: true
- name: List packages
id: list-packages
run: |
echo "📦 Packages in release:"
find . -name "*.ipk" -exec basename {} \; | sort -u
# Count unique packages
PKG_LIST=$(find . -name "*.ipk" -exec basename {} \; | sort -u | sed 's/_[0-9].*//g' | sort -u | tr '\n' ', ' | sed 's/,$//')
echo "packages=$PKG_LIST" >> $GITHUB_OUTPUT
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: ${{ github.event.inputs.package_name && format('{0} {1}', github.event.inputs.package_name, needs.setup.outputs.version) || format('SecuBox {0}', needs.setup.outputs.version) }}
tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('v{0}', needs.setup.outputs.version) }}
body: |
## 📦 ${{ github.event.inputs.package_name && format('{0} Package', github.event.inputs.package_name) || 'SecuBox Packages' }} v${{ needs.setup.outputs.version }}
Pre-built LuCI package${{ github.event.inputs.package_name && '' || 's' }} for OpenWrt ${{ env.OPENWRT_VERSION }}.
${{ github.event.inputs.package_name && format('🎯 **Single package build**: {0}', github.event.inputs.package_name) || '' }}
### ✅ Built Packages
${{ steps.list-packages.outputs.packages }}
### 📥 Installation
```bash
# Download the archive for your architecture
# Extract and upload .ipk files to router
opkg update
opkg install /tmp/luci-app-*.ipk
# Restart services
/etc/init.d/rpcd restart
```
### 🏗️ Supported Architectures
- `x86-64` - PC, VMs, Proxmox
- `aarch64-cortex-a72` - MOCHAbin, RPi4
- `aarch64-cortex-a53` - ESPRESSObin
- `aarch64-generic` - Generic ARM64
- `mips-24kc` - TP-Link, ath79
- `mipsel-24kc` - Xiaomi, GL.iNet
- `mediatek-filogic` - MT7981/MT7986
### 🔗 Links
- [SecuBox Website](https://secubox.cybermood.eu)
- [CyberMind.fr](https://cybermind.fr)
files: |
release/*.tar.gz
release/SHA256SUMS
draft: false
prerelease: ${{ github.event_name == 'workflow_dispatch' }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ============================================
# Final Summary
# ============================================
summary:
needs: [setup, build]
runs-on: ubuntu-latest
if: always()
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: packages
pattern: packages-*
continue-on-error: true
- name: Generate summary
run: |
PACKAGE_NAME="${{ github.event.inputs.package_name }}"
echo "# 📊 SecuBox Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Version | ${{ needs.setup.outputs.version }} |" >> $GITHUB_STEP_SUMMARY
echo "| OpenWrt | ${{ env.OPENWRT_VERSION }} |" >> $GITHUB_STEP_SUMMARY
echo "| Triggered by | ${{ github.event_name }} |" >> $GITHUB_STEP_SUMMARY
if [[ -n "$PACKAGE_NAME" ]]; then
echo "| Package | 🎯 $PACKAGE_NAME (single package build) |" >> $GITHUB_STEP_SUMMARY
else
echo "| Package | 📦 All packages |" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Build Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Architecture | Status | Packages |" >> $GITHUB_STEP_SUMMARY
echo "|--------------|--------|----------|" >> $GITHUB_STEP_SUMMARY
TOTAL=0
for dir in packages/packages-*/; do
if [[ -d "$dir" ]]; then
ARCH=$(basename "$dir" | sed 's/packages-//')
COUNT=$(find "$dir" -name "*.ipk" 2>/dev/null | wc -l)
TOTAL=$((TOTAL + COUNT))
if [[ $COUNT -gt 0 ]]; then
echo "| $ARCH | ✅ Success | $COUNT |" >> $GITHUB_STEP_SUMMARY
else
echo "| $ARCH | ⚠️ Empty | 0 |" >> $GITHUB_STEP_SUMMARY
fi
fi
done
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Total packages built: $TOTAL**" >> $GITHUB_STEP_SUMMARY