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
19 changes: 14 additions & 5 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,24 @@ WORKDIR /home/$USERNAME

# --------------------------------------------------------------------
# Install Rust + AimDB-specific targets and tools
# --------------------------------------------------------------------
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
#
# RUST_VERSION must match rust-toolchain.toml's channel. It is repeated here
# because this image builds from the .devcontainer/ context and so cannot read
# the repo root; `make check-toolchain-pin` fails when the two drift apart.
# --------------------------------------------------------------------
ARG RUST_VERSION=1.98.0
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain ${RUST_VERSION} --profile minimal \
-c rustfmt -c clippy
ENV PATH="/home/$USERNAME/.cargo/bin:${PATH}"

# Add embedded targets for AimDB MCU support
# The first two mirror rust-toolchain.toml's `targets` so the image needs no
# download on first use; the thumbv6m/thumbv7m pair is a devcontainer-only
# convenience for MCU work outside what the workspace builds.
RUN rustup target add thumbv7em-none-eabihf \
&& rustup target add wasm32-unknown-unknown \
&& rustup target add thumbv6m-none-eabi \
&& rustup target add thumbv7m-none-eabi \
&& rustup target add wasm32-unknown-unknown
&& rustup target add thumbv7m-none-eabi

# Install core AimDB development tools
RUN cargo install cargo-audit cargo-watch cargo-expand
Expand Down
78 changes: 19 additions & 59 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,17 @@ jobs:
- uses: actions/checkout@v7
with:
submodules: recursive


# A text comparison, so it needs no toolchain and can fail before we spend
# one. `make check` runs it again in comprehensive-check, which gates on
# three other jobs and would report drift far later.
- name: Check the devcontainer pin matches rust-toolchain.toml
run: make check-toolchain-pin

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: thumbv7em-none-eabihf, wasm32-unknown-unknown
components: rustfmt, clippy

- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-format-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Check formatting (workspace members only)
run: make fmt-check
Expand All @@ -50,18 +46,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: thumbv7em-none-eabihf, wasm32-unknown-unknown

- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Build all valid feature combinations
run: make build
Expand Down Expand Up @@ -91,18 +78,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: thumbv7em-none-eabihf

- name: Cache dependencies
uses: actions/cache@v6
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-embedded-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Test embedded cross-compilation
run: make test-embedded
Expand All @@ -117,25 +95,17 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: wasm32-unknown-unknown
rustflags: ""
# wasm-pack downloads wasm-bindgen/wasm-opt binaries into here.
cache-directories: ~/.cache/.wasm-pack

# Prebuilt: the Makefile's fallback is `cargo install wasm-pack --locked`,
# a multi-minute source build on a cold runner.
- name: Install wasm-pack
uses: taiki-e/install-action@wasm-pack

- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
~/.cache/.wasm-pack
target
key: ${{ runner.os }}-cargo-wasm-browser-${{ hashFiles('**/Cargo.lock') }}

# Chrome is preinstalled on the runner image, so this pins chromedriver to
# its major version; chromedriver refuses a browser it does not match.
- name: Install browser toolchain
Expand Down Expand Up @@ -186,19 +156,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: thumbv7em-none-eabihf, wasm32-unknown-unknown
components: rustfmt, clippy

- name: Cache dependencies
uses: actions/cache@v6
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-comprehensive-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Run comprehensive development check
run: make check
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/devcontainer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ jobs:
rustup --version
"

# `make check-toolchain-pin` compares two files; this compares the file to
# the compiler that actually landed in the image. The image is built from
# the .devcontainer/ context and never sees rust-toolchain.toml, so this is
# the only place the pin is checked against a real rustc.
- name: Test Rust version matches rust-toolchain.toml
run: |
pin="$(sed -n 's/^channel[[:space:]]*=[[:space:]]*"\(.*\)"/\1/p' rust-toolchain.toml)"
[ -n "$pin" ] || { echo "no [toolchain] channel in rust-toolchain.toml"; exit 1; }
got="$(docker run --rm aimdb-devcontainer:test rustc --version | awk '{print $2}')"
echo "pinned=$pin image=$got"
[ "$pin" = "$got" ] || {
echo "devcontainer image built rustc $got but the repo pins $pin"; exit 1;
}

