From 63ff9c49317fbda849155e9b82187a0abc9b79c5 Mon Sep 17 00:00:00 2001 From: user Date: Thu, 5 Feb 2026 12:20:19 +0100 Subject: [PATCH] ci: Add deploy job for OTA firmware updates - Triggers on manual workflow_dispatch with deploy=true - Triggers automatically on version tags (v*) - Deploys to muddy-storm, amber-maple, hollow-acorn via OTA - Uses podman to rebuild, then serves firmware via HTTP --- .gitea/workflows/lint.yml | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/.gitea/workflows/lint.yml b/.gitea/workflows/lint.yml index 3d9c39f..719a469 100644 --- a/.gitea/workflows/lint.yml +++ b/.gitea/workflows/lint.yml @@ -3,8 +3,19 @@ name: Lint & Build on: push: branches: [main] + tags: ['v*'] pull_request: branches: [main] + workflow_dispatch: + inputs: + deploy: + description: 'Deploy to ESP fleet after build' + required: false + default: 'false' + type: choice + options: + - 'false' + - 'true' jobs: build: @@ -27,6 +38,72 @@ jobs: - name: Show binary size run: | ls -lh get-started/csi_recv_router/build/*.bin + + - name: Upload firmware artifact + run: | + mkdir -p /tmp/artifacts + cp get-started/csi_recv_router/build/csi_recv_router.bin /tmp/artifacts/ + cp get-started/csi_recv_router/build/bootloader/bootloader.bin /tmp/artifacts/ + cp get-started/csi_recv_router/build/partition_table/partition-table.bin /tmp/artifacts/ + cp get-started/csi_recv_router/build/ota_data_initial.bin /tmp/artifacts/ + echo "Artifacts ready in /tmp/artifacts" + ls -la /tmp/artifacts/ + + deploy: + name: Deploy to ESP Fleet + runs-on: anvil + needs: build + if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true' || startsWith(github.ref, 'refs/tags/v') + steps: + - name: Checkout + run: | + git clone --depth=1 --branch=${{ github.ref_name }} \ + https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git . + + - name: Rebuild firmware for deploy + run: | + podman run --rm -v $(pwd):/project -w /project docker.io/espressif/idf:v5.3 \ + bash -c ". /opt/esp/idf/export.sh && cd get-started/csi_recv_router && idf.py build" + + - name: Deploy via OTA + run: | + FIRMWARE="$(pwd)/get-started/csi_recv_router/build/csi_recv_router.bin" + SENSORS="muddy-storm amber-maple hollow-acorn" + PORT=8070 + + # Get runner IP (first non-loopback IPv4) + RUNNER_IP=$(hostname -I | awk '{print $1}') + echo "Runner IP: $RUNNER_IP" + + # Start HTTP server in background + cd get-started/csi_recv_router/build + python3 -m http.server $PORT & + HTTP_PID=$! + sleep 2 + + # Deploy to each sensor + for sensor in $SENSORS; do + echo "=== Deploying to $sensor ===" + # Resolve mDNS hostname + SENSOR_IP=$(getent hosts ${sensor}.local | awk '{print $1}' || avahi-resolve -n ${sensor}.local 2>/dev/null | awk '{print $2}') + if [ -z "$SENSOR_IP" ]; then + echo "Warning: Could not resolve $sensor.local, skipping" + continue + fi + echo "Sensor IP: $SENSOR_IP" + + # Send OTA command via UDP + echo "OTA http://${RUNNER_IP}:${PORT}/csi_recv_router.bin" | nc -u -w 2 $SENSOR_IP 5501 + echo "OTA command sent to $sensor" + + # Wait for device to download and reboot + sleep 30 + done + + # Cleanup + kill $HTTP_PID 2>/dev/null || true + echo "=== Deployment complete ===" + cppcheck: name: C/C++ Static Analysis runs-on: anvil