From 8cb6267ab3d162cf0067e7341c347919ffb56238 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Sat, 18 Apr 2026 12:35:46 -0400 Subject: [PATCH 1/2] chore(scripts): move first-party shell scripts under scripts/ Relocate format.sh, test.sh, and release.sh to scripts/ so all first-party shell tooling lives in one place. Each script now derives REPO_ROOT from SCRIPT_DIR so internal paths still resolve from the repo root. Callers in .justfile, CI, and CONTRIBUTING.md are updated to the new path. --- .github/workflows/github-actions-test.yml | 4 ++-- .justfile | 4 ++-- CONTRIBUTING.md | 2 +- format.sh => scripts/format.sh | 19 ++++++++++--------- release.sh => scripts/release.sh | 11 +++++++---- test.sh => scripts/test.sh | 5 +++-- 6 files changed, 25 insertions(+), 20 deletions(-) rename format.sh => scripts/format.sh (76%) rename release.sh => scripts/release.sh (89%) rename test.sh => scripts/test.sh (59%) diff --git a/.github/workflows/github-actions-test.yml b/.github/workflows/github-actions-test.yml index 9fce8fb..931f439 100644 --- a/.github/workflows/github-actions-test.yml +++ b/.github/workflows/github-actions-test.yml @@ -11,7 +11,7 @@ jobs: - name: Install clang-format run: sudo apt-get update && sudo apt-get install -y clang-format - name: Check formatting - run: ./format.sh --check + run: ./scripts/format.sh --check test: runs-on: ubuntu-latest @@ -21,7 +21,7 @@ jobs: with: submodules: 'recursive' - name: Run tests - run: ./test.sh + run: ./scripts/test.sh build: needs: [format-check, test] diff --git a/.justfile b/.justfile index efbf620..2da8707 100644 --- a/.justfile +++ b/.justfile @@ -23,10 +23,10 @@ monitor board="wave_4b": idf.py -B build_{{board}} -D SDKCONFIG=build_{{board}}/sdkconfig monitor format: - ./format.sh + ./scripts/format.sh test: - ./test.sh + ./scripts/test.sh clean: rm -fRd build build_wave_4b build_wave_35 build_wave_5 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2d0aa02..0d9b59d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,7 +28,7 @@ Do not introduce UI dependencies into core modules. If a core function needs use - Keep changes focused, one logical change per commit. - Format your code before submitting: ```bash - ./format.sh + ./scripts/format.sh ``` This runs `clang-format` (provided by ESP-IDF) on all `.c` and `.h` files in `main/` and first-party components. diff --git a/format.sh b/scripts/format.sh similarity index 76% rename from format.sh rename to scripts/format.sh index dc92e5c..580ffda 100755 --- a/format.sh +++ b/scripts/format.sh @@ -5,7 +5,7 @@ set -e -# Usage: ./format.sh [--check] +# Usage: ./scripts/format.sh [--check] # --check Dry-run mode: exit 1 if any file needs formatting (for CI) CHECK_MODE=false @@ -14,16 +14,17 @@ if [ "${1:-}" = "--check" ]; then fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" DIRS=( - "$SCRIPT_DIR/main" - "$SCRIPT_DIR/components/bbqr" - "$SCRIPT_DIR/components/cUR" - "$SCRIPT_DIR/components/k_quirc" - "$SCRIPT_DIR/components/sd_card" - "$SCRIPT_DIR/components/video" - "$SCRIPT_DIR/components/wave_4b" - "$SCRIPT_DIR/components/wave_35" + "$REPO_ROOT/main" + "$REPO_ROOT/components/bbqr" + "$REPO_ROOT/components/cUR" + "$REPO_ROOT/components/k_quirc" + "$REPO_ROOT/components/sd_card" + "$REPO_ROOT/components/video" + "$REPO_ROOT/components/wave_4b" + "$REPO_ROOT/components/wave_35" ) if $CHECK_MODE; then diff --git a/release.sh b/scripts/release.sh similarity index 89% rename from release.sh rename to scripts/release.sh index cc8e3d6..20f2350 100755 --- a/release.sh +++ b/scripts/release.sh @@ -2,15 +2,16 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" DEVICES="wave_4b wave_35 wave_5" -VERSION=$(cat "$SCRIPT_DIR/version.txt" | tr -d '[:space:]') +VERSION=$(cat "$REPO_ROOT/version.txt" | tr -d '[:space:]') if [ -z "$VERSION" ]; then echo "Error: version.txt is empty" exit 1 fi -RELEASE_DIR="$SCRIPT_DIR/release/v${VERSION}" +RELEASE_DIR="$REPO_ROOT/release/v${VERSION}" echo "Building Kern v${VERSION} release for: ${DEVICES}" echo "Output: ${RELEASE_DIR}" @@ -21,18 +22,20 @@ source ~/esp/esp-idf/export.sh mkdir -p "$RELEASE_DIR" +cd "$REPO_ROOT" + for DEVICE in $DEVICES; do echo "========================================" echo "Building for ${DEVICE}..." echo "========================================" # Remove sdkconfig so it regenerates for this device - rm -f "$SCRIPT_DIR/sdkconfig" + rm -f "$REPO_ROOT/sdkconfig" # Build idf.py -D "SDKCONFIG_DEFAULTS=sdkconfig.defaults;sdkconfig.defaults.${DEVICE}" build - BUILD_DIR="$SCRIPT_DIR/build" + BUILD_DIR="$REPO_ROOT/build" DEVICE_DIR="$RELEASE_DIR/${DEVICE}" mkdir -p "$DEVICE_DIR" diff --git a/test.sh b/scripts/test.sh similarity index 59% rename from test.sh rename to scripts/test.sh index 5bf9cf6..323b164 100755 --- a/test.sh +++ b/scripts/test.sh @@ -5,11 +5,12 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" echo "Running bbqr tests..." -make -C "$SCRIPT_DIR/components/bbqr/test" run +make -C "$REPO_ROOT/components/bbqr/test" run echo "Running core tests..." -make -C "$SCRIPT_DIR/main/core/test" run +make -C "$REPO_ROOT/main/core/test" run echo "All tests passed!" From c4a514019139e7f600f02746900fcc7e9cfdd296 Mon Sep 17 00:00:00 2001 From: pythcoiner Date: Sat, 18 Apr 2026 12:36:53 -0400 Subject: [PATCH 2/2] ci: add per-commit check workflow Add scripts/ci-checks.sh bundling format check, tests, and wave_4b build, and a new test-each-commit workflow that iterates every commit of a PR (except the tip, which is already covered by github-actions-test.yml) via git rebase --exec. This catches regressions in intermediate commits that would otherwise slip through when a later commit fixes them. Modelled on Bitcoin Core's test-each-commit job. --- .github/workflows/test-each-commit.yml | 77 ++++++++++++++++++++++++++ scripts/ci-checks.sh | 30 ++++++++++ scripts/format.sh | 2 +- scripts/test.sh | 2 +- 4 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test-each-commit.yml create mode 100755 scripts/ci-checks.sh diff --git a/.github/workflows/test-each-commit.yml b/.github/workflows/test-each-commit.yml new file mode 100644 index 0000000..afe4335 --- /dev/null +++ b/.github/workflows/test-each-commit.yml @@ -0,0 +1,77 @@ +name: Test each commit +on: + pull_request: + +jobs: + test-each-commit: + # Single-commit PRs are already fully covered by github-actions-test.yml, + # so there's nothing new to verify. + if: github.event.pull_request.commits > 1 + runs-on: ubuntu-latest + timeout-minutes: 360 + env: + IDF_COMMIT: 44c77cbf46844cd056c923277ece745173cb270d + steps: + - name: Checkout repo + uses: actions/checkout@v4 + with: + submodules: 'recursive' + # +1 so rebase can reach the parent of the PR base. + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Fetch base branch + run: | + git fetch --no-tags --prune --depth=1 origin \ + "+refs/heads/${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}" + + - name: Install clang-format + run: sudo apt-get update && sudo apt-get install -y clang-format + + - name: Cache ESP-IDF + uses: actions/cache@v4 + with: + path: | + ~/esp-idf + ~/.espressif + key: esp-idf-${{ env.IDF_COMMIT }}-esp32p4 + + - name: Setup ESP-IDF + run: | + if [ -f ~/esp-idf/.idf_commit_ok ] && [ "$(cat ~/esp-idf/.idf_commit_ok)" = "$IDF_COMMIT" ]; then + echo "ESP-IDF already at $IDF_COMMIT (cached)" + exit 0 + fi + if [ ! -d ~/esp-idf ]; then + git clone https://github.com/espressif/esp-idf.git ~/esp-idf + fi + cd ~/esp-idf + git fetch origin $IDF_COMMIT + git checkout $IDF_COMMIT + git submodule update --init --recursive + ./install.sh esp32p4 + echo "$IDF_COMMIT" > .idf_commit_ok + + - name: Configure git identity (required by rebase) + run: | + git config user.email "ci@example.com" + git config user.name "CI" + + - name: Run checks on each commit (excluding PR tip) + run: | + . ~/esp-idf/export.sh + # Stage the CI tooling outside the work tree so it survives the + # per-commit checkouts rebase performs -- intermediate commits + # predate the introduction of scripts/ci-checks.sh, so an in-tree + # --exec path would hit "No such file or directory". + mkdir -p "$RUNNER_TEMP/ci-scripts" + cp -p scripts/ci-checks.sh scripts/format.sh scripts/test.sh \ + "$RUNNER_TEMP/ci-scripts/" + # HEAD is the PR tip -- already covered by github-actions-test.yml. + # Walking the range origin/${GITHUB_BASE_REF}..HEAD~ runs checks on + # every intermediate commit. `git rebase --exec CMD BASE` replays + # each commit in (BASE..HEAD] chronologically and runs CMD after + # each, inheriting the parent shell's env (so idf.py stays on PATH). + git checkout HEAD~ + git rebase --exec "$RUNNER_TEMP/ci-scripts/ci-checks.sh" \ + "origin/${GITHUB_BASE_REF}" diff --git a/scripts/ci-checks.sh b/scripts/ci-checks.sh new file mode 100755 index 0000000..d8b61ea --- /dev/null +++ b/scripts/ci-checks.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Run all CI checks for a single commit: format, tests, and a wave_4b build. +# Invoked from the per-commit CI loop (see .github/workflows/test-each-commit.yml) +# and runnable locally to reproduce what CI does. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || (cd "$SCRIPT_DIR/.." && pwd))" +cd "$REPO_ROOT" + +echo "=== Commit under test ===" +git log -1 --oneline + +echo "=== format check ===" +"$SCRIPT_DIR/format.sh" --check + +echo "=== tests ===" +"$SCRIPT_DIR/test.sh" + +echo "=== build wave_4b ===" +# Local dev: load ESP-IDF if idf.py isn't already on PATH. In CI the job +# sources export.sh once before the per-commit loop, so this is a no-op. +command -v idf.py >/dev/null || . "${IDF_PATH:-$HOME/esp/esp-idf}/export.sh" +idf.py \ + -B build_wave_4b \ + -D SDKCONFIG=build_wave_4b/sdkconfig \ + -D 'SDKCONFIG_DEFAULTS=sdkconfig.defaults;sdkconfig.defaults.wave_4b' \ + build diff --git a/scripts/format.sh b/scripts/format.sh index 580ffda..4262ab6 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -14,7 +14,7 @@ if [ "${1:-}" = "--check" ]; then fi SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || (cd "$SCRIPT_DIR/.." && pwd))" DIRS=( "$REPO_ROOT/main" diff --git a/scripts/test.sh b/scripts/test.sh index 323b164..8ed675e 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -5,7 +5,7 @@ set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || (cd "$SCRIPT_DIR/.." && pwd))" echo "Running bbqr tests..." make -C "$REPO_ROOT/components/bbqr/test" run