mirror of
https://github.com/bherbruck/solidcraft.git
synced 2026-11-06 20:02:16 +00:00
2f92aaee6c
From the review of this PR: - What counts as code lives only in scripts/ci/affected.py now: nothing selected and not full means no code changed, on pull requests and pushes to main alike. The untested bash copy in Select checks disagreed with it. Root files and folders a crate embeds now select that crate (the licence texts and NOTICE: the engine; skills/: the MCP server's tests), where before a change to them ran no test at all. Other workflows and the bots' scripts select nothing. - A push to main skips the native jobs only when nothing a build reads changed since the last push to main whose run passed. Comparing with the push just before was unsafe: a newer push cancels a waiting run, so that commit may never have been tested. - Fail fast applies to pull requests only. On main, nightly and Run workflow the test build and the shards run regardless of the repository checks, so the action matrix and property tests that hang off Build tests keep their signal. Doc tests (main and nightly only now) no longer wait for the checks. - tests/robustness/ turns on the goldens, so a change to goldens.json runs the seed tests. - tests/oracle/ no longer selects the kernel, which never reads it. - The workflow header and CONTRIBUTING describe what main and pull requests now run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QWhMwdqJYQKQq8RCLSL1LT
136 lines
5.6 KiB
Python
136 lines
5.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Self-test for affected.py. Run: python3 -I scripts/ci/test_affected.py (from the repo root).
|
|
|
|
Uses a small synthetic workspace, then the real one (`cargo metadata --no-deps`).
|
|
"""
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import affected # noqa: E402
|
|
|
|
R = "/ws"
|
|
|
|
|
|
def pkg(name, dir_, deps=()):
|
|
return {
|
|
"name": name,
|
|
"manifest_path": f"{R}/{dir_}/Cargo.toml",
|
|
"dependencies": [{"name": d, "path": f"{R}/{p}"} for d, p in deps] + [{"name": "serde"}],
|
|
}
|
|
|
|
|
|
SYNTH = {
|
|
"workspace_root": R,
|
|
"packages": [
|
|
pkg("base", "crates/base"),
|
|
pkg("mid", "crates/mid", [("base", "crates/base")]),
|
|
pkg("top", "apps/top", [("mid", "crates/mid")]),
|
|
pkg("alone", "crates/alone"),
|
|
],
|
|
}
|
|
|
|
|
|
class Synthetic(unittest.TestCase):
|
|
def test_leaf_selects_only_itself(self):
|
|
self.assertEqual(affected.select(SYNTH, ["apps/top/src/main.rs"]), (False, ["top"]))
|
|
|
|
def test_reverse_dependencies_are_added(self):
|
|
self.assertEqual(affected.select(SYNTH, ["crates/base/src/lib.rs"]), (False, ["base", "mid", "top"]))
|
|
|
|
def test_unrelated_package_is_not_selected(self):
|
|
full, pk = affected.select(SYNTH, ["crates/mid/Cargo.toml"])
|
|
self.assertEqual((full, pk), (False, ["mid", "top"]))
|
|
|
|
def test_full_triggers(self):
|
|
for p in ["Cargo.lock", "Cargo.toml", ".cargo/config.toml", ".config/nextest.toml", "rust-toolchain.toml",
|
|
".github/workflows/ci.yml", "vendor/x/lib.rs", "tests/oracle/a.json", "assets/a.png",
|
|
"scripts/ci/affected.py", "unknown.txt"]:
|
|
self.assertEqual(affected.select(SYNTH, ["crates/alone/a.rs", p]), (True, []), p)
|
|
|
|
def test_docs_only_selects_nothing(self):
|
|
self.assertEqual(affected.select(SYNTH, ["docs/book/a.md", "README.md", "packaging/x.yml"]), (False, []))
|
|
|
|
def test_no_code_paths_select_nothing(self):
|
|
# What CI reads as "no code changed", on pull requests and pushes to main alike.
|
|
for p in [".github/workflows/docker.yml", ".github/ISSUE_TEMPLATE/bug.yml", "scripts/claim/claim.js",
|
|
"scripts/triage/triage.test.js", "vendor/README.md", "SECURITY.md"]:
|
|
self.assertEqual(affected.select(SYNTH, [p]), (False, []), p)
|
|
|
|
|
|
class RealWorkspace(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
cls.meta = affected.load_metadata(None)
|
|
|
|
def test_render_change_selects_render_and_dependents_not_kernel(self):
|
|
full, pk = affected.select(self.meta, ["crates/render/src/lib.rs"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-render", pk)
|
|
self.assertGreater(len(pk), 1)
|
|
self.assertNotIn("solidcraft-kernel", pk)
|
|
|
|
def test_cargo_lock_selects_full(self):
|
|
self.assertEqual(affected.select(self.meta, ["Cargo.lock"]), (True, []))
|
|
|
|
def test_docs_only_selects_nothing(self):
|
|
self.assertEqual(affected.select(self.meta, ["docs/book/src/dev/testing.md", "CONTRIBUTING.md"]), (False, []))
|
|
|
|
def test_goldens_select_the_engine_and_its_dependents_not_the_kernel(self):
|
|
full, pk = affected.select(self.meta, ["tests/robustness/goldens.json"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-engine", pk)
|
|
self.assertNotIn("solidcraft-kernel", pk)
|
|
self.assertNotIn("solidcraft-render", pk)
|
|
|
|
def test_oracle_cases_select_the_cli_and_xtask_not_the_kernel(self):
|
|
full, pk = affected.select(self.meta, ["tests/oracle/box/recipe.json"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-cli", pk)
|
|
self.assertIn("xtask", pk)
|
|
self.assertNotIn("solidcraft-kernel", pk)
|
|
|
|
def test_embedded_root_files_select_their_crate(self):
|
|
for path, pkg in [("ATTRIBUTION.md", "solidcraft-ui-egui"), ("LICENSE-MIT", "solidcraft-engine"),
|
|
("NOTICE", "solidcraft-engine"), ("THIRD-PARTY-LICENSES.txt", "solidcraft-engine"),
|
|
("skills/solidcraft-modeling/SKILL.md", "solidcraft-mcp")]:
|
|
full, pk = affected.select(self.meta, [path])
|
|
self.assertFalse(full, path)
|
|
self.assertIn(pkg, pk, path)
|
|
self.assertNotIn("solidcraft-kernel", pk, path)
|
|
|
|
def test_unmapped_test_data_selects_full(self):
|
|
self.assertEqual(affected.select(self.meta, ["tests/tools/x.json"]), (True, []))
|
|
|
|
def test_vendored_truck_selects_the_kernel_and_up_not_render(self):
|
|
full, pk = affected.select(self.meta, ["vendor/truck-shapeops/src/lib.rs"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-kernel", pk)
|
|
self.assertIn("solidcraft-engine", pk)
|
|
self.assertNotIn("solidcraft-render", pk)
|
|
self.assertNotIn("solidcraft-geom", pk)
|
|
|
|
def test_vendored_egui_wgpu_selects_the_ui_and_apps_not_the_kernel(self):
|
|
full, pk = affected.select(self.meta, ["vendor/egui-wgpu/src/winit.rs"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-ui-egui", pk)
|
|
self.assertIn("solidcraft", pk)
|
|
self.assertNotIn("solidcraft-kernel", pk)
|
|
self.assertNotIn("solidcraft-engine", pk)
|
|
|
|
def test_vendor_readme_alone_selects_nothing(self):
|
|
self.assertEqual(affected.select(self.meta, ["vendor/README.md"]), (False, []))
|
|
|
|
def test_translation_selects_the_ui_and_xtask_not_the_kernel(self):
|
|
full, pk = affected.select(self.meta, ["assets/locales/ja.json", "assets/locales/it.json"])
|
|
self.assertFalse(full)
|
|
self.assertIn("solidcraft-ui-egui", pk)
|
|
self.assertIn("xtask", pk)
|
|
self.assertNotIn("solidcraft-kernel", pk)
|
|
self.assertNotIn("solidcraft-engine", pk)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|