secubox-openwrt/.github/workflows/build-openwrt-packages.yml
CyberMind-FR a15cdfc823 fix(ci): Sync GHA build workflow with local-build.sh methodology
- Split builds into SDK (PKGARCH:=all) and Toolchain (native binaries)
- Mirror OPENWRT_ONLY_PACKAGES list from local-build.sh
- Add all architectures: x86-64, aarch64-cortex-a72, aarch64-cortex-a53,
  aarch64-generic, rockchip-armv8, mips-24kc, mipsel-24kc
- SDK builds: LuCI apps, shell scripts, configs
- Toolchain builds: Go (crowdsec), C++ (netifyd, ndpid)
- Combine artifacts per architecture with checksums
- Create GitHub releases on tags

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-18 12:59:05 +01:00

744 lines
26 KiB
YAML

name: Build OpenWrt Packages
on:
push:
branches: [main, master, develop]
tags:
- 'v*'
pull_request:
branches: [main, master]
workflow_dispatch:
inputs:
openwrt_version:
description: 'OpenWrt version'
required: true
default: '24.10.5'
type: choice
options:
- '24.10.5'
- '23.05.5'
build_toolchain_packages:
description: 'Build toolchain packages (Go/C++)'
required: false
default: true
type: boolean
architectures:
description: 'Architectures (comma-separated or "all")'
required: false
default: 'all'
env:
OPENWRT_VERSION: ${{ github.event.inputs.openwrt_version || '24.10.5' }}
permissions:
contents: write
jobs:
# ============================================
# Setup - determine version and build matrix
# Mirrors: local-build.sh setup logic
# ============================================
setup:
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
version: ${{ steps.version.outputs.version }}
sdk_packages: ${{ steps.packages.outputs.sdk_packages }}
toolchain_packages: ${{ steps.packages.outputs.toolchain_packages }}
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}"
- name: Categorize packages (mirrors local-build.sh OPENWRT_ONLY_PACKAGES)
id: packages
run: |
# Toolchain-only packages (from local-build.sh OPENWRT_ONLY_PACKAGES)
# These compile native code and need full OpenWrt buildroot
TOOLCHAIN_ONLY=(
# C/C++ native binaries
"secubox-app-netifyd"
"secubox-app-ndpid"
"secubox-app-nodogsplash"
# Go binaries
"secubox-app-crowdsec"
"secubox-app-cs-firewall-bouncer"
# Python/special packages
"secubox-app-mitmproxy"
"secubox-app-metablogizer"
"secubox-app-tor"
)
SDK_PACKAGES=""
TOOLCHAIN_PACKAGES=""
# Find all secubox packages
for pkg_dir in package/secubox/*/; do
[ -f "${pkg_dir}Makefile" ] || continue
PKG_NAME=$(basename "$pkg_dir")
# Check if it's in toolchain-only list
IS_TOOLCHAIN=false
for tc_pkg in "${TOOLCHAIN_ONLY[@]}"; do
if [[ "$PKG_NAME" == "$tc_pkg" ]]; then
IS_TOOLCHAIN=true
break
fi
done
if $IS_TOOLCHAIN; then
TOOLCHAIN_PACKAGES="${TOOLCHAIN_PACKAGES}${PKG_NAME},"
else
SDK_PACKAGES="${SDK_PACKAGES}${PKG_NAME},"
fi
done
# Root level luci-app-* (all SDK buildable)
for pkg_dir in luci-app-*/; do
[ -f "${pkg_dir}Makefile" ] || continue
PKG_NAME=$(basename "$pkg_dir")
SDK_PACKAGES="${SDK_PACKAGES}${PKG_NAME},"
done
# luci-theme-secubox
[ -d "luci-theme-secubox" ] && SDK_PACKAGES="${SDK_PACKAGES}luci-theme-secubox,"
echo "sdk_packages=${SDK_PACKAGES%,}" >> $GITHUB_OUTPUT
echo "toolchain_packages=${TOOLCHAIN_PACKAGES%,}" >> $GITHUB_OUTPUT
echo "📦 SDK packages (PKGARCH:=all): ${SDK_PACKAGES%,}"
echo "🔧 Toolchain packages (native binaries): ${TOOLCHAIN_PACKAGES%,}"
- name: Set build matrix (mirrors local-build.sh set_architecture)
id: set-matrix
run: |
# Architecture mapping from local-build.sh
cat > /tmp/matrix.json << 'EOF'
{
"include": [
{
"target": "x86-64",
"arch": "x86_64",
"sdk_path": "x86/64",
"toolchain_target": "x86",
"toolchain_subtarget": "64",
"description": "x86 64-bit (PC, VM)"
},
{
"target": "aarch64-cortex-a72",
"arch": "aarch64_cortex-a72",
"sdk_path": "mvebu/cortexa72",
"toolchain_target": "mvebu",
"toolchain_subtarget": "cortexa72",
"description": "ARM Cortex-A72 (MOCHAbin, RPi4)"
},
{
"target": "aarch64-cortex-a53",
"arch": "aarch64_cortex-a53",
"sdk_path": "mvebu/cortexa53",
"toolchain_target": "mvebu",
"toolchain_subtarget": "cortexa53",
"description": "ARM Cortex-A53 (ESPRESSObin)"
},
{
"target": "aarch64-generic",
"arch": "aarch64_generic",
"sdk_path": "armsr/armv8",
"toolchain_target": "armsr",
"toolchain_subtarget": "armv8",
"description": "ARM 64-bit generic"
},
{
"target": "rockchip-armv8",
"arch": "aarch64_generic",
"sdk_path": "rockchip/armv8",
"toolchain_target": "rockchip",
"toolchain_subtarget": "armv8",
"description": "Rockchip (NanoPi R4S/R5S)"
},
{
"target": "mips-24kc",
"arch": "mips_24kc",
"sdk_path": "ath79/generic",
"toolchain_target": "ath79",
"toolchain_subtarget": "generic",
"description": "MIPS 24Kc (Atheros/QCA)"
},
{
"target": "mipsel-24kc",
"arch": "mipsel_24kc",
"sdk_path": "ramips/mt7621",
"toolchain_target": "ramips",
"toolchain_subtarget": "mt7621",
"description": "MIPS LE (MT7621)"
}
]
}
EOF
# Filter by input architectures if specified
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=$(echo "$MATRIX" | jq -c)" >> $GITHUB_OUTPUT
echo "📋 Build matrix:"
echo "$MATRIX" | jq '.'
# ============================================
# Build SDK packages (LuCI apps, shell scripts)
# Mirrors: local-build.sh SDK build path
# ============================================
build-sdk:
needs: setup
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: SDK ${{ matrix.target }}
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
- 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 rsync 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 }}-v6
- name: Download OpenWrt SDK
if: steps.cache-sdk.outputs.cache-hit != 'true'
run: |
BASE_URL="https://downloads.openwrt.org/releases/${{ env.OPENWRT_VERSION }}/targets/${{ matrix.sdk_path }}"
for attempt in 1 2 3; do
SDK_FILE=$(curl -sL "$BASE_URL/" | grep -oP 'openwrt-sdk[^"<>]+\.tar\.(xz|zst)' | head -1) && break
sleep 10
done
[ -z "$SDK_FILE" ] && { echo "❌ Could not find SDK"; exit 1; }
echo "📥 Downloading: $SDK_FILE"
wget -q "${BASE_URL}/${SDK_FILE}" -O /tmp/sdk.tar.xz
mkdir -p sdk
tar -xf /tmp/sdk.tar.xz -C sdk --strip-components=1
rm -f /tmp/sdk.tar.xz
- name: Setup SDK feeds (mirrors local-build.sh)
run: |
cd sdk
# Remove unwanted feeds (from local-build.sh)
sed -i '/telephony/d; /routing/d' feeds.conf.default 2>/dev/null || true
# Determine branch based on OpenWrt version
VERSION="${{ env.OPENWRT_VERSION }}"
if [[ "$VERSION" =~ ^24\. ]]; then
BRANCH="openwrt-24.10"
elif [[ "$VERSION" =~ ^23\. ]]; then
BRANCH="openwrt-23.05"
else
BRANCH="master"
fi
echo "📌 Using branch: $BRANCH for OpenWrt $VERSION"
cat > feeds.conf << EOF
src-git packages https://github.com/openwrt/packages.git;$BRANCH
src-git luci https://github.com/openwrt/luci.git;$BRANCH
src-link secubox ${{ github.workspace }}/secubox-tools/local-feed
EOF
# Update feeds with retry
for feed in packages luci; do
for attempt in 1 2 3; do
./scripts/feeds update $feed && break
sleep $((10 * attempt))
done
done
./scripts/feeds install -a
make defconfig
- name: Copy packages to SDK
run: |
VERSION="${{ needs.setup.outputs.version }}"
# Sync to local-feed first (mirrors local-build.sh)
mkdir -p secubox-tools/local-feed
for pkg in package/secubox/*/; do
[ -f "${pkg}Makefile" ] || continue
PKG_NAME=$(basename "$pkg")
cp -r "$pkg" "secubox-tools/local-feed/"
# Update version in copied package
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" "secubox-tools/local-feed/${PKG_NAME}/Makefile" 2>/dev/null || true
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" "secubox-tools/local-feed/${PKG_NAME}/Makefile" 2>/dev/null || true
done
# Copy root level luci-app-*
for pkg in luci-app-*/; do
[ -f "${pkg}Makefile" ] || continue
cp -r "$pkg" "secubox-tools/local-feed/"
done
# Copy theme
[ -d "luci-theme-secubox" ] && cp -r "luci-theme-secubox" "secubox-tools/local-feed/"
# Update secubox feed
cd sdk
./scripts/feeds update secubox
./scripts/feeds install -a -p secubox
- name: Build SDK packages
run: |
cd sdk
SDK_PACKAGES="${{ needs.setup.outputs.sdk_packages }}"
echo "📦 Building SDK packages: $SDK_PACKAGES"
# Enable packages
for pkg in ${SDK_PACKAGES//,/ }; do
echo "CONFIG_PACKAGE_${pkg}=m" >> .config
# Remove LUCI_DEPENDS for SDK build (runtime only)
PKG_DIR=$(find package -name "$pkg" -type d | head -1)
[ -n "$PKG_DIR" ] && sed -i 's/^LUCI_DEPENDS:=/#&/' "$PKG_DIR/Makefile" 2>/dev/null || true
done
make defconfig
# Build each package
BUILT=0
FAILED=0
BUILT_LIST=""
FAILED_LIST=""
for pkg in ${SDK_PACKAGES//,/ }; do
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📦 Building: $pkg"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if timeout 300 make package/$pkg/compile V=s -j$(nproc) 2>&1 | tail -30; then
PKG_FILE=$(find bin -name "${pkg}*.ipk" 2>/dev/null | head -1)
if [ -n "$PKG_FILE" ]; then
echo "✅ Built: $pkg → $PKG_FILE"
BUILT=$((BUILT + 1))
BUILT_LIST="${BUILT_LIST}${pkg},"
else
echo "⚠️ No .ipk generated for $pkg"
FAILED=$((FAILED + 1))
FAILED_LIST="${FAILED_LIST}${pkg},"
fi
else
echo "❌ Build failed: $pkg"
FAILED=$((FAILED + 1))
FAILED_LIST="${FAILED_LIST}${pkg},"
fi
done
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 SDK Build Summary for ${{ matrix.target }}"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Built: $BUILT packages"
echo "❌ Failed: $FAILED packages"
[ -n "$BUILT_LIST" ] && echo "Built: ${BUILT_LIST%,}"
[ -n "$FAILED_LIST" ] && echo "Failed: ${FAILED_LIST%,}"
- name: Collect SDK artifacts
id: collect
run: |
mkdir -p artifacts/${{ matrix.target }}
find sdk/bin -name "*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
PKG_COUNT=$(find artifacts/${{ matrix.target }} -name "*.ipk" 2>/dev/null | wc -l)
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
echo "📦 SDK packages for ${{ matrix.target }}: $PKG_COUNT"
ls -la artifacts/${{ matrix.target }}/ 2>/dev/null || echo "None"
# Create checksums
[ "$PKG_COUNT" -gt 0 ] && (cd artifacts/${{ matrix.target }} && sha256sum *.ipk > SHA256SUMS)
- name: Upload SDK artifacts
uses: actions/upload-artifact@v4
if: steps.collect.outputs.pkg_count > 0
with:
name: sdk-packages-${{ matrix.target }}
path: artifacts/${{ matrix.target }}/
retention-days: 30
# ============================================
# Build Toolchain packages (Go, C/C++)
# Mirrors: local-build.sh OpenWrt buildroot path
# ============================================
build-toolchain:
needs: setup
if: github.event.inputs.build_toolchain_packages != 'false' && needs.setup.outputs.toolchain_packages != ''
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
name: Toolchain ${{ matrix.target }}
steps:
- name: Checkout source
uses: actions/checkout@v4
- name: Free disk space
run: |
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
- name: Cache OpenWrt Toolchain
uses: actions/cache@v4
id: cache-toolchain
with:
path: openwrt
key: openwrt-toolchain-${{ env.OPENWRT_VERSION }}-${{ matrix.target }}-v4
- name: Clone OpenWrt
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: |
VERSION="${{ env.OPENWRT_VERSION }}"
if [[ "$VERSION" =~ ^24\. ]]; then
BRANCH="openwrt-24.10"
elif [[ "$VERSION" =~ ^23\. ]]; then
BRANCH="openwrt-23.05"
else
BRANCH="master"
fi
git clone --depth 1 -b "$BRANCH" https://github.com/openwrt/openwrt.git
- name: Setup OpenWrt feeds
run: |
cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a
- name: Configure and build toolchain
if: steps.cache-toolchain.outputs.cache-hit != 'true'
run: |
cd openwrt
# Set target configuration
cat > .config << EOF
CONFIG_TARGET_${{ matrix.toolchain_target }}=y
CONFIG_TARGET_${{ matrix.toolchain_target }}_${{ matrix.toolchain_subtarget }}=y
CONFIG_PACKAGE_golang=y
CONFIG_PACKAGE_golang-src=y
EOF
make defconfig
echo "⚙️ Building toolchain for ${{ matrix.target }}..."
make toolchain/install -j$(nproc) V=s || make toolchain/install -j1 V=s
- name: Copy toolchain packages
run: |
VERSION="${{ needs.setup.outputs.version }}"
TOOLCHAIN_PACKAGES="${{ needs.setup.outputs.toolchain_packages }}"
mkdir -p openwrt/package/secubox
for pkg in ${TOOLCHAIN_PACKAGES//,/ }; do
if [ -d "package/secubox/$pkg" ]; then
cp -r "package/secubox/$pkg" "openwrt/package/secubox/"
sed -i "s/PKG_VERSION:=.*/PKG_VERSION:=$VERSION/" "openwrt/package/secubox/${pkg}/Makefile" 2>/dev/null || true
sed -i "s/PKG_RELEASE:=.*/PKG_RELEASE:=1/" "openwrt/package/secubox/${pkg}/Makefile" 2>/dev/null || true
fi
done
- name: Build toolchain packages
run: |
cd openwrt
TOOLCHAIN_PACKAGES="${{ needs.setup.outputs.toolchain_packages }}"
echo "🔧 Building toolchain packages: $TOOLCHAIN_PACKAGES"
for pkg in ${TOOLCHAIN_PACKAGES//,/ }; do
echo "CONFIG_PACKAGE_${pkg}=m" >> .config
done
make defconfig
BUILT=0
FAILED=0
for pkg in ${TOOLCHAIN_PACKAGES//,/ }; do
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔧 Building: $pkg"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
if timeout 1800 make package/$pkg/compile V=s -j$(nproc) 2>&1 | tail -50; then
PKG_FILE=$(find bin -name "${pkg}*.ipk" 2>/dev/null | head -1)
if [ -n "$PKG_FILE" ]; then
echo "✅ Built: $pkg → $PKG_FILE"
BUILT=$((BUILT + 1))
else
echo "⚠️ No .ipk generated for $pkg"
FAILED=$((FAILED + 1))
fi
else
echo "❌ Build failed: $pkg"
FAILED=$((FAILED + 1))
fi
done
echo ""
echo "📊 Toolchain Build Summary: $BUILT built, $FAILED failed"
- name: Collect toolchain artifacts
id: collect
run: |
mkdir -p artifacts/${{ matrix.target }}
find openwrt/bin -name "*.ipk" -exec cp {} artifacts/${{ matrix.target }}/ \; 2>/dev/null || true
PKG_COUNT=$(find artifacts/${{ matrix.target }} -name "*.ipk" 2>/dev/null | wc -l)
echo "pkg_count=$PKG_COUNT" >> $GITHUB_OUTPUT
echo "🔧 Toolchain packages for ${{ matrix.target }}: $PKG_COUNT"
ls -la artifacts/${{ matrix.target }}/ 2>/dev/null || echo "None"
- name: Upload toolchain artifacts
uses: actions/upload-artifact@v4
if: steps.collect.outputs.pkg_count > 0
with:
name: toolchain-packages-${{ matrix.target }}
path: artifacts/${{ matrix.target }}/
retention-days: 30
# ============================================
# Combine and publish artifacts
# ============================================
publish:
needs: [setup, build-sdk, build-toolchain]
if: always() && (needs.build-sdk.result == 'success' || needs.build-toolchain.result == 'success')
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: packages
pattern: '*-packages-*'
- name: Combine packages per architecture
run: |
VERSION="${{ needs.setup.outputs.version }}"
mkdir -p release
# Combine SDK and toolchain packages per architecture
for dir in packages/*/; do
[ -d "$dir" ] || continue
# Extract architecture from directory name
ARCH=$(basename "$dir" | sed 's/.*-packages-//')
mkdir -p "release/${ARCH}"
# Copy all .ipk files
find "$dir" -name "*.ipk" -exec cp {} "release/${ARCH}/" \; 2>/dev/null || true
done
# Create per-architecture tarballs
for arch_dir in release/*/; do
[ -d "$arch_dir" ] || continue
ARCH=$(basename "$arch_dir")
PKG_COUNT=$(find "$arch_dir" -name "*.ipk" | wc -l)
if [ "$PKG_COUNT" -gt 0 ]; then
tar -czf "release/secubox-${VERSION}-${ARCH}.tar.gz" -C "release/${ARCH}" .
echo "📦 $ARCH: $PKG_COUNT packages"
fi
done
# Create all-in-one archive
tar -czf "release/secubox-${VERSION}-all-architectures.tar.gz" -C release .
# Checksums
cd release
sha256sum *.tar.gz > SHA256SUMS 2>/dev/null || true
echo ""
echo "📋 Release contents:"
ls -la
- 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
# ============================================
# Create GitHub Release (on tags)
# ============================================
release:
needs: [setup, publish]
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
steps:
- name: Download release artifact
uses: actions/download-artifact@v4
with:
name: secubox-release-${{ needs.setup.outputs.version }}
path: release
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
name: SecuBox v${{ needs.setup.outputs.version }}
body: |
## 📦 SecuBox Packages v${{ needs.setup.outputs.version }}
Pre-built OpenWrt packages for OpenWrt ${{ env.OPENWRT_VERSION }}.
### 📥 Installation
```bash
# Upload .ipk files to router
opkg update
opkg install /tmp/*.ipk
/etc/init.d/rpcd restart
```
### 🏗️ Supported Architectures
| Target | Description |
|--------|-------------|
| `x86-64` | PC, VMs, Proxmox |
| `aarch64-cortex-a72` | MOCHAbin, Raspberry Pi 4 |
| `aarch64-cortex-a53` | ESPRESSObin |
| `aarch64-generic` | NanoPi R4S/R5S, Generic ARM64 |
| `rockchip-armv8` | NanoPi R4S/R5S (Rockchip) |
| `mips-24kc` | TP-Link, Atheros/QCA |
| `mipsel-24kc` | Xiaomi, GL.iNet, MT7621 |
### 📦 Package Types
- **SDK packages**: LuCI apps, shell scripts (PKGARCH:=all)
- **Toolchain packages**: Go binaries (crowdsec), C++ binaries (netifyd)
files: |
release/*.tar.gz
release/SHA256SUMS
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# ============================================
# Summary
# ============================================
summary:
needs: [setup, build-sdk, build-toolchain, publish]
if: always()
runs-on: ubuntu-latest
steps:
- name: Download artifacts for summary
uses: actions/download-artifact@v4
with:
path: packages
pattern: '*-packages-*'
continue-on-error: true
- name: Generate summary
run: |
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 "" >> $GITHUB_STEP_SUMMARY
echo "## Package Categories" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**SDK Packages** (PKGARCH:=all):" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ needs.setup.outputs.sdk_packages }}" | tr ',' '\n' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Toolchain Packages** (native binaries):" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "${{ needs.setup.outputs.toolchain_packages }}" | tr ',' '\n' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Build Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
echo "| SDK Build | ${{ needs.build-sdk.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Toolchain Build | ${{ needs.build-toolchain.result }} |" >> $GITHUB_STEP_SUMMARY
echo "| Publish | ${{ needs.publish.result }} |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Packages per Architecture" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Architecture | SDK | Toolchain | Total |" >> $GITHUB_STEP_SUMMARY
echo "|--------------|-----|-----------|-------|" >> $GITHUB_STEP_SUMMARY
for dir in packages/*/; do
[ -d "$dir" ] || continue
ARCH=$(basename "$dir" | sed 's/.*-packages-//')
TYPE=$(basename "$dir" | sed 's/-packages-.*//')
COUNT=$(find "$dir" -name "*.ipk" 2>/dev/null | wc -l)
if [[ "$TYPE" == "sdk" ]]; then
echo "| $ARCH | $COUNT | - | $COUNT |" >> $GITHUB_STEP_SUMMARY
else
echo "| $ARCH | - | $COUNT | $COUNT |" >> $GITHUB_STEP_SUMMARY
fi
done