feat(build): fetch QEMU binaries from velxio.dev license endpoint

The qemu-prebuilt GitHub Release was the convenience-binary hosting
path before we shipped the license module. With the license module
live at /api/pro/license/downloads/, the prebuilts now live there
behind a free personal-tier key.

Dockerfile.standalone:
  - New build-args VELXIO_LICENSE_KEY + VELXIO_BINARY_BASE_URL
  - prebuilt/qemu/ local files still win first (lets users compile
    QEMU from source per docs/BUILD-QEMU.md and use that instead)
  - Legacy QEMU_RELEASE_URL kept as escape hatch for private mirrors
  - Fail-fast with a friendly message if no path is configured

backend-e2e-tests workflow:
  - Reads secrets.VELXIO_BUILD_LICENSE_KEY (set in repo settings)
  - Uses the gated URL pattern; same fallback message on missing key

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
davidmonterocrespo24 2026-05-14 05:55:38 +02:00
parent 1dd1d37696
commit 36bd49f507
2 changed files with 83 additions and 17 deletions

View File

@ -12,7 +12,10 @@ jobs:
timeout-minutes: 30
env:
QEMU_RELEASE_URL: https://github.com/davidmonterocrespo24/velxio/releases/download/qemu-prebuilt
# velxio.dev gated download endpoint (license module). Override
# via the legacy QEMU_RELEASE_URL env if you mirror the binaries
# to a private CDN.
VELXIO_BINARY_BASE_URL: https://velxio.dev/api/pro/license/downloads
QEMU_DIR: /opt/velxio-qemu
BACKEND_URL: http://localhost:8001
@ -33,19 +36,28 @@ jobs:
libslirp0
# ── QEMU binaries + ROM files ──────────────────────────────────────────────
# Repository-level secret VELXIO_BUILD_LICENSE_KEY holds a free
# personal-tier key generated at https://velxio.dev/license/signup ;
# rotate via the admin panel if it leaks.
- name: Download QEMU binaries and ROM files
env:
VELXIO_LICENSE_KEY: ${{ secrets.VELXIO_BUILD_LICENSE_KEY }}
run: |
if [ -z "$VELXIO_LICENSE_KEY" ]; then
echo "::error ::secrets.VELXIO_BUILD_LICENSE_KEY is not set. Add it under Settings → Secrets and variables → Actions. Get a free key from https://velxio.dev/license/signup."
exit 1
fi
mkdir -p $QEMU_DIR
cd $QEMU_DIR
echo "Downloading QEMU shared libraries..."
curl -fSL -o libqemu-xtensa.so "$QEMU_RELEASE_URL/libqemu-xtensa-amd64.so"
curl -fSL -o libqemu-riscv32.so "$QEMU_RELEASE_URL/libqemu-riscv32-amd64.so"
curl -fSL -o libqemu-xtensa.so "$VELXIO_BINARY_BASE_URL/libqemu-xtensa-amd64?key=$VELXIO_LICENSE_KEY"
curl -fSL -o libqemu-riscv32.so "$VELXIO_BINARY_BASE_URL/libqemu-riscv32-amd64?key=$VELXIO_LICENSE_KEY"
echo "Downloading ROM files..."
curl -fSL -o esp32-v3-rom.bin "$QEMU_RELEASE_URL/esp32-v3-rom.bin"
curl -fSL -o esp32-v3-rom-app.bin "$QEMU_RELEASE_URL/esp32-v3-rom-app.bin"
curl -fSL -o esp32c3-rom.bin "$QEMU_RELEASE_URL/esp32c3-rom.bin"
curl -fSL -o esp32-v3-rom.bin "$VELXIO_BINARY_BASE_URL/esp32-v3-rom?key=$VELXIO_LICENSE_KEY"
curl -fSL -o esp32-v3-rom-app.bin "$VELXIO_BINARY_BASE_URL/esp32-v3-rom-app?key=$VELXIO_LICENSE_KEY"
curl -fSL -o esp32c3-rom.bin "$VELXIO_BINARY_BASE_URL/esp32c3-rom?key=$VELXIO_LICENSE_KEY"
chmod +x libqemu-xtensa.so libqemu-riscv32.so
ls -lh .

View File