- name: Test embedded targets
run: |
docker run --rm aimdb-devcontainer:test bash -c "
Expand Down
13 changes: 2 additions & 11 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: wasm32-unknown-unknown

- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-docs-cargo-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Build documentation
run: make doc
Expand Down
14 changes: 2 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: thumbv7em-none-eabihf, wasm32-unknown-unknown
components: rustfmt, clippy

- name: Cache dependencies
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-release-${{ hashFiles('**/Cargo.lock') }}
rustflags: ""

- name: Run comprehensive checks
run: make check
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""

- name: Install cargo-audit
run: cargo install cargo-audit
Expand All @@ -44,7 +46,9 @@ jobs:
submodules: recursive

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""

- name: Install cargo-deny
run: cargo install cargo-deny
Expand Down
11 changes: 4 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ AimDB is an async, in-memory database designed for data synchronization across *

### Prerequisites

- **Rust**: Latest stable version (2021 edition)
- **Rust cross-compilation targets**: required by `make check`/`make clippy`, which
cross-compile the embedded and wasm crates. The devcontainer installs these for
you; on a native setup add them manually:
```bash
rustup target add thumbv7em-none-eabihf wasm32-unknown-unknown
```
- **Rust**: pinned by [`rust-toolchain.toml`](rust-toolchain.toml). rustup reads
that file on every `cargo` call in this repo, so it installs the right compiler
and the embedded/wasm cross-compilation targets `make check` and `make clippy`
need. Nothing to add by hand.
- **Git**: For version control
- **Make**: For build automation
- **Docker**: For running integration tests (optional)
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ debug = 2
[workspace.package]
version = "1.1.0"
edition = "2021"
# The compiler we build and test with, and so the only one we can honestly
# promise consumers. Bump it together with rust-toolchain.toml.
rust-version = "1.98.0"
authors = ["AimDB Team <team@aimdb.dev>"]
license = "Apache-2.0"
repository = "https://github.com/aimdb-dev/aimdb"
Expand Down
49 changes: 47 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# AimDB Makefile
# Simple automation for common development tasks

.PHONY: help build test clean clean-embedded fmt fmt-check clippy doc all check test-embedded test-wasm wasm wasm-test wasm-test-deps examples deny audit security publish publish-check readme-check codegen-drift check-no-sim check-no-globals
.PHONY: help build test clean clean-embedded fmt fmt-check clippy doc all check test-embedded test-wasm wasm wasm-test wasm-test-deps examples deny audit security publish publish-check readme-check codegen-drift check-no-sim check-no-globals check-toolchain-pin
.DEFAULT_GOAL := help

# Separate target dir for embedded checks so an interrupted example build
Expand Down Expand Up @@ -703,8 +703,52 @@ check-no-globals:
printf "$(BLUE)✓ scanner verified against a positive control$(NC)\n"; \
printf "$(GREEN)✓ No library crate installs a process-global$(NC)\n"

