Skip to content

Commit 05c2837

Browse files
authored
Merge pull request #120 from escendit/feat/epm-t140-gh119-build-a-node-and-a-hub-from-the-docs
feat(docs): build a Node and a Hub from the docs
2 parents 84b05b1 + 87da6b4 commit 05c2837

19 files changed

Lines changed: 2013 additions & 5 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"actions": [
3+
"After this PR merges, cut the first release from main: keep the charts at 0.1.0 (or run deploy/charts/set-version.sh <X.Y.Z> in a chore(release) PR and merge it), then push the tag: git tag -a v0.1.0 -m 'Coldframe 0.1.0' && git push origin v0.1.0.",
4+
"Watch the Release workflow run for that tag and confirm it is green and that the GitHub Release v0.1.0 has coldframe-hub/node-0.1.0.bin and .elf, every <chart>-0.1.0.tgz, SHA256SUMS and the grouped notes with the docs/build/apps.md link.",
5+
"Confirm ghcr.io/escendit/coldframe/{server,web,migrations,keycloak}:0.1.0 exist, then download the Release assets and run sha256sum --check --strict SHA256SUMS."
6+
],
7+
"parked_at": "2026-10-19",
8+
"run_id": "20261012-230921-d74a",
9+
"spec_file": "_bmad-output/implementation-artifacts/spec-10-1-releases-with-one-version-and-firmware-binaries.md",
10+
"story_key": "10-1-releases-with-one-version-and-firmware-binaries"
11+
}

‎.github/workflows/docs.yml‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
# Checks the adopter docs (Story 10.2): every relative link and referenced repository path
2+
# resolves, and every command block of the build guide (docs/build/*.md) either runs against the
3+
# firmware crates (`<!-- ci:run <dir> -->`, builds only) or, when it needs a board
4+
# (`<!-- ci:hardware -->`), names only real espflash subcommands. Nothing is ever flashed, and no
5+
# external link is fetched. Not a required status check.
6+
#
7+
# Actions are pinned to a commit; the comment names the release. The firmware setup of the
8+
# `commands` job is copied from the `firmware` job of ci.yml: keep the two in step.
9+
name: Docs
10+
11+
on:
12+
pull_request:
13+
paths:
14+
# Everything the docs link to or mirror (the toolchain pins of ci.yml and release.yml).
15+
- "docs/**"
16+
- "hardware/**"
17+
- "README.md"
18+
- "LICENSE"
19+
- ".gitignore"
20+
- "apps/**"
21+
- "packages/**"
22+
- "deploy/**"
23+
- "tests/**"
24+
- "aspire/**"
25+
- ".github/workflows/**"
26+
push:
27+
branches:
28+
- main
29+
paths:
30+
- "docs/**"
31+
- "hardware/**"
32+
- "README.md"
33+
- "LICENSE"
34+
- ".gitignore"
35+
- "apps/**"
36+
- "packages/**"
37+
- "deploy/**"
38+
- "tests/**"
39+
- "aspire/**"
40+
- ".github/workflows/**"
41+
workflow_dispatch:
42+
43+
permissions:
44+
contents: read
45+
46+
concurrency:
47+
group: ${{ github.workflow }}-${{ github.ref }}
48+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
49+
50+
jobs:
51+
links:
52+
name: Links
53+
runs-on: ubuntu-24.04
54+
timeout-minutes: 10
55+
steps:
56+
- name: Check out
57+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
58+
with:
59+
persist-credentials: false
60+
61+
- name: Test the doc checks
62+
run: docs/test.sh
63+
64+
- name: Check links and paths
65+
run: docs/check-links.sh
66+
67+
commands:
68+
name: Commands
69+
runs-on: ubuntu-24.04
70+
timeout-minutes: 60
71+
env:
72+
# The same pins as the `firmware` job of ci.yml.
73+
ESPUP_VERSION: "0.17.1"
74+
ESP_TOOLCHAIN_VERSION: "1.95.0.0"
75+
ESPFLASH_VERSION: "4.5.0"
76+
steps:
77+
- name: Check out
78+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
79+
with:
80+
persist-credentials: false
81+
82+
# cmake and ninja for the mbedTLS rebuild; libudev for espflash.
83+
- name: Install build tools
84+
run: sudo apt-get update && sudo apt-get install --yes --no-install-recommends cmake ninja-build libudev-dev pkg-config
85+
86+
- name: Cache
87+
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
88+
with:
89+
workspaces: |
90+
apps/rs/hub
91+
apps/rs/node
92+
key: espup-${{ env.ESPUP_VERSION }}-esp-${{ env.ESP_TOOLCHAIN_VERSION }}-espflash-${{ env.ESPFLASH_VERSION }}
93+
cache-bin: "true"
94+
cache-directories: |
95+
~/.rustup/toolchains/esp
96+
~/export-esp.sh
97+
98+
# On the runner's stable toolchain: apps/rs/hub/rust-toolchain.toml names `esp`, which is not
99+
# installed until the next step.
100+
- name: Install espup and espflash
101+
working-directory: apps/rs/hub
102+
run: |
103+
if [[ "$(espup --version 2>/dev/null)" != "espup ${ESPUP_VERSION}" ]]; then
104+
rustup run stable cargo install espup --version "${ESPUP_VERSION}" --locked --force
105+
fi
106+
if [[ "$(espflash --version 2>/dev/null)" != "espflash ${ESPFLASH_VERSION}" ]]; then
107+
rustup run stable cargo install espflash --version "${ESPFLASH_VERSION}" --locked --force
108+
fi
109+
110+
- name: Install the esp toolchain
111+
working-directory: apps/rs/hub
112+
env:
113+
GITHUB_TOKEN: ${{ github.token }}
114+
run: |
115+
if [[ ! -f "${HOME}/export-esp.sh" ]] || ! rustup run esp rustc --version | grep -qF "(${ESP_TOOLCHAIN_VERSION})"; then
116+
espup install --toolchain-version "${ESP_TOOLCHAIN_VERSION}" --targets esp32s3 --export-file "${HOME}/export-esp.sh"
117+
fi
118+
rustup run esp rustc --version
119+
120+
# The guide's own install block runs too; with the tools above already in place it reuses them.
121+
- name: Run the documented commands
122+
env:
123+
GITHUB_TOKEN: ${{ github.token }}
124+
run: |
125+
docs/check-commands.sh --list
126+
docs/check-commands.sh

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ and deployment all live in this repository.
1010
## Start here
1111

