7 Commits

Author SHA1 Message Date
user
a338c9f65f ci: Fix multiline command syntax for host runner
Some checks failed
Lint & Build / C/C++ Static Analysis (push) Successful in 29s
Lint & Build / Security Flaw Analysis (push) Successful in 20s
Lint & Build / Secret Scanning (push) Successful in 8s
Lint & Build / Shell Script Analysis (push) Successful in 9s
Lint & Build / Build Firmware (push) Successful in 2m4s
Lint & Build / Deploy to ESP Fleet (push) Failing after 1s
2026-02-05 22:18:50 +01:00
user
fbf2e9a7c1 ci: Add OTA progress monitoring with version checks
Some checks are pending
Lint & Build / C/C++ Static Analysis (push) Successful in 29s
Lint & Build / Deploy to ESP Fleet (push) Blocked by required conditions
Lint & Build / Security Flaw Analysis (push) Successful in 21s
Lint & Build / Secret Scanning (push) Successful in 8s
Lint & Build / Shell Script Analysis (push) Successful in 9s
Lint & Build / Build Firmware (push) Successful in 2m24s
2026-02-05 22:11:13 +01:00
user
1377abe248 ci: Run deploy on host instead of container for network access
Some checks failed
Lint & Build / Deploy to ESP Fleet (push) Has been cancelled
Lint & Build / Security Flaw Analysis (push) Has been cancelled
Lint & Build / Secret Scanning (push) Has been cancelled
Lint & Build / Shell Script Analysis (push) Has been cancelled
Lint & Build / C/C++ Static Analysis (push) Has been cancelled
Lint & Build / Build Firmware (push) Has been cancelled
2026-02-05 22:09:47 +01:00
user
551225d308 fix: Remove unused app_size variable (cppcheck)
All checks were successful
Lint & Build / C/C++ Static Analysis (push) Successful in 29s
Lint & Build / Security Flaw Analysis (push) Successful in 22s
Lint & Build / Secret Scanning (push) Successful in 8s
Lint & Build / Shell Script Analysis (push) Successful in 10s
Lint & Build / Build Firmware (push) Successful in 2m21s
Lint & Build / Deploy to ESP Fleet (push) Successful in 3m20s
2026-02-05 22:08:30 +01:00
user
7f2e3f6dad ci: Add ccache for faster builds + parallel OTA deployment
Some checks failed
Lint & Build / C/C++ Static Analysis (push) Failing after 32s
Lint & Build / Security Flaw Analysis (push) Successful in 21s
Lint & Build / Secret Scanning (push) Successful in 8s
Lint & Build / Shell Script Analysis (push) Successful in 10s
Lint & Build / Build Firmware (push) Successful in 2m7s
Lint & Build / Deploy to ESP Fleet (push) Successful in 3m0s
Build improvements:
- Enable ccache via IDF_CCACHE_ENABLE=1
- Mount /var/cache/ccache volume for persistent cache
- Show ccache stats after build

Deployment improvements:
- Deploy to all sensors in parallel (max 3)
- Reduced total deploy time from ~2.5min to ~1min

Note: Runner needs /var/cache/ccache directory with write permissions
2026-02-05 22:02:29 +01:00
user
a85a2d776b ci: Use host network for deploy container
Some checks failed
Lint & Build / C/C++ Static Analysis (push) Failing after 34s
Lint & Build / Security Flaw Analysis (push) Successful in 21s
Lint & Build / Secret Scanning (push) Successful in 7s
Lint & Build / Shell Script Analysis (push) Successful in 10s
Lint & Build / Build Firmware (push) Successful in 1m56s
Lint & Build / Deploy to ESP Fleet (push) Successful in 4m18s
2026-02-05 21:55:21 +01:00
user
6dbab23329 ci: Serve firmware from runner for OTA deployment
Some checks failed
Lint & Build / C/C++ Static Analysis (push) Failing after 37s
Lint & Build / Security Flaw Analysis (push) Successful in 21s
Lint & Build / Secret Scanning (push) Successful in 5s
Lint & Build / Shell Script Analysis (push) Successful in 6s
Lint & Build / Build Firmware (push) Successful in 2m12s
Lint & Build / Deploy to ESP Fleet (push) Successful in 4m19s
Instead of having ESP devices download from Gitea (TLS cert issues),
the runner now serves firmware via local HTTP server and triggers
OTA with the local URL.
2026-02-05 21:48:53 +01:00
2 changed files with 94 additions and 40 deletions