# The devcontainer image builds from the .devcontainer/ context, so it cannot
# read rust-toolchain.toml and has to repeat the channel in ARG RUST_VERSION.
# Nothing else keeps the two honest. Every lookup is checked for emptiness so a
# parse that quietly returns nothing cannot make this pass vacuously.
check-toolchain-pin:
@printf "$(GREEN)Checking the devcontainer agrees with rust-toolchain.toml...$(NC)\n"
@pin=$$(sed -n 's/^channel[[:space:]]*=[[:space:]]*"\(.*\)"/\1/p' rust-toolchain.toml); \
arg=$$(sed -n 's/^ARG RUST_VERSION=\(.*\)$$/\1/p' .devcontainer/Dockerfile); \
if [ -z "$$pin" ]; then \
printf "$(RED)✗ no [toolchain] channel found in rust-toolchain.toml$(NC)\n"; exit 1; \
fi; \
if [ -z "$$arg" ]; then \
printf "$(RED)✗ no ARG RUST_VERSION found in .devcontainer/Dockerfile$(NC)\n"; exit 1; \
fi; \
if [ "$$pin" != "$$arg" ]; then \
printf "$(RED)✗ compiler drift: rust-toolchain.toml pins $$pin, .devcontainer/Dockerfile builds $$arg$(NC)\n"; \
printf "$(YELLOW) Update ARG RUST_VERSION in .devcontainer/Dockerfile to $$pin.$(NC)\n"; \
exit 1; \
fi; \
printf "$(BLUE)✓ compiler pinned to $$pin on both sides$(NC)\n"; \
targets=$$(sed -n 's/^targets[[:space:]]*=[[:space:]]*\[\(.*\)\]/\1/p' rust-toolchain.toml | tr -d '"' | tr ',' ' '); \
if [ -z "$$targets" ]; then \
printf "$(RED)✗ no targets found in rust-toolchain.toml$(NC)\n"; exit 1; \
fi; \
for t in $$targets; do \
if ! grep -q "rustup target add $$t" .devcontainer/Dockerfile; then \
printf "$(RED)✗ '$$t' is pinned in rust-toolchain.toml but the devcontainer never installs it$(NC)\n"; \
exit 1; \
fi; \
printf "$(BLUE)✓ $$t present in both$(NC)\n"; \
done; \
components=$$(sed -n 's/^components[[:space:]]*=[[:space:]]*\[\(.*\)\]/\1/p' rust-toolchain.toml | tr -d '"' | tr ',' ' '); \
if [ -z "$$components" ]; then \
printf "$(RED)✗ no components found in rust-toolchain.toml$(NC)\n"; exit 1; \
fi; \
for c in $$components; do \
if ! grep -q -- "-c $$c" .devcontainer/Dockerfile; then \
printf "$(RED)✗ '$$c' is pinned in rust-toolchain.toml but the devcontainer never installs it$(NC)\n"; \
exit 1; \
fi; \
printf "$(BLUE)✓ $$c present in both$(NC)\n"; \
done; \
printf "$(GREEN)✓ Devcontainer and rust-toolchain.toml agree$(NC)\n"

## Convenience commands
check: fmt-check clippy test test-embedded test-wasm deny readme-check codegen-drift check-no-sim check-no-globals
check: check-toolchain-pin fmt-check clippy test test-embedded test-wasm deny readme-check codegen-drift check-no-sim check-no-globals
@printf "$(GREEN)Comprehensive development checks completed!$(NC)\n"
@printf "$(BLUE)✓ Code formatting verified$(NC)\n"
@printf "$(BLUE)✓ Linter passed$(NC)\n"
Expand All @@ -715,6 +759,7 @@ check: fmt-check clippy test test-embedded test-wasm deny readme-check codegen-d
@printf "$(BLUE)✓ README quickstart in sync and compiling$(NC)\n"
@printf "$(BLUE)✓ Codegen output compiles against the workspace$(NC)\n"
@printf "$(BLUE)✓ No library crate installs a process-global$(NC)\n"
@printf "$(BLUE)✓ Devcontainer and CI pinned to the same compiler$(NC)\n"

## WASM commands
wasm:
Expand Down
1 change: 1 addition & 0 deletions aimdb-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-client"
version = "0.6.0"
edition = "2021"
rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-codegen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-codegen"
version = "0.2.0"
edition = "2021"
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-core"
version = "1.2.0"
edition = "2021"
rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-data-contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-data-contracts"
version = "0.4.0"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-derive"
version = "0.3.0"
edition.workspace = true
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-embassy-adapter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-embassy-adapter"
version = "0.6.0"
edition = "2021"
rust-version.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
Expand Down
1 change: 1 addition & 0 deletions aimdb-knx-connector/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "aimdb-knx-connector"
version = "0.5.0"
edition = "2021"
rust-version.workspace = true
authors.workspace = true
license.workspace = true
repository.workspace = true
Expand Down
Loading
Loading