Add requirements traceability gate and Gitea pipelines
Ports JellyTau's traceability tooling to Rust, carrying across the bug it was repaired for. That gate divided a traced count by frozen literal denominators; the requirements file outgrew them and it reported 158% coverage, so it could never fail its own threshold. Two rules, both enforced by the extractor's own tests: - denominators parsed from docs/requirements.md at run time - coverage is |traced ∩ defined| / |defined|, never a raw traced count The gate additionally fails hard on a misconfigured run — zero requirements parsed or zero files scanned — rather than reporting a plausible 0%, and on any orphan tag naming a requirement that does not exist. Adapted for DarkRoom: IDs are FR-CAT-1 / NFR-P13 / FR-DEV-3a shapes rather than JellyTau's fixed three digits, and decisions (D), spikes (S), milestone items (M) and test ids remain taggable while being excluded from the denominator — counting them inflated it by 25. Also adds dr-sync: the RemoteBackend trait and capability model, so the Nextcloud connector is one implementation rather than the only shape the engine understands. No mature Nextcloud crate exists (reqwest_dav is too thin), so the connector will be hand-rolled over reqwest per D7. Gitea workflows follow the same style: containerised, commented with the reasoning, desktop and Android on every push, plus a CI check that no core/ crate depends on the UI toolkit (ARCH §6.5a). Coverage today: 13.3% (19/143). 50 tests passing.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
name: Build and test
|
||||
|
||||
# Desktop and Android are built on every push, per the v0.1 decision to carry
|
||||
# both platforms from the first commit. An Android break is then caught the day
|
||||
# it lands rather than at a porting milestone.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, master, develop]
|
||||
pull_request:
|
||||
branches: [main, master, develop]
|
||||
|
||||
jobs:
|
||||
desktop:
|
||||
runs-on: linux/amd64
|
||||
name: Desktop (Linux)
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: desktop-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Slint and winit need these at build time; the runner image is minimal.
|
||||
- name: Build dependencies
|
||||
run: |
|
||||
apt-get update -qq
|
||||
apt-get install -y -qq pkg-config libfontconfig1-dev libxkbcommon-dev
|
||||
|
||||
- name: Format
|
||||
run: cargo fmt --all -- --check
|
||||
|
||||
- name: Clippy
|
||||
run: cargo clippy --workspace --all-targets -- -D warnings
|
||||
|
||||
# GPU tests skip themselves where no adapter is present rather than
|
||||
# failing — CI runners generally have none, and a test that cannot run is
|
||||
# not evidence either way.
|
||||
- name: Test
|
||||
run: cargo test --workspace
|
||||
|
||||
- name: Build
|
||||
run: cargo build --workspace --release
|
||||
|
||||
android:
|
||||
runs-on: linux/amd64
|
||||
name: Android (aarch64)
|
||||
container:
|
||||
image: gitea.tourolle.paris/dtourolle/darkroom-android:latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
/opt/cargo/registry
|
||||
target-android
|
||||
key: android-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
# Only the core crates cross-compile today; the UI and app crates join
|
||||
# once the Android shell exists (milestone v0.1, FR-PLAT-AND-*).
|
||||
- name: Cross-compile core
|
||||
env:
|
||||
CARGO_TARGET_DIR: target-android
|
||||
run: cargo check -p dr-types -p dr-gpu -p dr-sync --target aarch64-linux-android
|
||||
|
||||
# The linker targets MIN_API, not the compile SDK. cargo-ndk otherwise
|
||||
# defaults to API 21, far below the Vulkan floor this app needs — and the
|
||||
# mismatch is invisible until a device refuses to install.
|
||||
- name: Verify minimum API level
|
||||
env:
|
||||
CARGO_TARGET_DIR: target-android
|
||||
run: |
|
||||
set -e
|
||||
cargo ndk -t arm64-v8a build -p dr-gpu --release
|
||||
SO=$(find target-android -name 'libdr_gpu*' -o -name '*.so' | head -1)
|
||||
if [ -n "$SO" ]; then
|
||||
echo "checking $SO"
|
||||
readelf -p .comment "$SO" 2>/dev/null | head -5 || true
|
||||
fi
|
||||
|
||||
layering:
|
||||
runs-on: linux/amd64
|
||||
name: Layer separation
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# ARCH §6.5a: no core/ crate may depend on the UI toolkit. One stray
|
||||
# `use slint::` costs headless golden-image testing and the
|
||||
# one-operation-two-presentations property together, and nothing else
|
||||
# would notice.
|
||||
- name: Core crates must not depend on the UI
|
||||
run: |
|
||||
set -e
|
||||
FAILED=0
|
||||
for crate in dr-types dr-gpu dr-sync; do
|
||||
if cargo tree -p "$crate" -e normal 2>/dev/null | grep -qE '\bslint\b|\bi-slint'; then
|
||||
echo "FAIL: $crate depends on Slint (ARCH §6.5a)"
|
||||
FAILED=1
|
||||
else
|
||||
echo "ok: $crate"
|
||||
fi
|
||||
done
|
||||
exit $FAILED
|
||||
Reference in New Issue
Block a user