mirror of
https://github.com/imjasonh/esp32
synced 2026-07-08 00:15:18 +00:00
Implements provisioning-plan.md. The OTA-distributed firmware no longer contains any secrets or per-device config — those live in NVS and are written via USB by `make provision` from a (gitignored) `provisioning.toml`. Same firmware bytes can run on any device. Firmware changes: - src/main.rs reads wifi/ssid + wifi/pass from NVS namespace `wifi`. Strict-inert (sit-and-log) when missing; no compile-time fallback. WIFI_SSID/WIFI_PASS env! macros gone. - src/trust.rs becomes a `TrustConfig::load(nvs)` loader. Identities come from NVS namespace `trust`, key `identities` (JSON-encoded array). Sigstore root + intermediate PEMs come from `trust/fulcio_root` and `trust/fulcio_inter` blobs. include_str! gone. - src/sig.rs and src/ota.rs thread &TrustConfig through verify_bundle and the OTA loop instead of reading global consts. - build.rs no longer tracks WIFI_* env changes. New tool: - tools/provision/ host-side cargo crate. Reads provisioning.toml, emits an NVS CSV, shells out to ESP-IDF's nvs_partition_gen.py to produce a binary NVS image, optionally `espflash write-bin`'s it. Make targets: - `make provision` — build NVS image + flash it. - `make bootstrap` — flash-all + provision (new device setup). - `make build` no longer requires wifi.env. - wifi.env removed from prereqs / WIFI_ENV variable removed. Workflows: - ci.yml: drops the placeholder wifi.env step, adds a `build provision` job alongside the firmware + publisher jobs. - publish.yml: drops WIFI_SSID/WIFI_PASS secret reads. Only secret needed is the auto-injected GITHUB_TOKEN. Docs: - README updated to use `make bootstrap` + `make provision` flow. Project layout moved to a new repo-local CLAUDE.md. - provisioning.toml.example committed as the template the user copies. - wifi.env.example removed (no longer used). Migration: existing devices need `make bootstrap` over USB. The new firmware has no embedded creds; OTAing to it without provisioning would just sit in strict-inert. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
94 lines
2.7 KiB
YAML
94 lines
2.7 KiB
YAML
name: CI
|
|
|
|
# Build verification on PRs (and pushes to main, redundantly with the
|
|
# publish workflow but harmless and gives faster feedback).
|
|
#
|
|
# No publishing or signing — that's publish.yml's job. This workflow
|
|
# just confirms the code compiles for both targets (esp32 firmware
|
|
# and the host-side publisher tool).
|
|
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
|
|
# Per-PR concurrency: a new push to a branch cancels the in-flight CI
|
|
# for older commits on the same branch. Doesn't affect other PRs.
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
firmware:
|
|
name: build firmware
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- name: Install cmake + ninja
|
|
run: sudo apt-get update && sudo apt-get install -y cmake ninja-build
|
|
|
|
- name: Setup uv (for python-shim)
|
|
uses: astral-sh/setup-uv@v7
|
|
|
|
- name: Setup Xtensa toolchain (espup)
|
|
uses: esp-rs/xtensa-toolchain@v1.7
|
|
with:
|
|
default: true
|
|
buildtargets: esp32
|
|
ldproxy: true
|
|
|
|
# Intentionally not caching .embuild here. Sharing the cache
|
|
# with publish.yml led to "too many levels of symbolic links"
|
|
# in the IDF venv (absolute symlinks baked in by one runner
|
|
# don't resolve cleanly on another). CI gets a slower cold
|
|
# build each time; the trade-off is reproducibility.
|
|
|
|
- name: Cache cargo build
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
shared-key: ci-firmware
|
|
|
|
- name: Build firmware
|
|
# No wifi.env needed — the firmware reads Wi-Fi creds from NVS
|
|
# at runtime, not from env!() at compile time. The published
|
|
# OCI image is device-agnostic.
|
|
run: make build
|
|
|
|
publisher:
|
|
name: build publisher
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: tools/publisher
|
|
shared-key: ci-publisher
|
|
|
|
- name: Build publisher
|
|
# Explicit --target overrides the parent .cargo/config.toml's
|
|
# `target = "xtensa-esp32-espidf"`. Hardcoded triple is fine
|
|
# because we control the runner (ubuntu-latest = x86_64-linux).
|
|
run: cd tools/publisher && cargo build --release --target x86_64-unknown-linux-gnu
|
|
|
|
provision:
|
|
name: build provision
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
steps:
|
|
- uses: actions/checkout@v6
|
|
|
|
- uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: tools/provision
|
|
shared-key: ci-provision
|
|
|
|
- name: Build provision
|
|
run: cd tools/provision && cargo build --release --target x86_64-unknown-linux-gnu
|