ci: run the workspace tests on every change; drop the unused flake

- .github/workflows/ci.yml runs `cargo test --workspace --locked` on
  pushes to main and on pull requests, with the Linux libraries the
  release build installs. No formatter check: the tree is not
  rustfmt-clean and stays that way.
- flake.nix, flake.lock and the direnv hook are removed. Nothing used
  them, and their pinned dependency hashes were already stale after the
  codec and kernel bumps.
- Under cfg(test) the "system" language resolves to en-US. The unit
  tests compare English text through one process-wide loader, and every
  apply_config of a default config asked for the system language, so a
  Turkish locale failed 22 tests and parallel tests raced each other
  through a language switch (the thickness-row test found its section
  under one language and looked it up under another).
- The arc grip test follows #1352: the start, end and midpoint grips
  drive the whole arc.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Fable 5.1 committed 2026-09-21 22:21:19 +03:00
1 parent fd2062bdec
commit ececb0ef8c
7 files changed
+63 -218

No files matched your search

-1
View File
@@ -1 +0,0 @@
use flake
+44
View File
@@ -0,0 +1,44 @@
name: Tests
# Until now nothing ran the test suite on a change: the release workflows
# build the app, web-check.yml type-checks the wasm target, and pull requests
# reported their own local runs. Run the workspace tests on every push to
# main and on every pull request. There is deliberately no formatter check:
# the tree is not rustfmt-clean and is not going to be reformatted.
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
concurrency:
group: tests-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
# The same libraries the Linux release build needs (windowing, GL,
# fonts); the packaging tools are left out.
- name: System libraries
run: |
sudo apt-get update
sudo apt-get install -y \
libgl1-mesa-dev libx11-dev libxcursor-dev libxi-dev libxrandr-dev \
libxkbcommon-dev libwayland-dev libfontconfig1-dev libfreetype6-dev
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
# LC_ALL=C: a few tests compare English message text.
- name: cargo test
env:
LC_ALL: C
run: cargo test --workspace --locked
-3
View File
@@ -36,9 +36,6 @@ __pycache__/
# Claude Code local preview/dev-server config
.claude/launch.json
# nix-direnv
.direnv/
# Worktrees created for isolated runs
.claude/worktrees/
Generated
-48
View File
@@ -1,48 +0,0 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1789149629,
"narHash": "sha256-H6GwaZzZf+4npqv0tph94w9tZddSjFjmQrVsW0z78uk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "eaad089433ca2bb662274377d33df3d0e51ef28b",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"rust-overlay": "rust-overlay"
}
},
"rust-overlay": {
"inputs": {
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1789196581,
"narHash": "sha256-yJr1Bt4fKkKIpPYbsKGqJ0VFdoDnURgRwuffmBQ2WzY=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "228ecefb6329d5a531b77b46b581a2f0c26ee056",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
}
},
"root": "root",
"version": 7
}
-156
View File
@@ -1,156 +0,0 @@
{
description = "Open CAD Studio - 2D drafting and 3D modeling in Rust";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# rust-overlay ships upstream Rust binaries rather than building them, so
# following nixpkgs costs it no binary cache.
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, rust-overlay }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
forAllSystems = f:
nixpkgs.lib.genAttrs systems (system: f (import nixpkgs {
inherit system;
overlays = [ rust-overlay.overlays.default ];
}));
in
{
packages = forAllSystems (pkgs:
let
inherit (pkgs) lib stdenv;
toolchain = pkgs.rust-bin.stable.latest.default.override {
targets = [ "wasm32-unknown-unknown" ];
};
# Build with the overlay's toolchain rather than the nixpkgs default,
# so the package and the devShell compile with the same rustc.
rustPlatform = pkgs.makeRustPlatform {
cargo = toolchain;
rustc = toolchain;
};
# winit/wgpu dlopen these at run time, so they must also be on the
# wrapped binary's LD_LIBRARY_PATH, not just at link time.
runtimeLibs = with pkgs; [
libGL
libxkbcommon
vulkan-loader
wayland
xorg.libX11
xorg.libXcursor
xorg.libXi
xorg.libXrandr
];
in
rec {
default = opencadstudio;
opencadstudio = rustPlatform.buildRustPackage {
pname = "opencadstudio";
version = (lib.importTOML ./Cargo.toml).package.version;
src = self;
cargoLock = {
lockFile = ./Cargo.lock;
# One entry per distinct git source in Cargo.lock, keyed by any
# one package from it. Two of these are transitive and easy to
# miss by reading Cargo.toml alone: cryoglyph and dpi arrive
# through iced, which pins its own forks. Regenerate the list
# from the lock rather than the manifest:
# grep -B2 'source = "git+' Cargo.lock
# Each hash must be refreshed whenever the matching rev moves.
outputHashes = {
"acadrust-0.5.5" = "sha256-rYtJaJsb+lZZIDBtPTCfWRVyA1Gfinn3UqJlfzkhhGk=";
"cadkernel-0.1.0" = "sha256-7smcL9oo5mJwoCLYUbD4+lA9Xcm+/qpVswYxzoGjTDk=";
"cryoglyph-0.1.0" = "sha256-5BOJNDcjhpt17/XSri3JGtX8NwC7db18bddp5wanMes=";
"dpi-0.1.1" = "sha256-pQn1lCFSJMkjUfHoggEzMHnm5k+Chnzi5JEDjahnjUA=";
"iced-0.15.0-dev" = "sha256-Atg+nr1VgXwW5I7LiMAMqHemz/9ZiehTc2EWuSFEGHI=";
"iced_aw-0.14.1" = "sha256-OynSIjv8SgSoxpw1S4wH58vDdqga/YojOR5A9ZLKrd8=";
};
};
nativeBuildInputs = with pkgs; [
pkg-config
makeWrapper
];
buildInputs = with pkgs; [
fontconfig
freetype
] ++ runtimeLibs
++ lib.optionals stdenv.hostPlatform.isDarwin [ darwin.apple_sdk.frameworks.AppKit ];
# build.rs asks git for a revision and falls back to "unknown"
# when the repo or the binary is absent, which it is in the
# sandbox. Nothing to do but let it take the fallback.
doCheck = false;
postInstall = lib.optionalString stdenv.hostPlatform.isLinux ''
wrapProgram $out/bin/OpenCADStudio \
--prefix LD_LIBRARY_PATH : ${lib.makeLibraryPath runtimeLibs}
'';
meta = {
description = "Open-source 2D drafting and 3D modeling, built with Rust";
homepage = "https://www.opencadstudio.com";
license = lib.licenses.gpl3Only;
mainProgram = "OpenCADStudio";
platforms = systems;
};
};
});
devShells = forAllSystems (pkgs:
let
toolchain = pkgs.rust-bin.stable.latest.default.override {
extensions = [ "rust-src" "rust-analyzer" "clippy" "rustfmt" ];
targets = [ "wasm32-unknown-unknown" ];
};
runtimeLibs = with pkgs; [
libGL
libxkbcommon
vulkan-loader
wayland
xorg.libX11
xorg.libXcursor
xorg.libXi
xorg.libXrandr
];
in
{
default = pkgs.mkShell {
packages = with pkgs; [
toolchain
pkg-config
fontconfig
freetype
git
# Web build: `trunk build` per Trunk.toml. wasm-bindgen-cli must
# match the wasm-bindgen version Cargo.lock resolves, the same
# constraint .github/workflows/pages.yml:83 reads out of the lock.
trunk
wasm-bindgen-cli
# Rasterises assets/logo.svg for packaging, as release.yml does.
librsvg
] ++ runtimeLibs;
# A dev binary is run straight out of ./target, so it never gets
# the wrapper the package build applies.
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath runtimeLibs;
};
});
checks = forAllSystems (pkgs: {
default = self.packages.${pkgs.stdenv.hostPlatform.system}.opencadstudio;
});
formatter = forAllSystems (pkgs: pkgs.nixpkgs-fmt);
};
}
+7
View File
@@ -158,6 +158,13 @@ impl std::fmt::Display for Language {
}
fn system_languages() -> Vec<i18n_embed::unic_langid::LanguageIdentifier> {
// The unit tests compare English prompts and messages through one
// process-wide loader, and every `apply_config` of a default config asks
// for the system language, so the machine's locale must never reach
// them — not even from a test that runs in parallel.
#[cfg(test)]
return vec!["en-US".parse().expect("en-US is a valid language identifier")];
#[cfg(target_arch = "wasm32")]
let mut requested = WebLanguageRequester::requested_languages();
#[cfg(not(target_arch = "wasm32"))]
+12 -10
View File
@@ -2371,7 +2371,10 @@ mod tests {
}
#[test]
fn arc_grips_drive_center_start_and_end_but_not_midpoint() {
/// The center grip drives the center; the start, end and midpoint grips
/// reshape the arc, so they drive the whole curve and a paired Equal or
/// Symmetric follows the new radius and sweep.
fn arc_grips_drive_center_or_the_whole_arc() {
let handle = h(8);
let arc = acadrust::EntityType::Arc(acadrust::entities::Arc::from_coords(
0.0,
@@ -2386,15 +2389,14 @@ mod tests {
grip_solve_anchor_refs(&arc, handle, 0),
vec![ParametricRef::center(handle)]
);
assert_eq!(
grip_solve_anchor_refs(&arc, handle, 1),
vec![ParametricRef::point(handle, 0)]
);
assert_eq!(
grip_solve_anchor_refs(&arc, handle, 2),
vec![ParametricRef::point(handle, 1)]
);
assert_eq!(grip_solve_anchor_refs(&arc, handle, 3), Vec::new());
for grip in 1..=3 {
assert_eq!(
grip_solve_anchor_refs(&arc, handle, grip),
vec![ParametricRef::whole(handle)],
"grip {grip}"
);
}
assert_eq!(grip_solve_anchor_refs(&arc, handle, 4), Vec::new());
}
#[test]