Public Access
CI: a push runs the tests, a pull request also builds the firmware
CI / build (push) Successful in 1m6s
CI / build (push) Successful in 1m6s
Rebuilding both firmwares on every push was more than anyone looked at. A push now runs the host tests with their coverage (under two minutes); a pull request adds the release firmware and the Debug Build, and is how changes reach main; a tag still does everything before it releases. Pull requests from forks don't run. scripts/ci.sh takes 'tests' or 'builds' for one half; coverage.sh now fails when a test fails. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
+15
-11
@@ -1,7 +1,8 @@
|
|||||||
# CI and releases (docs/milestones/R1.md).
|
# CI and releases (docs/milestones/R1.md).
|
||||||
# Any push: host tests, the release firmware and the Debug Build, then the tests'
|
# A push: the host tests, with their coverage of lib/. On main, the README's badges
|
||||||
# coverage of lib/; on main, its badge is published to the branch `badges`.
|
# are published to the branch `badges`.
|
||||||
# A tag v*: the same, then a Gitea release with the signed Update File.
|
# A pull request: the same, then the release firmware and the Debug Build.
|
||||||
|
# A tag v*: all of it, then a Gitea release with the signed Update File.
|
||||||
# Run by hand: the release of a tag that exists already (the ones from before CI).
|
# Run by hand: the release of a tag that exists already (the ones from before CI).
|
||||||
#
|
#
|
||||||
# The job runs in a plain Python image, as scripts/ci.sh does on a developer's machine, with the
|
# The job runs in a plain Python image, as scripts/ci.sh does on a developer's machine, with the
|
||||||
@@ -10,8 +11,9 @@
|
|||||||
name: CI
|
name: CI
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ['**', '!badges'] # badges holds what CI itself publishes: the coverage badge
|
branches: ['**', '!badges'] # badges holds what CI itself publishes
|
||||||
tags: ['v*']
|
tags: ['v*']
|
||||||
|
pull_request:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
tag:
|
tag:
|
||||||
@@ -21,6 +23,8 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu
|
runs-on: ubuntu
|
||||||
|
# A pull request from a fork would run someone else's code on our runner: not without us (Q154).
|
||||||
|
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||||
container:
|
container:
|
||||||
image: python:3.12-slim
|
image: python:3.12-slim
|
||||||
volumes:
|
volumes:
|
||||||
@@ -42,18 +46,18 @@ jobs:
|
|||||||
git config --global --add safe.directory '*'
|
git config --global --add safe.directory '*'
|
||||||
git init -q .
|
git init -q .
|
||||||
git remote add origin "${{ github.server_url }}/${{ github.repository }}.git"
|
git remote add origin "${{ github.server_url }}/${{ github.repository }}.git"
|
||||||
git fetch -q --tags origin '+refs/heads/*:refs/remotes/origin/*'
|
git fetch -q --tags origin '+refs/heads/*:refs/remotes/origin/*' '+refs/pull/*/head:refs/remotes/pull/*'
|
||||||
git checkout -q --detach "${{ github.sha }}"
|
git checkout -q --detach "${{ github.sha }}"
|
||||||
git describe --tags --always
|
git describe --tags --always
|
||||||
|
|
||||||
- name: Host tests and both builds
|
- name: Host tests, and their coverage of lib/
|
||||||
if: github.event_name == 'push'
|
if: github.event_name != 'workflow_dispatch'
|
||||||
run: scripts/ci.sh
|
|
||||||
|
|
||||||
- name: Coverage of lib/ by the host tests
|
|
||||||
if: github.event_name == 'push'
|
|
||||||
run: scripts/coverage.sh
|
run: scripts/coverage.sh
|
||||||
|
|
||||||
|
- name: The release firmware and the Debug Build
|
||||||
|
if: github.event_name == 'pull_request' || github.ref_type == 'tag'
|
||||||
|
run: scripts/ci.sh builds
|
||||||
|
|
||||||
# The README's badges are files on a branch of their own, replaced at each push to main.
|
# The README's badges are files on a branch of their own, replaced at each push to main.
|
||||||
- name: Publish the badges
|
- name: Publish the badges
|
||||||
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/coverage')
|
if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/coverage')
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ The framework is rebuilt with the TLS settings in `platformio.ini` (`custom_sdkc
|
|||||||
|
|
||||||
## CI and releases
|
## CI and releases
|
||||||
|
|
||||||
Gitea Actions runs the same thing on every push (`.gitea/workflows/ci.yml`, docs/milestones/R1.md). Pushing a tag `v*` also publishes a release on Gitea with:
|
Gitea Actions (`.gitea/workflows/ci.yml`, docs/milestones/R1.md) runs the host tests on every push, and on a pull request also builds the release firmware and the Debug Build: changes reach `main` through pull requests. Pushing a tag `v*` runs all of it and publishes a release on Gitea with:
|
||||||
|
|
||||||
- `roro9stack-<version>.ota`, the signed Update File;
|
- `roro9stack-<version>.ota`, the signed Update File;
|
||||||
- `roro9stack-<version>-factory.bin`, the whole flash image for a first install over USB;
|
- `roro9stack-<version>-factory.bin`, the whole flash image for a first install over USB;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Until now the tests, the builds, the signing and the flashing all happened on on
|
|||||||
|
|
||||||
| # | Decision |
|
| # | Decision |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Q151 | Every push, to any branch: the host tests and both builds. A tag `v*`: the same, then a release. |
|
| Q151 | A push, to any branch: the host tests (with their coverage). A pull request: the same and both builds; changes reach `main` through pull requests. A tag `v*`: all of it, then a release. (First: everything on every push, which rebuilt the firmware far more often than anyone looked at it.) |
|
||||||
| Q152 | **CI signs.** The signing key is the repository secret `OTA_SIGNING_KEY`; a tag push makes a complete, signed release with no manual step (ADR 0008). |
|
| Q152 | **CI signs.** The signing key is the repository secret `OTA_SIGNING_KEY`; a tag push makes a complete, signed release with no manual step (ADR 0008). |
|
||||||
| Q153 | The Debug Build is built in CI with a token of the runner's own, to prove it compiles, and **isn't published**: it would hand everyone its Debug Console token. |
|
| Q153 | The Debug Build is built in CI with a token of the runner's own, to prove it compiles, and **isn't published**: it would hand everyone its Debug Console token. |
|
||||||
| Q154 | Pull requests from forks don't start a run. |
|
| Q154 | Pull requests from forks don't start a run. |
|
||||||
|
|||||||
+8
-1
@@ -1,7 +1,14 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Local CI: run host unit tests, then build the firmware.
|
# Local CI: run host unit tests, then build the firmware.
|
||||||
|
# Usage: scripts/ci.sh [tests|builds] one half only; both by default
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
source "$(dirname "$0")/_docker.sh"
|
source "$(dirname "$0")/_docker.sh"
|
||||||
DOCKER_EXTRA=()
|
DOCKER_EXTRA=()
|
||||||
|
|
||||||
run_in_container bash -c 'git config --global --add safe.directory "$PWD" && pio test -e native && pio run -e cardputer-adv -e cardputer-adv-debug'
|
case "${1:-all}" in
|
||||||
|
tests) STEPS='pio test -e native' ;;
|
||||||
|
builds) STEPS='pio run -e cardputer-adv -e cardputer-adv-debug' ;;
|
||||||
|
all) STEPS='pio test -e native && pio run -e cardputer-adv -e cardputer-adv-debug' ;;
|
||||||
|
*) echo "Usage: scripts/ci.sh [tests|builds]" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
run_in_container bash -c 'git config --global --add safe.directory "$PWD" && '"$STEPS"
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# How much of lib/ the host tests run: builds them with coverage counters, runs them, and reports.
|
# Runs the host tests and says how much of lib/ they run: they're built with coverage counters.
|
||||||
# Usage: scripts/coverage.sh [out folder, default .pio/coverage]
|
# Usage: scripts/coverage.sh [out folder, default .pio/coverage]
|
||||||
# Out: summary.json (gcovr), coverage.svg (the README's badge), index.html (line by line).
|
# Out: summary.json (gcovr), coverage.svg (the README's badge), index.html (line by line).
|
||||||
# What it measures: the lines of lib/ that compile on a PC. Not lib/SD (the card's driver) and not
|
# What it measures: the lines of lib/ that compile on a PC. Not lib/SD (the card's driver) and not
|
||||||
@@ -10,7 +10,7 @@ DOCKER_EXTRA=()
|
|||||||
OUT="${1:-.pio/coverage}"
|
OUT="${1:-.pio/coverage}"
|
||||||
|
|
||||||
run_in_container bash -c '
|
run_in_container bash -c '
|
||||||
set -e
|
set -eo pipefail # a failing test fails this script, tail or not
|
||||||
git config --global --add safe.directory "$PWD"
|
git config --global --add safe.directory "$PWD"
|
||||||
rm -rf .pio/build/native-coverage "'"$OUT"'"
|
rm -rf .pio/build/native-coverage "'"$OUT"'"
|
||||||
mkdir -p "'"$OUT"'"
|
mkdir -p "'"$OUT"'"
|
||||||
|
|||||||
Reference in New Issue
Block a user