secubox-openwrt/.github/workflows/build-secubox-images.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

765 lines
32 KiB
YAML

name: Build SecuBox Images (GlobalScale)
on:
workflow_dispatch:
inputs:
device:
description: 'Target device'
required: true
type: choice
options:
- espressobin-v7
- espressobin-ultra
- sheeva64
- sheeva64-wifi
- mochabin
- all
openwrt_version:
description: 'OpenWrt version'
required: true
default: '23.05.5'
type: choice
options:
- '23.05.5'
- '23.05.4'
- 'SNAPSHOT'
include_secubox:
description: 'Include SecuBox packages'
required: true
type: boolean
default: true
env:
OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version }}
permissions:
contents: write
jobs:
# ============================================
# Generate build matrix based on input
# ============================================
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Set build matrix
id: set-matrix
run: |
DEVICE="${{ github.event.inputs.device }}"
# Define all devices in a file to avoid heredoc issues
cat > /tmp/devices.json << 'DEVICES_EOF'
[
{
"device": "espressobin-v7",
"target": "mvebu",
"subtarget": "cortexa53",
"profile": "globalscale_espressobin",
"description": "ESPRESSObin V7 (1-2GB DDR4)"
},
{
"device": "espressobin-ultra",
"target": "mvebu",
"subtarget": "cortexa53",
"profile": "globalscale_espressobin-ultra",
"description": "ESPRESSObin Ultra (PoE, WiFi)"
},
{
"device": "sheeva64",
"target": "mvebu",
"subtarget": "cortexa53",
"profile": "globalscale_sheeva64",
"description": "Sheeva64 (Plug computer)"
},
{
"device": "sheeva64-wifi",
"target": "mvebu",
"subtarget": "cortexa53",
"profile": "globalscale_sheeva64",
"description": "Sheeva64 WiFi (802.11ac + BT)"
},
{
"device": "mochabin",
"target": "mvebu",
"subtarget": "cortexa72",
"profile": "globalscale_mochabin",
"description": "MOCHAbin (Quad-core A72, 10G)"
}
]
DEVICES_EOF
# Filter based on input
if [[ "$DEVICE" == "all" ]]; then
MATRIX=$(jq -c '{"include": .}' /tmp/devices.json)
else
MATRIX=$(jq -c --arg dev "$DEVICE" '{"include": [.[] | select(.device == $dev)]}' /tmp/devices.json)
fi
# Use delimiter for multiline output
echo "matrix<<EOF" >> $GITHUB_OUTPUT
echo "$MATRIX" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
echo "📋 Build matrix:"
echo "$MATRIX" | jq '.'
# ============================================
# Build firmware images for GlobalScale devices
# ============================================
build-image:
needs: setup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: ${{ matrix.description }}
steps:
- name: Checkout SecuBox packages
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
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 qemu-utils
- name: Clone OpenWrt
run: |
if [[ "${{ env.OPENWRT_VERSION }}" == "SNAPSHOT" ]]; then
git clone --depth 1 https://github.com/openwrt/openwrt.git openwrt
else
git clone --depth 1 --branch v${{ env.OPENWRT_VERSION }} \
https://github.com/openwrt/openwrt.git openwrt
fi
- name: Update feeds
run: |
cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a
- name: Copy SecuBox packages
if: ${{ github.event.inputs.include_secubox == 'true' }}
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 COPYING SECUBOX PACKAGES"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
mkdir -p openwrt/package/secubox
PKG_COUNT=0
for pkg in luci-app-*/; do
if [[ -d "$pkg" ]]; then
PKG_NAME=$(basename "$pkg")
echo " ✅ $PKG_NAME"
cp -r "$pkg" openwrt/package/secubox/
PKG_COUNT=$((PKG_COUNT + 1))
fi
done
echo ""
echo "📊 Total: $PKG_COUNT SecuBox packages copied"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- name: Generate SecuBox config
run: |
cd openwrt
# Base configuration
cat > .config << EOF
# Target
CONFIG_TARGET_${{ matrix.target }}=y
CONFIG_TARGET_${{ matrix.target }}_${{ matrix.subtarget }}=y
CONFIG_TARGET_${{ matrix.target }}_${{ matrix.subtarget }}_DEVICE_${{ matrix.profile }}=y
# Image settings
CONFIG_TARGET_ROOTFS_SQUASHFS=y
CONFIG_TARGET_ROOTFS_EXT4FS=y
CONFIG_TARGET_KERNEL_PARTSIZE=32
CONFIG_TARGET_ROOTFS_PARTSIZE=512
# Base packages
CONFIG_PACKAGE_luci=y
CONFIG_PACKAGE_luci-ssl=y
CONFIG_PACKAGE_luci-app-opkg=y
CONFIG_PACKAGE_luci-theme-openwrt-2020=y
# Networking essentials
CONFIG_PACKAGE_curl=y
CONFIG_PACKAGE_wget-ssl=y
CONFIG_PACKAGE_iptables=y
CONFIG_PACKAGE_ip6tables=y
CONFIG_PACKAGE_kmod-nft-core=y
# USB support
CONFIG_PACKAGE_kmod-usb-core=y
CONFIG_PACKAGE_kmod-usb3=y
CONFIG_PACKAGE_kmod-usb-storage=y
# Filesystem
CONFIG_PACKAGE_kmod-fs-ext4=y
CONFIG_PACKAGE_kmod-fs-vfat=y
CONFIG_PACKAGE_block-mount=y
# Wireless (if applicable)
CONFIG_PACKAGE_hostapd-common=y
CONFIG_PACKAGE_wpad-basic-mbedtls=y
# Monitoring tools
CONFIG_PACKAGE_htop=y
CONFIG_PACKAGE_iftop=y
CONFIG_PACKAGE_tcpdump=y
# SSH
CONFIG_PACKAGE_openssh-sftp-server=y
EOF
- name: Add SecuBox packages to config
if: ${{ github.event.inputs.include_secubox == 'true' }}
run: |
cd openwrt
# CrowdSec
cat >> .config << EOF
CONFIG_PACKAGE_crowdsec=y
CONFIG_PACKAGE_crowdsec-firewall-bouncer=y
CONFIG_PACKAGE_luci-app-crowdsec-dashboard=y
EOF
# Netdata
cat >> .config << EOF
CONFIG_PACKAGE_netdata=y
CONFIG_PACKAGE_luci-app-netdata-dashboard=y
EOF
# Netifyd
cat >> .config << EOF
CONFIG_PACKAGE_netifyd=y
CONFIG_PACKAGE_luci-app-netifyd-dashboard=y
EOF
# WireGuard
cat >> .config << EOF
CONFIG_PACKAGE_wireguard-tools=y
CONFIG_PACKAGE_kmod-wireguard=y
CONFIG_PACKAGE_luci-app-wireguard-dashboard=y
CONFIG_PACKAGE_qrencode=y
EOF
# SecuBox core
cat >> .config << EOF
CONFIG_PACKAGE_luci-app-network-modes=y
CONFIG_PACKAGE_luci-app-client-guardian=y
CONFIG_PACKAGE_luci-app-system-hub=y
EOF
- name: Add device-specific packages
run: |
cd openwrt
case "${{ matrix.device }}" in
mochabin)
# 10G networking, more RAM
cat >> .config << EOF
CONFIG_PACKAGE_kmod-sfp=y
CONFIG_PACKAGE_kmod-phy-marvell-10g=y
CONFIG_PACKAGE_prometheus-node-exporter-lua=y
EOF
;;
espressobin-ultra|sheeva64-wifi)
# WiFi support
cat >> .config << EOF
CONFIG_PACKAGE_kmod-mt76=y
CONFIG_PACKAGE_kmod-mac80211=y
EOF
;;
sheeva64*)
# Minimal for plug computer
cat >> .config << EOF
# Optimized for plug form factor
CONFIG_PACKAGE_kmod-ledtrig-heartbeat=y
EOF
;;
esac
- name: Make defconfig
run: |
cd openwrt
# Clean up telephony feed to avoid indexing errors
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
- name: Download packages
run: |
cd openwrt
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📥 DOWNLOADING PACKAGES"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "Downloading source packages and dependencies..."
echo "This may take several minutes depending on network speed."
echo ""
if make download -j$(nproc) V=s; then
echo ""
echo "✅ All packages downloaded successfully"
else
echo ""
echo "⚠️ Parallel download failed, retrying with single thread..."
make download -j1 V=s
fi
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
- name: Build firmware
run: |
cd openwrt
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔨 BUILDING FIRMWARE"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📋 Build Information:"
echo " • Device: ${{ matrix.description }}"
echo " • Profile: ${{ matrix.profile }}"
echo " • Target: ${{ matrix.target }}/${{ matrix.subtarget }}"
echo " • OpenWrt: ${{ env.OPENWRT_VERSION }}"
echo " • CPU Cores: $(nproc)"
echo " • Estimated Time: 1-2 hours"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
START_TIME=$(date +%s)
if make -j$(nproc) V=s 2>&1 | tee build.log; then
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
MINUTES=$((DURATION / 60))
SECONDS=$((DURATION % 60))
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ BUILD SUCCESSFUL"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "⏱️ Build Time: ${MINUTES}m ${SECONDS}s"
echo "📁 Output: bin/targets/${{ matrix.target }}/${{ matrix.subtarget }}/"
echo ""
else
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚠️ PARALLEL BUILD FAILED - RETRYING WITH SINGLE THREAD"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "This is often caused by race conditions in parallel builds."
echo "Retrying with -j1 (single thread) for better stability..."
echo ""
if make -j1 V=s 2>&1 | tee build-retry.log; then
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
MINUTES=$((DURATION / 60))
SECONDS=$((DURATION % 60))
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ BUILD SUCCESSFUL (after retry)"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "⏱️ Total Build Time: ${MINUTES}m ${SECONDS}s"
echo "📁 Output: bin/targets/${{ matrix.target }}/${{ matrix.subtarget }}/"
echo ""
else
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "❌ BUILD FAILED"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "📋 Last 50 lines of build log:"
echo ""
tail -50 build-retry.log
exit 1
fi
fi
- name: Prepare artifacts
id: prepare
run: |
mkdir -p artifacts
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Collecting Firmware Images"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Copy firmware images
IMG_COUNT=0
for pattern in "*.img.gz" "*.bin" "*sysupgrade*" "*factory*"; do
while IFS= read -r file; do
if [[ -f "$file" ]]; then
cp "$file" artifacts/
echo " ✅ $(basename "$file")"
IMG_COUNT=$((IMG_COUNT + 1))
fi
done < <(find openwrt/bin/targets -name "$pattern" 2>/dev/null)
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Collecting SecuBox Packages"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# Copy packages
mkdir -p artifacts/packages
PKG_COUNT=0
for pattern in "luci-app-*secubox*.ipk" "luci-app-*dashboard*.ipk" "luci-app-*guardian*.ipk" "luci-app-*modes*.ipk" "luci-app-*hub*.ipk"; do
while IFS= read -r file; do
if [[ -f "$file" ]]; then
cp "$file" artifacts/packages/
echo " ✅ $(basename "$file")"
PKG_COUNT=$((PKG_COUNT + 1))
fi
done < <(find openwrt/bin/packages -name "$pattern" 2>/dev/null)
done
# Generate checksums
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔐 Generating Checksums"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
cd artifacts
sha256sum *.* > SHA256SUMS 2>/dev/null || true
if [[ -d packages ]] && [[ -n "$(ls -A packages)" ]]; then
(cd packages && sha256sum *.ipk > SHA256SUMS 2>/dev/null || true)
fi
# Create info file
cat > BUILD_INFO.txt << EOF
SecuBox Firmware Build
=======================
Device: ${{ matrix.description }}
Profile: ${{ matrix.profile }}
Target: ${{ matrix.target }}/${{ matrix.subtarget }}
OpenWrt: ${{ env.OPENWRT_VERSION }}
SecuBox: ${{ github.event.inputs.include_secubox }}
Built: $(date -u +%Y-%m-%dT%H:%M:%SZ)
Commit: ${{ github.sha }}
Firmware Images: $IMG_COUNT
SecuBox Packages: $PKG_COUNT
EOF
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📋 Artifact Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "Device: ${{ matrix.description }}"
echo "Firmware images: $IMG_COUNT files"
echo "SecuBox packages: $PKG_COUNT files"
echo ""
echo "📁 Contents:"
ls -lh
# Export counts for summary
echo "img_count=$IMG_COUNT" >> $GITHUB_OUTPUT
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: secubox-${{ matrix.device }}-${{ env.OPENWRT_VERSION }}
path: artifacts/
retention-days: 30
- name: Generate build summary
if: always()
run: |
echo "# 🎯 Build Complete: ${{ matrix.description }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📊 Build Information" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Device | ${{ matrix.description }} |" >> $GITHUB_STEP_SUMMARY
echo "| Profile | \`${{ matrix.profile }}\` |" >> $GITHUB_STEP_SUMMARY
echo "| Target | ${{ matrix.target }}/${{ matrix.subtarget }} |" >> $GITHUB_STEP_SUMMARY
echo "| OpenWrt Version | ${{ env.OPENWRT_VERSION }} |" >> $GITHUB_STEP_SUMMARY
echo "| SecuBox Included | ${{ github.event.inputs.include_secubox }} |" >> $GITHUB_STEP_SUMMARY
echo "| Build Time | $(date -u +%Y-%m-%d\ %H:%M:%S\ UTC) |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📦 Generated Artifacts" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Type | Count | Files |" >> $GITHUB_STEP_SUMMARY
echo "|------|-------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Firmware Images | ${{ steps.prepare.outputs.img_count }} | \`*.img.gz\`, \`*sysupgrade*\`, \`*factory*\` |" >> $GITHUB_STEP_SUMMARY
echo "| SecuBox Packages | ${{ steps.prepare.outputs.pkg_count }} | \`luci-app-*.ipk\` |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📥 Download Artifacts" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Artifact Name:** \`secubox-${{ matrix.device }}-${{ env.OPENWRT_VERSION }}\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "To download:" >> $GITHUB_STEP_SUMMARY
echo "1. Go to the **Summary** page of this workflow run" >> $GITHUB_STEP_SUMMARY
echo "2. Scroll to the **Artifacts** section at the bottom" >> $GITHUB_STEP_SUMMARY
echo "3. Click on \`secubox-${{ matrix.device }}-${{ env.OPENWRT_VERSION }}\` to download" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ -f artifacts/BUILD_INFO.txt ]]; then
echo "## 📄 Build Details" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat artifacts/BUILD_INFO.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi
echo "## 📋 Firmware Files" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
ls -lh artifacts/*.{img.gz,bin} 2>/dev/null | awk '{print $9, "(" $5 ")"}' | sed 's|artifacts/||' || echo "No firmware images found"
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ -d artifacts/packages ]] && [[ -n "$(ls -A artifacts/packages 2>/dev/null)" ]]; then
echo "## 📦 SecuBox Packages" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
ls -1 artifacts/packages/*.ipk 2>/dev/null | xargs -I{} basename {} || echo "No packages"
echo '```' >> $GITHUB_STEP_SUMMARY
fi
# ============================================
# Create combined release for all devices
# ============================================
release:
needs: [setup, build-image]
runs-on: ubuntu-latest
if: github.event.inputs.device == 'all'
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: firmware
pattern: secubox-*
- name: Organize release
run: |
mkdir -p release
for device_dir in firmware/secubox-*/; do
DEVICE=$(basename "$device_dir" | sed 's/secubox-//' | sed "s/-${{ env.OPENWRT_VERSION }}//")
echo "📦 Processing $DEVICE..."
# Create device archive
tar -czf "release/secubox-firmware-${DEVICE}.tar.gz" -C "$device_dir" .
done
# Global checksums
cd release
sha256sum *.tar.gz > SHA256SUMS
# Release notes
cat > RELEASE_NOTES.md << 'EOF'
# SecuBox Firmware Images
Pre-built firmware images for GlobalScale devices with SecuBox modules pre-installed.
## Included Devices
| Device | SoC | RAM | Description |
|--------|-----|-----|-------------|
| ESPRESSObin V7 | Armada 3720 | 1-2GB | Entry-level |
| ESPRESSObin Ultra | Armada 3720 | 1-2GB | WiFi + PoE |
| Sheeva64 | Armada 3720 | 1GB | Plug computer |
| MOCHAbin | Armada 7040 | 4-8GB | Quad-core + 10G |
## Pre-installed SecuBox Modules
- 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
## Installation
1. Download the appropriate firmware for your device
2. Flash using OpenWrt sysupgrade or manufacturer tools
3. Access LuCI at http://192.168.1.1
4. Navigate to Services → SecuBox
## Support
- [Documentation](https://cybermind.fr/docs/secubox)
- [CyberMind.fr](https://cybermind.fr)
EOF
- name: Create release
if: github.ref == 'refs/heads/main'
uses: softprops/action-gh-release@v2
with:
name: "SecuBox Firmware ${{ env.OPENWRT_VERSION }}"
tag_name: "firmware-${{ env.OPENWRT_VERSION }}-${{ github.run_number }}"
body_path: release/RELEASE_NOTES.md
files: |
release/*.tar.gz
release/SHA256SUMS
draft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ============================================
# Final summary of all builds
# ============================================
summary:
needs: [setup, build-image]
runs-on: ubuntu-latest
if: always()
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: all-artifacts
pattern: secubox-*
continue-on-error: true
- name: Generate final summary
run: |
echo "# 🏗️ SecuBox Firmware Build Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## ⚙️ Build Configuration" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Property | Value |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| OpenWrt Version | ${{ env.OPENWRT_VERSION }} |" >> $GITHUB_STEP_SUMMARY
echo "| SecuBox Included | ${{ github.event.inputs.include_secubox }} |" >> $GITHUB_STEP_SUMMARY
echo "| Target Device | ${{ github.event.inputs.device }} |" >> $GITHUB_STEP_SUMMARY
echo "| Workflow Run | #${{ github.run_number }} |" >> $GITHUB_STEP_SUMMARY
echo "| Triggered by | ${{ github.event_name }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📦 Generated Artifacts" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [[ -d all-artifacts ]]; then
ARTIFACT_COUNT=$(find all-artifacts -type d -mindepth 1 -maxdepth 1 | wc -l)
if [[ $ARTIFACT_COUNT -gt 0 ]]; then
echo "✅ **$ARTIFACT_COUNT artifact(s) available for download**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Device | Artifact Name | Firmware Images | Packages |" >> $GITHUB_STEP_SUMMARY
echo "|--------|---------------|-----------------|----------|" >> $GITHUB_STEP_SUMMARY
for artifact_dir in all-artifacts/secubox-*/; do
if [[ -d "$artifact_dir" ]]; then
ARTIFACT_NAME=$(basename "$artifact_dir")
DEVICE=$(echo "$ARTIFACT_NAME" | sed 's/secubox-//' | sed "s/-${{ env.OPENWRT_VERSION }}//")
# Count files
IMG_COUNT=$(find "$artifact_dir" -maxdepth 1 \( -name "*.img.gz" -o -name "*.bin" -o -name "*sysupgrade*" -o -name "*factory*" \) 2>/dev/null | wc -l)
PKG_COUNT=$(find "$artifact_dir/packages" -name "*.ipk" 2>/dev/null | wc -l)
echo "| $DEVICE | \`$ARTIFACT_NAME\` | $IMG_COUNT | $PKG_COUNT |" >> $GITHUB_STEP_SUMMARY
fi
done
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📥 How to Download" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "1. Navigate to the **Summary** tab of this workflow run" >> $GITHUB_STEP_SUMMARY
echo "2. Scroll to the **Artifacts** section at the bottom of the page" >> $GITHUB_STEP_SUMMARY
echo "3. Click on the artifact name to download the ZIP file" >> $GITHUB_STEP_SUMMARY
echo "4. Extract the ZIP to access firmware images and packages" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📋 Artifact Contents" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Each artifact contains:" >> $GITHUB_STEP_SUMMARY
echo "- **Firmware images**: \`*.img.gz\`, \`*sysupgrade.bin\`, \`*factory.bin\`" >> $GITHUB_STEP_SUMMARY
echo "- **SecuBox packages**: \`luci-app-*.ipk\` (in \`packages/\` subdirectory)" >> $GITHUB_STEP_SUMMARY
echo "- **Checksums**: \`SHA256SUMS\` for verification" >> $GITHUB_STEP_SUMMARY
echo "- **Build info**: \`BUILD_INFO.txt\` with build details" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# List detailed contents of first artifact as example
FIRST_ARTIFACT=$(find all-artifacts -type d -mindepth 1 -maxdepth 1 | head -1)
if [[ -n "$FIRST_ARTIFACT" ]]; then
echo "### 📄 Example: $(basename "$FIRST_ARTIFACT")" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "Firmware Images:" >> $GITHUB_STEP_SUMMARY
find "$FIRST_ARTIFACT" -maxdepth 1 -type f \( -name "*.img.gz" -o -name "*.bin" \) -exec basename {} \; 2>/dev/null | sort || echo " (none)"
echo "" >> $GITHUB_STEP_SUMMARY
if [[ -d "$FIRST_ARTIFACT/packages" ]]; then
echo "SecuBox Packages:" >> $GITHUB_STEP_SUMMARY
find "$FIRST_ARTIFACT/packages" -name "*.ipk" -exec basename {} \; 2>/dev/null | sort || echo " (none)"
fi
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
fi
echo "### 🔐 Verification" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "After downloading, verify file integrity:" >> $GITHUB_STEP_SUMMARY
echo '```bash' >> $GITHUB_STEP_SUMMARY
echo "# Extract artifact" >> $GITHUB_STEP_SUMMARY
echo "unzip secubox-*.zip" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "# Verify checksums" >> $GITHUB_STEP_SUMMARY
echo "sha256sum -c SHA256SUMS" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ **No artifacts were generated**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Check the build logs above for errors." >> $GITHUB_STEP_SUMMARY
fi
else
echo "⚠️ **No artifacts found**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "This may indicate that all builds failed. Check individual job logs for details." >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "---" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "📚 For installation instructions, see the [SecuBox documentation](https://github.com/gkerma/secubox)" >> $GITHUB_STEP_SUMMARY