secubox-deb/.github/workflows/build-image.yml
CyberMind-FR 3d52b63d26 ci: drop espressobin-v7 + espressobin-ultra from scheduled image matrix (ref #503)
The two boards fail in the cross-arm64 chroot stage of build-image.yml
and (even with fail-fast: false) block the downstream release.yml job
from publishing the OTHER boards' images.  Releases v2.13.9 through
v2.13.12 all hit this trap.

This change keeps both entries available via workflow_dispatch (operators
can still build them on-demand), but removes them from the push-tag
scheduled matrix so mochabin / vm-x64 / rpi400 actually ship on tag.

Board support files (board/espressobin-*/, image/build-image.sh
--board espressobin-*) stay in tree.

  - build-image.yml matrix excludes espressobin-v7 + espressobin-ultra
    on push and workflow_call.
  - build-image.yml workflow_dispatch choice list keeps both entries
    flagged as on-demand only.
  - Release notes template drops the two image rows, adds a note
    explaining the on-demand path.
  - Install instruction adjusted (MOCHAbin + Raspberry Pi 400).
2026-06-09 09:42:08 +02:00

282 lines
9.7 KiB
YAML

name: Build SecuBox System Images
on:
workflow_call:
inputs:
board:
description: 'Target board'
required: false
type: string
default: 'all'
size:
description: 'Image size (empty = use board default)'
required: false
type: string
default: ''
secrets:
GPG_PRIVATE_KEY:
required: false
workflow_dispatch:
inputs:
board:
description: 'Target board'
required: true
type: choice
options:
- mochabin
- espressobin-v7 # on-demand only — disabled in scheduled CI, ref #503
- espressobin-ultra # on-demand only — disabled in scheduled CI, ref #503
- vm-x64
- vm-arm64
- rpi400
- all
default: vm-x64
size:
description: 'Image size (empty = use board default)'
required: false
default: ''
push:
tags:
- 'v*'
env:
DEBIAN_SUITE: bookworm
jobs:
# Build system images
build-image:
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
# Handle all event types: push (tags), workflow_call, workflow_dispatch
# Scheduled / tag-push matrix excludes espressobin-v7 + espressobin-ultra (#503) :
# those board builds fail in the cross-arm64 chroot stage and block the
# downstream release.yml job for every image even though fail-fast is off.
# Operators can still build them on-demand via workflow_dispatch (the
# choice list above retains the entries).
board: ${{ (github.event_name == 'push' || (inputs.board == 'all' || inputs.board == '')) && fromJson('["mochabin","vm-x64","rpi400"]') || (github.event.inputs.board == 'all' && fromJson('["mochabin","vm-x64","rpi400"]') || fromJson(format('["{0}"]', inputs.board || github.event.inputs.board || 'vm-x64'))) }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Free disk space
run: |
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc
df -h
- name: Setup QEMU + binfmt
if: contains(matrix.board, 'arm') || contains(matrix.board, 'espresso') || contains(matrix.board, 'mocha')
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Install build tools
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq \
debootstrap qemu-user-static binfmt-support \
parted dosfstools e2fsprogs rsync \
gzip pigz xz-utils
- name: Download package artifacts
uses: dawidd6/action-download-artifact@v3
with:
workflow: build-packages.yml
name: secubox-debs-all
path: output/debs/
if_no_artifact_found: warn
continue-on-error: true
- name: List available packages
run: |
echo "=== SecuBox packages to slipstream ==="
ls output/debs/secubox-*.deb 2>/dev/null | wc -l || echo "0"
ls output/debs/secubox-*.deb 2>/dev/null | xargs -I{} basename {} | sed 's/_.*$//' | sort -u || echo "No packages found"
- name: Determine architecture
id: arch
run: |
case "${{ matrix.board }}" in
vm-x64)
echo "arch=amd64" >> $GITHUB_OUTPUT
echo "is_arm=false" >> $GITHUB_OUTPUT
;;
*)
echo "arch=arm64" >> $GITHUB_OUTPUT
echo "is_arm=true" >> $GITHUB_OUTPUT
;;
esac
- name: Build image for ${{ matrix.board }}
env:
DEBIAN_FRONTEND: noninteractive
run: |
# Use slipstream if packages are available
SLIPSTREAM_OPT=""
if ls output/debs/secubox-*.deb >/dev/null 2>&1; then
SLIPSTREAM_OPT="--slipstream"
echo "Slipstream enabled: $(ls output/debs/secubox-*.deb | wc -l) packages"
fi
# Build with board-specific size (from board/*/config.mk)
SIZE_OPT=""
if [ -n "${{ inputs.size || github.event.inputs.size }}" ]; then
SIZE_OPT="--size ${{ inputs.size || github.event.inputs.size }}"
fi
sudo -E bash image/build-image.sh \
--board ${{ matrix.board }} \
--suite ${{ env.DEBIAN_SUITE }} \
--out output/ \
$SIZE_OPT \
$SLIPSTREAM_OPT
sudo chown -R $(id -u):$(id -g) output/
timeout-minutes: 90
- name: List output
run: |
ls -lh output/
- name: Generate checksums
run: |
cd output/
sha256sum *.img.gz > SHA256SUMS 2>/dev/null || echo "No images found" > SHA256SUMS
cat SHA256SUMS
- name: Upload image artifact
uses: actions/upload-artifact@v4
with:
name: secubox-${{ matrix.board }}-${{ env.DEBIAN_SUITE }}
path: |
output/*.img.gz
output/SHA256SUMS
if-no-files-found: error
retention-days: 30
# Collect all images and create release
release:
needs: build-image
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: images/
merge-multiple: true
- name: Generate combined checksums
run: |
cd images/
# Remove individual SHA256SUMS files
rm -f SHA256SUMS
# Generate combined checksums
sha256sum *.img.gz 2>/dev/null | sort > SHA256SUMS || echo "No images" > SHA256SUMS
cat SHA256SUMS
- name: Sign checksums
env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
run: |
if [ -n "$GPG_PRIVATE_KEY" ]; then
echo "$GPG_PRIVATE_KEY" | gpg --batch --import
cd images/
gpg --clearsign SHA256SUMS
mv SHA256SUMS.asc SHA256SUMS.gpg
fi
- name: Checkout for scripts
uses: actions/checkout@v4
with:
sparse-checkout: image
- name: Delete existing release assets (if any)
run: |
VERSION="${{ github.ref_name }}"
if gh release view "$VERSION" &>/dev/null; then
echo "Release $VERSION exists, deleting duplicate assets..."
for file in images/*.img.gz images/SHA256SUMS images/SHA256SUMS.gpg image/create-qemu-arm64-vm.sh image/create-vbox-vm.sh; do
[ -f "$file" ] || continue
name=$(basename "$file")
gh release delete-asset "$VERSION" "$name" --yes 2>/dev/null || true
done
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
files: |
images/*.img.gz
images/SHA256SUMS
images/SHA256SUMS.gpg
image/create-qemu-arm64-vm.sh
image/create-vbox-vm.sh
body: |
## SecuBox-DEB ${{ github.ref_name }} System Images
Flashable system images for SecuBox appliances.
### Available Images
| Image | Board | Architecture | Description |
|-------|-------|--------------|-------------|
| `secubox-mochabin-bookworm.img.gz` | MOCHAbin | arm64 | Marvell Armada 7040 (Pro) |
| `secubox-rpi400-bookworm.img.gz` | Raspberry Pi 400 | arm64 | Pi 400 / Pi 4 |
| `secubox-vm-x64-bookworm.img.gz` | VirtualBox/QEMU | amd64 | VM for testing |
| `create-qemu-arm64-vm.sh` | QEMU ARM64 | script | Run ARM64 on x86 hosts |
*ESPRESSObin v7 and Ultra board images are no longer published in
scheduled releases (see #503). Board support remains in tree and
on-demand builds are available via workflow_dispatch.*
### Installation
**ARM64 boards (MOCHAbin, Raspberry Pi 400):**
```bash
# Flash to SD card or eMMC
gunzip -c secubox-mochabin-bookworm.img.gz | sudo dd of=/dev/sdX bs=4M status=progress
sync
```
**VirtualBox (x64):**
```bash
# Convert to VDI
gunzip secubox-vm-x64-bookworm.img.gz
VBoxManage convertfromraw secubox-vm-x64-bookworm.img secubox.vdi --format VDI
# Create VM
VBoxManage createvm --name SecuBox --ostype Debian_64 --register
VBoxManage modifyvm SecuBox --memory 2048 --cpus 2 --nic1 nat
VBoxManage storagectl SecuBox --name SATA --add sata
VBoxManage storageattach SecuBox --storagectl SATA --port 0 --device 0 --type hdd --medium secubox.vdi
```
### Verification
```bash
sha256sum -c SHA256SUMS
gpg --verify SHA256SUMS.gpg
```
### Default Credentials
- **SSH:** root / (SSH key only, set during firstboot)
- **Web UI:** https://secubox.local:8443 (admin / generated at firstboot)
### Included Packages
**124 SecuBox packages** across all security domains:
- **Core:** hub, core, portal, system, console
- **Security:** crowdsec, waf, auth, nac, threats, ipblock, mac-guard
- **Networking:** wireguard, haproxy, dpi, qos, netmodes, vhost, cdn
- **Applications:** mail, gitea, nextcloud, ollama, jellyfin, matrix
- **SOC:** soc-agent, soc-gateway, soc-web
- **Intel:** device-intel, vortex-dns, vortex-firewall, ai-insights
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}