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
765 lines
32 KiB
YAML
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
|