Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 41 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# The one pull-request workflow. On a pull request it compiles once: `cargo fmt --check` and
# `cargo clippy --workspace --locked -D warnings` without test targets, on Linux. A by-hand run
# (workflow_dispatch) also lints the test targets and runs every test. A docs-only pull request
# skips the Rust job; a skipped job still satisfies its check.
#
# Runs on pull requests only: a push to develop is the merge of a pull request that already passed,
# and the release workflow builds every target again from the tag.
name: CI

on:
push:
branches: [develop, main]
pull_request:
workflow_dispatch:

Expand All @@ -12,38 +17,58 @@ env:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
cancel-in-progress: true

permissions:
contents: read

jobs:
changes:
name: changes
runs-on: ubuntu-latest
timeout-minutes: 5
outputs:
heavy: ${{ steps.classify.outputs.heavy }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- id: classify
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
run: |
heavy=true
if [ -n "$BASE_SHA" ] && ! git diff --name-only "$BASE_SHA" HEAD | grep -qvE '(\.md$|^docs/|^LICENSE)'; then
heavy=false
fi
echo "heavy=$heavy" | tee -a "$GITHUB_OUTPUT"

test:
name: test (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
name: fmt, clippy, test
needs: changes
# A failed classifier never skips the gate.
if: ${{ !cancelled() && (needs.changes.result != 'success' || needs.changes.outputs.heavy == 'true') }}
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- name: Desktop build deps and a software Vulkan driver for the headless UI snapshot
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends libxkbcommon-dev libwayland-dev libxcb1-dev libx11-dev libgl-dev mesa-vulkan-drivers
- name: Format
if: runner.os == 'Linux'
run: cargo fmt --all -- --check
- name: Clippy
- name: Clippy (compile once)
if: github.event_name == 'pull_request'
run: cargo clippy --workspace --locked -- -D warnings
# Test targets and the tests: by-hand runs only.
- name: Clippy, all targets
if: github.event_name != 'pull_request'
run: cargo clippy --workspace --all-targets --locked -- -D warnings
- name: Test
if: github.event_name != 'pull_request'
run: cargo test --workspace --locked
- name: Browser build compiles
if: runner.os == 'Linux'
run: cargo check -p redrob-board-web --target wasm32-unknown-unknown --locked
2 changes: 0 additions & 2 deletions .github/workflows/gitflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ on:
# what happened in a sibling repository when the default moved to `develop` and three workflows
# kept filtering on `[main, master]`.
types: [opened, reopened, edited, synchronize]
push:
branches: [main]
workflow_dispatch:

permissions:
Expand Down
6 changes: 2 additions & 4 deletions .github/workflows/oracle.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
name: oracle

# Stage gates that compare our tools with an external oracle. The oracle is installed on the runner
# only; nothing from it ships. A stage is done when this job is green.
# only; nothing from it ships. A stage is done when this job is green. It installs KiCad and
# ngspice, so it runs by hand (workflow_dispatch) when a stage is checked, not on every pull request.

on:
push:
branches: [develop, main]
pull_request:
workflow_dispatch:

permissions:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/packaging-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
name: Packaging lint

on:
push:
branches: [develop, main]
paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**"]
pull_request:
paths: [".github/workflows/**", "packaging/**", "assets/app-icon/**"]
workflow_dispatch:
Expand Down
38 changes: 1 addition & 37 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,45 +254,9 @@ jobs:
path: dist/release/*
if-no-files-found: error

web:
name: Web (wasm)
needs: version
runs-on: ubuntu-latest
# No `environment: release`: this job signs nothing, so it gets no release secrets.
env:
REDROB_BOARD_VERSION: ${{ needs.version.outputs.version }}
REDROB_BOARD_BUILD_DATE: ${{ needs.version.outputs.date }}
REDROB_BOARD_BUILD_SHA: ${{ needs.version.outputs.sha }}
TRUNK_VERSION: 0.21.14
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.version.outputs.sha }}
- uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
with:
key: release-web
- name: Install trunk
run: |
curl -fsSL "https://github.com/trunk-rs/trunk/releases/download/v${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz" \
| tar -xz -C "$HOME/.cargo/bin" trunk
trunk --version
- name: Apply version override
if: inputs.version != ''
run: cargo xtask version set "$REDROB_BOARD_VERSION"
- name: Build and zip
run: packaging/web/package.sh
- uses: actions/upload-artifact@v4
with:
name: release-web
path: dist/release/*
if-no-files-found: error

release:
name: Publish GitHub Release
needs: [version, macos, windows, linux, web]
needs: [version, macos, windows, linux]
# Only a version tag publishes; a manual dispatch stops before this job.
if: github.ref_type == 'tag'
runs-on: ubuntu-latest
Expand Down
22 changes: 9 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 1 addition & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "3"
members = ["crates/*", "apps/*", "xtask"]
members = ["crates/*", "xtask"]

[workspace.package]
version = "0.2.0"
Expand Down Expand Up @@ -54,8 +54,3 @@ opt-level = 1
lto = "thin"
codegen-units = 1

[profile.wasm-release]
inherits = "release"
opt-level = "s"
lto = "fat"
strip = "debuginfo"
9 changes: 4 additions & 5 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ JavaScript 없음, 웹뷰 없음, 외부 EDA 바이너리 없음. 상류 도구(

```sh
cargo test --workspace
cargo run -p board-agent --bin board-cli -- pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab
cargo run -p redrob-board -- pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab
cargo run -p redrob-board # 데스크톱 앱
```

Expand All @@ -43,7 +43,7 @@ cargo run -p redrob-board # 데스크톱 앱
일치. 배치 엔진은 14부품 센서 노드를 겹침 없이, 손 배치보다 배선 길이 54% 짧게 놓습니다(게이트 20%). 라우터는 분배기와 센서 노드
두 배치를 2층으로 끝까지 배선해 DRC 위반 0이고, KiCad도 배선된 센서 노드를 깨끗하다고 판정합니다. 우리 거버(동박·마스크·페이스트·외곽)와 드릴 파일은
같은 보드를 KiCad가 그린 것과 우리 리더로 10um 래스터화해 비교합니다: 동박·마스크·페이스트(모듈 접지판의 페이스트 창 격자 포함)·외곽·드릴 48개 파일 전부 픽셀 일치, 실크(자체 선 폰트 참조기호)는 느슨한 일치(위치·좌우·잉크량 2배 이내). BOM·픽앤플레이스
CSV는 `board-bom`이 냅니다. `board-cli pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab`이
CSV는 `board-bom`이 냅니다. `redrob-board pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab`이
전체 흐름을 돌려 배선 완주·DRC 0일 때만 종료 코드 0을 냅니다. `redrob-board`(egui) 앱은 같은 일을 버튼으로 하고,
헤드리스 `egui_kittest` 테스트가 그 버튼들을 눌러 렌더 결과를 `crates/app/tests/snapshots/sensor_node_routed.png`와 비교합니다.
앱의 AGENT 팔레트는 공유 Redrob Code 엔진(`redrob-engine-client`)과 대화하며, 호출자 소유 도구 10개(`board-agent`:
Expand All @@ -57,7 +57,7 @@ catalog·write_schematic·place·route·drc·export_zip 등)를 선언합니다:
차동쌍, 길이 매칭 그룹, 내층 GND·전원 플레인이 있는 4층 보드(다른 넷 주변 존 채움, 섬·조각 제거; 내층 거버(G36/G37 영역)가
KiCad 플롯과 픽셀 일치, KiCad DRC 0), 자체 스트로크 폰트 실크와 모듈 플레이트 페이스트 창, `board-sim`(넷리스트의 선형 DC 동작점·AC
소신호, `oracle` 워크플로 `sim` 잡에서 ngspice와 1% 이내 일치, `simulate` 도구와 레일 검사), 3D 미리보기(코트야드 위 상자 부품, 드래그
회전), 브라우저 빌드, 보드 하우스 패키지: `export_zip`이 JLCPCB·PCBWay 리더가 기대하는 이름으로 파일을 쓰고 주문 시트(층수·크기·규칙·LCSC
회전), 보드 하우스 패키지: `export_zip`이 JLCPCB·PCBWay 리더가 기대하는 이름으로 파일을 쓰고 주문 시트(층수·크기·규칙·LCSC
재고 커버·업로드 위치)를 아카이브에 넣습니다. 앱의 ORDER 팔레트는 Labs 스위치(`REDROB_BOARD_LABS=order` 또는 Labs 체크박스)이고 꺼져
있으면 그리지 않습니다. 주문 버튼은 없습니다: 두 하우스 모두 판매자 계정 없는 공개 주문 API가 없어서, 패키지와 시트가 인계점입니다.

Expand All @@ -67,8 +67,7 @@ KiCad 플롯과 픽셀 일치, KiCad DRC 0), 자체 스트로크 폰트 실크
Linux AppImage/deb/rpm/tar.gz(x86_64·aarch64)가 있습니다:
[github.com/redrob-labs/redrob-board/releases](https://github.com/redrob-labs/redrob-board/releases).
`vX.Y.Z` 태그가 `.github/workflows/release.yml`을 돌려 한 커밋에서 모든 잡을 빌드하고 릴리즈를 발행합니다.
패키징 스크립트는 `packaging/`에 있습니다. 릴리즈에는 브라우저 빌드(`redrob-board-web-<버전>.zip`, 정적 WebAssembly 사이트,
호스팅 안내는 `packaging/web/README.md`)도 들어갑니다: 엔진 없는 같은 창이라 AGENT 팔레트가 그 사실을 말합니다.
패키징 스크립트는 `packaging/`에 있습니다.

## 라이선스

Expand Down
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ called done. Nothing of theirs ships in the product. See [UPSTREAM.md](./UPSTREA

```sh
cargo test --workspace
cargo run -p board-agent --bin board-cli -- pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab
cargo run -p redrob-board -- pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab
cargo run -p redrob-board # the desktop app
```

The app binary is also the command line: `redrob-board pipeline | tool | examples | drc |
kicad-export | gerber-compare` (`redrob-board help`). Each exit code is the verdict.

## Status

Stages 0 (bootstrap), 1 (footprint library, DRC), 2 (placement), 3 (routing), 4 (manufacturing
Expand All @@ -52,7 +55,7 @@ divider and both sensor-node placements on two layers with zero DRC violations,
the routed sensor node is clean. Our Gerbers (copper, mask, paste, edge cuts) and Excellon drill
files are compared with KiCad's plots of the same boards by rasterising both at 10 um with our own
reader: 48 of 48 copper, mask, paste (with the grid of paste windows on the module ground plate), edge and drill files are pixel-identical, and the silkscreen (reference designators in our own stroke font) matches KiCad's loosely -- same place, same mirror, same ink within a factor of two. BOM and pick-and-place CSVs come from `board-bom`.
`board-cli pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab`
`redrob-board pipeline --design sensor-node --outline 30x25 --edge J1=left --edge SW1=right --out fab`
runs the whole flow and exits 0 only when routing is complete and DRC is clean; `redrob-board`
(egui) does the same from buttons, and a headless `egui_kittest` test drives those buttons and
compares the rendered frame to `crates/app/tests/snapshots/sensor_node_routed.png`. The app's
Expand All @@ -72,7 +75,7 @@ nets, islands and slivers dropped; our inner-layer Gerbers with G36/G37 regions
to KiCad's plots and KiCad's DRC stays at zero), silkscreen in our own stroke font and paste windows
on module plates, `board-sim` (linear DC operating point and AC small-signal of the netlist, checked
against ngspice within 1% in the `oracle` workflow's `sim` job, with a `simulate` tool and rail
checks), a 3D preview (parts as boxes over their courtyards, drag to turn), a browser build, and
checks), a 3D preview (parts as boxes over their courtyards, drag to turn), and
board-house packages: `export_zip` names the files the way JLCPCB or PCBWay's reader expects and
puts an order sheet (layers, size, rules, LCSC stock coverage, where to upload) in the archive. The
app's ORDER palette is a Labs switch (`REDROB_BOARD_LABS=order` or the Labs checkbox) and is not
Expand All @@ -86,9 +89,7 @@ Releases carry a signed and notarized macOS disk image (universal), signed Windo
and portable zips (x64, arm64) and Linux AppImage/deb/rpm/tar.gz (x86_64, aarch64):
[github.com/redrob-labs/redrob-board/releases](https://github.com/redrob-labs/redrob-board/releases).
A `vX.Y.Z` tag runs `.github/workflows/release.yml`, which builds every job from one commit and
publishes the release; the packaging scripts live in `packaging/`. The release also carries a
browser build (`redrob-board-web-<version>.zip`, a static WebAssembly site; `packaging/web/README.md`
has the hosting notes): the same window without the engine, so the AGENT palette says so.
publishes the release; the packaging scripts live in `packaging/`.

## License

Expand Down
27 changes: 0 additions & 27 deletions apps/redrob-board-web/Cargo.toml

This file was deleted.

10 changes: 0 additions & 10 deletions apps/redrob-board-web/Trunk.toml

This file was deleted.

21 changes: 0 additions & 21 deletions apps/redrob-board-web/index.html

This file was deleted.

Loading
Loading