1
0
Fork 0
mirror of https://github.com/imjasonh/esp32 synced 2026-07-06 23:52:24 +00:00
esp32/.github/workflows/publish.yml
Jason Hall ed1d18d8df ci: restore caches before cargo install espflash
`cargo install espflash --locked` builds from source. Moving the
.embuild + Swatinem cargo-cache restores ahead of it lets the install
use the cached registry index + downloaded crates instead of fetching
them fresh each run — shaves ~30 s off the install on warm caches.

Pure step-reordering; no behavioural change. Both caches still depend
on inputs that exist at checkout, so an earlier restore is safe.

Bigger speedup is available by replacing the cargo install with a
prebuilt-binary install (e.g. taiki-e/install-action drops espflash
from ~3-5 min to ~2 s). Deferred to its own PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 00:17:25 -04:00

96 lines
3.2 KiB
YAML

name: Publish OTA
# Build the firmware on every push to main, push it as an OCI artifact
# to ghcr.io/imjasonh/esp32, and sign it keylessly with cosign using
# the workflow's ambient OIDC token. The on-device verifier (src/sig.rs)
# trusts this workflow's identity (provisioned into the device's NVS).
#
# Published image is device-agnostic: contains no Wi-Fi creds, no
# trust roots, no GCP keys. Per-device config lives in NVS and is
# written via USB by `make provision`. See provisioning-plan.md.
#
# Only secret needed: GITHUB_TOKEN (auto-provided by the runner).
on:
push:
branches: [main]
workflow_dispatch:
# Don't run two publish jobs at once -- :latest would race. The newer
# commit wins.
concurrency:
group: publish
cancel-in-progress: true
permissions:
contents: read
packages: write
id-token: write # cosign keyless OIDC
jobs:
publish:
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
# Restore caches *before* `cargo install espflash` so it benefits
# from the cached cargo registry (saves the ~30s of crates-io
# index sync + dep download). The .embuild cache also primes
# earlier — same restore time, just less time-to-build at the end.
- name: Cache .embuild (ESP-IDF + tools)
uses: actions/cache@v5
with:
path: .embuild
key: embuild-v5.2.2-${{ runner.os }}-${{ hashFiles('Cargo.toml', 'rust-toolchain.toml', '.cargo/config.toml') }}
restore-keys: |
embuild-v5.2.2-${{ runner.os }}-
- name: Cache cargo build
uses: Swatinem/rust-cache@v2
with:
workspaces: |
.
tools/publisher
shared-key: publish
- name: Install espflash
run: cargo install espflash --locked
- name: Install cosign
# cosign-installer doesn't publish a moving v4 tag, only specific
# patch versions. Pin to the latest v4.x. (v4 installs cosign 3
# by default, which produces the Sigstore Bundle v0.3 format
# the on-device verifier in src/sig.rs parses.)
uses: sigstore/cosign-installer@v4.1.1
- name: Write gh.env from GITHUB_TOKEN
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# `make publish` sources gh.env for cosign's registry auth.
# %q escapes for safe sourcing regardless of special chars.
run: |
printf 'export GH_TOKEN=%q\n' "$GH_TOKEN" > gh.env
chmod 600 gh.env
- name: Build, push, and sign
env:
# cosign uses GH_TOKEN for registry auth (push the sig
# artifact to GHCR). The OIDC identity for keyless signing
# is the workflow's ambient token, picked up automatically
# because we set id-token: write at the job level.
COSIGN_REGISTRY_USERNAME: ${{ github.actor }}
run: make publish