1212
- [Developer quickstart](docs/quickstart.md): run the local stack and every test suite.
13+
- [Build guide](docs/build/README.md): build, flash and add your own Node and Hub.
14+
- [Hardware design](hardware/README.md): schematics, BOM, wiring, enclosure and probe sealing.
1315
- [Hub radio coexistence spike](docs/spikes/hub-radio-coexistence.md): what the Hub's radio can do at once.
1416

1517
## Repository layout
@@ -21,7 +23,7 @@ and deployment all live in this repository.
2123
| [`tests/`](tests) | All tests, split by language |
2224
| [`aspire/`](aspire) | The local development stack, which is also the integration-test host |
2325
| [`deploy/`](deploy) | Helm charts, Fleet bundles and a Compose example |
24-
| [`hardware/`](hardware) | Schematics, PCB and enclosure |
26+
| [`hardware/`](hardware) | The reference Node and Hub design: schematics, BOM, wiring, enclosure |
2527
| [`docs/`](docs) | Guides and references |
2628

2729
## License

‎_bmad-output/implementation-artifacts/deferred-work.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,3 +930,19 @@ location: tests/cs/server.integration/Edge/InvitationTests.cs
930930
source_spec: `spec-9-1-invite-someone-to-my-site.md`
931931
reason: InvitationTests asserts the link equals the configured redirect URI and accepts by signing in on Keycloak directly; the web app is not part of the AppHost, so link -> web sign-in -> invitation required action is unverified end to end. Settle by running the web app against the AppHost and following the Mailpit link.
932932
status: open
933+
934+
### DW-120: A v* tag on any commit publishes; the documented "tag only from main" rule is not enforced by the workflow.
935+
origin: spec-deferred 7aa938ff9d90
936+
location: .github/workflows/release.yml (mode job)
937+
source_spec: `spec-10-1-releases-with-one-version-and-firmware-binaries.md`
938+
severity: low
939+
reason: Pre-existing since Story 2.1 (deploy/images/README.md already asks for a tag ruleset); the mode job accepts any v* push.
940+
status: open
941+
942+
### DW-121: The tag-only branches of release.yml (ghcr login, --push, imagetools summary, verify, gh release create, --prerelease) never run in the dry run.
943+
origin: spec-deferred bce640467f2d
944+
location: .github/workflows/release.yml (publish, release jobs)
945+
source_spec: `spec-10-1-releases-with-one-version-and-firmware-binaries.md`
946+
severity: medium
947+
reason: dry_run is true for every non-push event, so these steps are skipped on PRs; only a real v* tag exercises them. Owed as an operator action (cut the first release and check it).
948+
status: open

0 commit comments

Comments
 (0)