@ -1,36 +1,90 @@
# ---- Stage 0: QEMU .so + ROM binaries ----
# Downloads arch-specific .so from GitHub Release (e.g. libqemu-xtensa-amd64.so)
# and renames to libqemu-xtensa.so so the backend needs no changes.
# Local prebuilt files (prebuilt/qemu/) are used if present.
# The Velxio runtime needs libqemu-xtensa.so + libqemu-riscv32.so (the
# QEMU shared libraries that simulate ESP32 / ESP32-S3 / ESP32-C3) plus
# the matching boot ROM blobs. Three sources, tried in order:
#
# 1. Local prebuilt files at prebuilt/qemu/<file>.
# Drop your own compiled .so files in there (see docs/BUILD-QEMU.md
# for the full build-from-source guide) and they win — no network
# access required.
#
# 2. velxio.dev gated download endpoint, when VELXIO_LICENSE_KEY is set.
# Free personal-tier keys at https://velxio.dev/license/signup.
#
# 3. Build fails with a clear error telling you which of the two paths
# to pick.
#
# Backward compatibility: the old QEMU_RELEASE_URL ARG is still accepted
# so forks pointing at a private mirror of the binaries keep working.
FROM ubuntu:22.04 AS qemu-provider
RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \
&& rm -rf /var/lib/apt/lists/*
ARG TARGETARCH
ARG QEMU_RELEASE_URL=https://github.com/davidmonterocrespo24/velxio/releases/download/qemu-prebuilt
ARG VELXIO_LICENSE_KEY=
ARG VELXIO_BINARY_BASE_URL=https://velxio.dev/api/pro/license/downloads
# Legacy escape hatch — set this to keep using the old GitHub Release
# mirror (or any other CDN you proxy from). When set, takes precedence
# over the gated path.
ARG QEMU_RELEASE_URL=
# Copy the prebuilt directory (may contain .so+ROM files or just the .gitkeep)
RUN mkdir -p /qemu
COPY prebuilt/qemu/ /qemu/
# Download arch-specific .so and arch-independent ROM files
# Resolve which fetch path the build will use and fail-fast with a
# friendly message if neither prebuilt files nor a key were provided.
RUN cd /qemu \
&& have_libs=1 && for base in libqemu-xtensa libqemu-riscv32; do \
[ -f "${base}.so" ] || have_libs=0 ; \
done \
&& if [ "$have_libs" = "1" ]; then \
echo "[qemu-provider] using local prebuilt/qemu/ files — no download" ; \
elif [ -n "${QEMU_RELEASE_URL}" ]; then \
echo "[qemu-provider] using legacy QEMU_RELEASE_URL: ${QEMU_RELEASE_URL}" ; \
elif [ -n "${VELXIO_LICENSE_KEY}" ]; then \
echo "[qemu-provider] using velxio.dev gated download with provided license key" ; \
else \
echo "" ; \
echo "ERROR: Velxio docker build needs the QEMU runtime libraries." ; \
echo "" ; \
echo "Pick one:" ; \
echo " a) Free personal key from https://velxio.dev/license/signup ," ; \
echo " then re-build with --build-arg VELXIO_LICENSE_KEY=vlx_personal_..." ; \
echo " b) Build QEMU yourself (see docs/BUILD-QEMU.md) and drop the .so" ; \
echo " files plus the three esp32*-rom.bin files into prebuilt/qemu/." ; \
echo "" ; \
exit 1 ; \
fi
# Download arch-specific .so and arch-independent ROM files.
# The gated endpoint serves the same byte-for-byte content as the legacy
# GitHub Release path; asset paths just drop the .so extension since the
# license module's manifest carries the real filename.
RUN cd /qemu \
&& for base in libqemu-xtensa libqemu-riscv32; do \
f="${base}.so" ; \
if [ ! -f "$f" ]; then \
echo "Downloading ${base}-${TARGETARCH}.so → $f ..." ; \
if [ -f "$f" ]; then \
echo "Using local $f ($(stat -c%s "$f") bytes)" ; \
elif [ -n "${QEMU_RELEASE_URL}" ]; then \
echo "Downloading ${base}-${TARGETARCH}.so → $f (legacy URL) ..." ; \
curl -fSL -o "$f" "${QEMU_RELEASE_URL}/${base}-${TARGETARCH}.so" ; \
else \
echo "Using local $f ($(stat -c%s "$f") bytes)" ; \
echo "Downloading ${base}-${TARGETARCH}$f (velxio.dev) ..." ; \
curl -fSL -o "$f" "${VELXIO_BINARY_BASE_URL}/${base}-${TARGETARCH}?key=${VELXIO_LICENSE_KEY}" ; \
fi ; \
done \
&& for f in esp32-v3-rom.bin esp32-v3-rom-app.bin esp32c3-rom.bin; do \
if [ ! -f "$f" ]; then \
echo "Downloading $f ..." ; \
asset="${f%.bin}" ; \
if [ -f "$f" ]; then \
echo "Using local $f ($(stat -c%s "$f") bytes)" ; \
elif [ -n "${QEMU_RELEASE_URL}" ]; then \
echo "Downloading $f (legacy URL) ..." ; \
curl -fSL -o "$f" "${QEMU_RELEASE_URL}/$f" ; \
else \
echo "Using local $f ($(stat -c%s "$f") bytes)" ; \
echo "Downloading $asset$f (velxio.dev) ..." ; \
curl -fSL -o "$f" "${VELXIO_BINARY_BASE_URL}/${asset}?key=${VELXIO_LICENSE_KEY}" ; \
fi ; \
done \
&& ls -lh /qemu/