View File

@@ -23,18 +23,32 @@ jobs:
runs-on: anvil runs-on: anvil
container: container:
image: docker.io/espressif/idf:v5.3 image: docker.io/espressif/idf:v5.3
volumes:
- /var/cache/ccache:/ccache
env:
CCACHE_DIR: /ccache
IDF_CCACHE_ENABLE: 1
steps: steps:
- name: Checkout - name: Checkout
run: | run: |
git clone --depth=1 --branch=${{ github.ref_name }} \ git clone --depth=1 --branch=${{ github.ref_name }} \
https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git . https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .
- name: Setup ccache
run: |
apt-get update && apt-get install -y --no-install-recommends ccache
ccache --zero-stats
ccache --show-config | grep -E "(cache_dir|max_size)"
- name: Build firmware - name: Build firmware
run: | run: |
. /opt/esp/idf/export.sh . /opt/esp/idf/export.sh
cd get-started/csi_recv_router cd get-started/csi_recv_router
idf.py build idf.py build
- name: Show ccache stats
run: ccache --show-stats
- name: Show binary size - name: Show binary size
run: | run: |
ls -lh get-started/csi_recv_router/build/*.bin ls -lh get-started/csi_recv_router/build/*.bin
@@ -54,27 +68,19 @@ jobs:
runs-on: anvil runs-on: anvil
needs: build needs: build
if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true' || startsWith(github.ref, 'refs/tags/v') if: github.event_name == 'workflow_dispatch' && github.event.inputs.deploy == 'true' || startsWith(github.ref, 'refs/tags/v')
container: # Run directly on host (no container) to access local network
image: docker.io/espressif/idf:v5.3
steps: steps:
- name: Install tools
run: |
apt-get update && apt-get install -y --no-install-recommends netcat-openbsd curl jq
- name: Checkout - name: Checkout
run: | run: git clone --depth=1 --branch=${{ github.ref_name }} https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git workspace
git clone --depth=1 --branch=${{ github.ref_name }} \
https://oauth2:${{ github.token }}@git.mymx.me/${{ github.repository }}.git .
- name: Build firmware - name: Build firmware
run: | run: |
. /opt/esp/idf/export.sh cd workspace && . $HOME/esp/esp-idf/export.sh && cd get-started/csi_recv_router && idf.py build
cd get-started/csi_recv_router
idf.py build
- name: Create release and upload firmware - name: Create release and upload firmware
env: env:
GITEA_TOKEN: ${{ github.token }} GITEA_TOKEN: ${{ github.token }}
working-directory: workspace
run: | run: |
TAG="${{ github.ref_name }}" TAG="${{ github.ref_name }}"
REPO="${{ github.repository }}" REPO="${{ github.repository }}"
@@ -106,32 +112,88 @@ jobs:
-F "attachment=@get-started/csi_recv_router/build/csi_recv_router.bin" \ -F "attachment=@get-started/csi_recv_router/build/csi_recv_router.bin" \
"$API_URL/repos/$REPO/releases/$RELEASE_ID/assets?name=csi_recv_router.bin" "$API_URL/repos/$REPO/releases/$RELEASE_ID/assets?name=csi_recv_router.bin"
# Store release URL for OTA
FIRMWARE_URL="https://git.mymx.me/$REPO/releases/download/$TAG/csi_recv_router.bin"
echo "Firmware URL: $FIRMWARE_URL"
echo "$FIRMWARE_URL" > /tmp/firmware_url.txt
- name: Deploy via OTA - name: Deploy via OTA
working-directory: workspace
run: | run: |
FIRMWARE_URL=$(cat /tmp/firmware_url.txt) SENSORS="muddy-storm:192.168.129.29 amber-maple:192.168.129.30 hollow-acorn:192.168.129.31"
echo "Using firmware URL: $FIRMWARE_URL" OTA_PORT=8899
EXPECTED_VERSION="${{ github.ref_name }}"
# Deploy to muddy-storm # Get runner IP (first non-loopback interface)
echo "=== Deploying to muddy-storm (192.168.129.29) ===" RUNNER_IP=$(hostname -I | awk '{print $1}')
echo "OTA $FIRMWARE_URL" | nc -u -w 2 192.168.129.29 5501 || true echo "Runner IP: $RUNNER_IP"
sleep 30
# Deploy to amber-maple # Start HTTP server to serve firmware
echo "=== Deploying to amber-maple (192.168.129.30) ===" cd get-started/csi_recv_router/build
echo "OTA $FIRMWARE_URL" | nc -u -w 2 192.168.129.30 5501 || true python3 -m http.server $OTA_PORT &
sleep 30 HTTP_PID=$!
sleep 2
# Deploy to hollow-acorn FIRMWARE_URL="http://${RUNNER_IP}:${OTA_PORT}/csi_recv_router.bin"
echo "=== Deploying to hollow-acorn (192.168.129.31) ===" echo "Firmware URL: $FIRMWARE_URL"
echo "OTA $FIRMWARE_URL" | nc -u -w 2 192.168.129.31 5501 || true
sleep 30
echo "=== Deployment complete ===" # Verify server is running
curl -sI "http://localhost:${OTA_PORT}/csi_recv_router.bin" | head -1
# Deploy to all sensors in parallel
echo "=== Deploying to all sensors in parallel ==="
for entry in $SENSORS; do
NAME="${entry%%:*}"
IP="${entry##*:}"
echo "OTA $FIRMWARE_URL" | nc -u -w 2 "$IP" 5501 &
done
wait
# Monitor progress
echo "=== Monitoring OTA progress (timeout: 90s) ==="
TIMEOUT=90
INTERVAL=5
ELAPSED=0
while [ $ELAPSED -lt $TIMEOUT ]; do
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
echo "--- Progress check at ${ELAPSED}s ---"
ALL_UPDATED=true
for entry in $SENSORS; do
NAME="${entry%%:*}"
IP="${entry##*:}"
# Query sensor version via UDP STATUS command
RESPONSE=$(echo "STATUS" | nc -u -w 1 "$IP" 5501 2>/dev/null || echo "")
VERSION=$(echo "$RESPONSE" | grep -oP 'version=\K[^ ]+' || echo "offline")
if [ "$VERSION" = "$EXPECTED_VERSION" ]; then
echo " $NAME: ✓ $VERSION"
elif [ "$VERSION" = "offline" ] || [ -z "$VERSION" ]; then
echo " $NAME: ⟳ updating..."
ALL_UPDATED=false
else
echo " $NAME: $VERSION (waiting for $EXPECTED_VERSION)"
ALL_UPDATED=false
fi
done
if [ "$ALL_UPDATED" = true ]; then
echo "=== All sensors updated to $EXPECTED_VERSION ==="
break
fi
done
# Stop HTTP server
kill $HTTP_PID 2>/dev/null || true
# Final status
echo "=== Final sensor status ==="
for entry in $SENSORS; do
NAME="${entry%%:*}"
IP="${entry##*:}"
RESPONSE=$(echo "STATUS" | nc -u -w 1 "$IP" 5501 2>/dev/null || echo "")
VERSION=$(echo "$RESPONSE" | grep -oP 'version=\K[^ ]+' || echo "offline")
echo " $NAME: $VERSION"
done
cppcheck: cppcheck:
name: C/C++ Static Analysis name: C/C++ Static Analysis

View File

@@ -1532,14 +1532,6 @@ static int cmd_handle(const char *cmd, char *reply, size_t reply_size)
/* Partition info */ /* Partition info */
const esp_partition_t *running = esp_ota_get_running_partition(); const esp_partition_t *running = esp_ota_get_running_partition();
uint32_t part_size = running ? running->size : 0; uint32_t part_size = running ? running->size : 0;
uint32_t app_size = 0;
if (running) {
esp_app_desc_t desc;
if (esp_ota_get_partition_description(running, &desc) == ESP_OK) {
/* App size not directly available, use partition size */
app_size = part_size;
}
}
snprintf(reply, reply_size, snprintf(reply, reply_size,
"OK STATUS uptime=%s uptime_s=%lld heap=%lu rssi=%d channel=%d tx_power=%d rate=%d csi_rate=%d" "OK STATUS uptime=%s uptime_s=%lld heap=%lu rssi=%d channel=%d tx_power=%d rate=%d csi_rate=%d"