name: makepad-table # CI for the nested `makepad_table` workspace: the Table widget, the shared # document model, the PDF exporter and the invoicer app. # # This crate tree had no CI at all, and it showed. Its README stated it was # "written without a local cargo/rust toolchain, so the first compile on your # machine is the verification step" — and that first compile found three # defects in the money code, two of which made every currency string in the # application either panic or print the wrong number. None of them survive a # `cargo test`. This workflow is that `cargo test`, run on every push. # # Note the `--manifest-path`. `crates/apps/makepad_table` is named in the root # manifest's `workspace.exclude`, so it is invisible to every other workflow # here: `cargo test -p ...` from the repo root cannot reach it and # `--workspace` does not include it. Each step therefore points at the nested # manifest explicitly. Dropping the `--manifest-path` does not fail loudly, it # silently tests nothing, so the last job asserts the exclusion still holds. on: push: paths: - 'crates/apps/makepad_table/**' - 'rust-toolchain.toml' - '.forgejo/workflows/makepad-table.yml' pull_request: paths: - 'crates/apps/makepad_table/**' - 'rust-toolchain.toml' - '.forgejo/workflows/makepad-table.yml' env: MANIFEST: crates/apps/makepad_table/Cargo.toml jobs: # The model and the exporter are UI-free — serde, pdf-writer, ttf-parser — # so they need no GUI packages and give fast feedback on the arithmetic # that actually handles money. model: runs-on: ubuntu-latest timeout-minutes: 20 steps: - uses: actions/checkout@v4 - name: Document model tests run: cargo test --manifest-path "$MANIFEST" -p makepad-doc-model - name: PDF exporter tests run: cargo test --manifest-path "$MANIFEST" -p makepad-pdf-export - name: Clippy on the pure crates run: | cargo clippy --manifest-path "$MANIFEST" \ -p makepad-doc-model -p makepad-pdf-export \ --all-targets -- -D warnings # Money is stored in integer minor units precisely so that no rounding # error can enter a total. A reviewer adding `f64` to the model is # unlikely to be told why that is wrong, so the gate says it. - name: Amounts stay in integer minor units run: | set -euo pipefail MODEL=crates/apps/makepad_table/crates/doc-model/src/lib.rs if grep -nE '(_minor|amount|price|total|subtotal|discount)[a-z_]*:[[:space:]]*f(32|64)' "$MODEL"; then echo "FAIL: a monetary field is declared as a float" >&2 echo " minor units are i64 on purpose (see 'Data model highlights')" >&2 exit 1 fi # The widget needs Makepad's Linux backend to link, which is the slow half. widget: runs-on: ubuntu-latest timeout-minutes: 60 steps: - uses: actions/checkout@v4 - name: Install native dependencies run: | sudo apt-get update -qq sudo apt-get install -y -qq \ pkg-config libwayland-dev libxkbcommon-dev libx11-dev \ libxi-dev libxcursor-dev libxrandr-dev libgl1-mesa-dev \ libasound2-dev libpulse-dev libssl-dev - name: Widget tests run: cargo test --manifest-path "$MANIFEST" -p makepad-table - name: Widget clippy run: | cargo clippy --manifest-path "$MANIFEST" -p makepad-table \ --all-targets -- -D warnings # The invoicer's sidebar presentation logic is unit-tested; the rest # of it opens a window, so there is nothing to assert without a # display. The standalone demo is compile-only for the same reason. # Compiling both still catches the common break, which is a widget API # change the consumer was not updated for. - name: Invoicer tests run: cargo test --manifest-path "$MANIFEST" -p makepad-invoicer - name: Invoicer clippy run: | cargo clippy --manifest-path "$MANIFEST" -p makepad-invoicer \ --all-targets -- -D warnings - name: Demo compiles run: | cargo check --manifest-path "$MANIFEST" \ -p makepad-example-table --all-targets # The `capabilities` feature pulls nigig-uikit, which takes the # dependency tree from 89 crates to 275. That cost is only acceptable # because it is opt-in, so both halves have to keep working: the # default build must stay light, and the opt-in build must stay # buildable. A feature nothing compiles is a feature that rots — which # is exactly what happened to matrix_client's `native` (see # REVIEWS/MATRIX_CLIENT_FEATURE_GATE.md). - name: The capabilities feature still builds run: | cargo test --manifest-path "$MANIFEST" -p makepad-table \ --features capabilities - name: The default build pulls none of the heavy tree run: | set -euo pipefail # `cargo tree` on the default features must not mention any of # these. Checking the resolved tree rather than the manifest, # because an optional dependency can still be switched on by a # sibling crate's feature unification. leaked=$(cargo tree --manifest-path "$MANIFEST" -p makepad-table \ --prefix none 2>/dev/null \ | awk '{print $1}' | sort -u \ | grep -xE 'tokio|reqwest|hyper|clap|csv|image|nigig-uikit|nigig-core' || true) if [ -n "$leaked" ]; then echo "FAIL: the default build pulled the capabilities tree:" >&2 echo "$leaked" >&2 exit 1 fi echo "default build is clean of the capabilities dependencies" # makepad's own FileDialog is implemented on macOS only: the Linux and # Android backends never handle CxOsOp::SelectFileDialog, so a button # wired to it does nothing at all on the platform this repo targets. # That failure is invisible — it compiles, it runs, the dialog just # never appears — so the gate names it rather than trusting a reviewer # to remember. - name: The file picker is robius, not makepad's macOS-only dialog run: | set -euo pipefail APP=crates/apps/makepad_table/apps/invoicer/src/main.rs if grep -nE 'open_system_(openfile|savefile)_dialog' "$APP"; then echo "FAIL: uses makepad's FileDialog, which is macOS-only" >&2 echo " use robius_file_picker::FileDialog instead" >&2 exit 1 fi grep -q 'robius_file_picker' "$APP" \ || { echo "FAIL: the file picker import is gone" >&2; exit 1; } echo "file picking goes through robius-file-picker" hygiene: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v4 - name: Formatting run: | cargo fmt --manifest-path "$MANIFEST" -- --check \ || { echo "run: cargo fmt --manifest-path $MANIFEST"; exit 1; } # Without the exclusion this tree joins every workspace-wide build in # the repo and drags a second makepad checkout in with it. Cargo also # declines to absorb it because of its own `[workspace]` table, so this # asserts both halves: the root says exclude, and the nested manifest # still declares itself a workspace. - name: The nested workspace stays excluded from the root run: | set -euo pipefail # Match the quoted exclude entry, not the prose. The first version # of this check was a bare grep for the path, which the explanatory # comment above the exclude list also matches — deleting the entry # and keeping the comment passed the gate. Anchoring on the quotes # is what makes it able to fail. if ! grep -qE '^[[:space:]]*"crates/apps/makepad_table",?[[:space:]]*$' Cargo.toml; then echo "FAIL: root Cargo.toml no longer excludes crates/apps/makepad_table" >&2 exit 1 fi if ! grep -q '^\[workspace\]' "$MANIFEST"; then echo "FAIL: $MANIFEST no longer declares its own [workspace]" >&2 exit 1 fi members=$(cargo metadata --no-deps --format-version 1 --offline 2>/dev/null \ | tr ',' '\n' | grep -c 'makepad_table' || true) if [ "$members" -ne 0 ]; then echo "FAIL: makepad_table crates leaked into the root workspace" >&2 exit 1 fi echo "nested workspace is excluded from the root, and self-declared" # A floating git branch means the same commit builds against different # dependencies on different days. Every other crate here pins a rev. - name: Makepad dependency is pinned, not tracking a branch run: | set -euo pipefail if grep -rn 'branch[[:space:]]*=' crates/apps/makepad_table --include=Cargo.toml; then echo "FAIL: a manifest tracks a git branch instead of pinning a rev" >&2 exit 1 fi missing=0 while IFS= read -r manifest; do if grep -q 'makepad-widgets' "$manifest" && ! grep -q 'rev[[:space:]]*=' "$manifest"; then echo "FAIL: $manifest depends on makepad-widgets without a rev" >&2 missing=1 fi done < <(find crates/apps/makepad_table -name Cargo.toml) [ "$missing" -eq 0 ] echo "all makepad-widgets dependencies are pinned to a revision" - name: Reject whitespace errors run: git diff --check