From 7e2ed4af485c1567183e9ec25a502804caaa6f4c Mon Sep 17 00:00:00 2001 From: AlexMikhalev Date: Fri, 7 Aug 2026 19:41:33 +0100 Subject: [PATCH] ci: harden firecracker workflow diagnostics Improve Firecracker VM creation diagnostics by logging HTTP status/body and handling curl transport errors before JSON parsing. Run cargo nextest directly instead of through rch exec because rch's non-compilation path loses shell quoting around nextest filter expressions. Verification: - workflow YAML parsed - extracted Create VM shell passed bash -n - simulated 201, HTTP 500, and curl transport failure paths - independent review passed --- .github/workflows/ci-firecracker.yml | 36 +++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-firecracker.yml b/.github/workflows/ci-firecracker.yml index 01c8cdb0d..e7c07bde7 100644 --- a/.github/workflows/ci-firecracker.yml +++ b/.github/workflows/ci-firecracker.yml @@ -42,10 +42,30 @@ jobs: - name: Create VM id: vm run: | - RESPONSE=$(curl -sf -X POST $FCCTL_URL/api/vms \ + RESPONSE_FILE=$(mktemp) + trap 'rm -f "${RESPONSE_FILE}"' EXIT + if HTTP_STATUS=$(curl -sS -o "$RESPONSE_FILE" -w "%{http_code}" -X POST "$FCCTL_URL/api/vms" \ -H 'Content-Type: application/json' \ - -d "{\"vm_type\": \"$VM_TYPE\"}") + -d "{\"vm_type\": \"$VM_TYPE\"}"); then + : + else + CURL_EXIT=$? + RESPONSE=$(cat "$RESPONSE_FILE") + echo "fcctl create transport failed: curl exit $CURL_EXIT" + if [ -n "$RESPONSE" ]; then + echo "$RESPONSE" + fi + exit 1 + fi + RESPONSE=$(cat "$RESPONSE_FILE") + rm -f "$RESPONSE_FILE" + trap - EXIT + echo "fcctl create status: $HTTP_STATUS" echo "$RESPONSE" + if [ "$HTTP_STATUS" -lt 200 ] || [ "$HTTP_STATUS" -ge 300 ]; then + echo "ERROR: fcctl-web VM create failed with HTTP $HTTP_STATUS" + exit 1 + fi VM_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])") if [ -z "$VM_ID" ] || [ "$VM_ID" = "null" ]; then echo "ERROR: failed to parse vm id from response" @@ -144,8 +164,8 @@ jobs: # bigbox; see .cargo/config.toml for the Darwin `dynamic_lookup` # linker workaround on local Mac dev. # - # All cargo invocations are dispatched via `rch exec --` so they - # share rchd's queue + slot accounting with ADF agents (see + # Build-oriented cargo invocations are dispatched via `rch exec --` so + # they share rchd's queue + slot accounting with ADF agents (see # .docs/adr-rch-build-queue-not-firecracker-ci.md). Fail-open: if # rchd is down or no slot is available, rch falls through to local # cargo with no behaviour change. @@ -161,7 +181,7 @@ jobs: - name: Install cargo-nextest run: | if ! command -v cargo-nextest >/dev/null 2>&1; then - cargo install cargo-nextest --locked + curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C "${CARGO_HOME:-$HOME/.cargo}/bin" fi cargo nextest --version @@ -169,7 +189,11 @@ jobs: # Only test_chat_command is skipped: it requires LLM API credentials # not present in CI. All other failures must be fixed at the source, # not skipped. nextest uses filter expressions instead of --skip. - run: /home/alex/.local/bin/rch exec -- cargo nextest run --workspace --profile ci -E 'not test(test_chat_command)' + # Do not wrap this invocation in `rch exec`: rch's non-compilation + # command path loses shell quoting around the filter expression and + # makes `/bin/sh` parse the parentheses in `test(...)`. + # `RUSTC_WRAPPER=sccache` above still applies to rustc invocations. + run: cargo nextest run --workspace --profile ci -E 'not test(test_chat_command)' - name: sccache stats if: always()