secubox-openwrt/.github/workflows/build-secubox-images.yml

751 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 }}
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
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