Reference consumer for the current SCAD project architecture built around tool.scad-project.
The repository demonstrates the intended separation:
docker.scad-toolchain
runtime and external capabilities
tool.scad-project
reusable project workflow and conventions
template.scad-project
project configuration, CAD source and project documentation
- Production build
- Production build overview
- Production build PNG gallery
- Production build provenance
- Production verification
- Project releases
tool.scad-project v0.9.8
SCAD toolchain v0.4.1
SCons 4.11.1
The tool dependency is expressed semantically as v0.9.8 in project.yml. The Git submodule gitlink at tools/tool.scad-project points to the commit behind that tag, while Build, Verify and Release callers are pinned to the exact same 40-character commit SHA. This keeps the dependency readable while making reusable-workflow composition immutable and unambiguous.
This repository is the canonical minimal consumer for tool.scad-project. A tool release should be exercised here to prove that the documented project structure, bootstrap/update flow and thin Build/Verify/Release callers still work together on a small representative project.
The template is intentionally not the only integration test. Larger consumers can supplement it when a feature needs a realistic dependency graph or enough independent outputs to demonstrate selective rebuild behaviour. In particular, dependency-selective cache tests are more informative in a project such as the HUB75 display frame, while this repository remains the first-line reference/smoke consumer.
Functional verification also checks the reference-consumer tooling contract: the semantic tool ref in project.yml must resolve to the checked-out tool gitlink commit, all three workflow callers must use that exact commit SHA, and the root bootstrap/update scripts must match the canonical scripts from that pinned release.
.
├── project.yml
├── dsg/
│ ├── openscad/
│ │ ├── ext/
│ │ ├── lib/
│ │ ├── components/
│ │ ├── assemblies/
│ │ ├── render/
│ │ ├── export/
│ │ └── main.scad
│ └── pythonscad/
├── tools/
│ └── tool.scad-project/
├── scripts/
├── vrf/
└── .github/workflows/
bld/ is generated output and is not source-of-truth content.
Normal OpenSCAD outputs are discovered from directories configured in project.yml:
paths:
design_root: dsg
build_root: bld
render_root: dsg/openscad/render
export_root: dsg/openscad/exportThe default mapping is:
dsg/openscad/render/*.scad -> bld/png/*.png
dsg/openscad/export/*.scad -> bld/stl/*.stl
The reference assembly therefore has two small stable entrypoints with the same basename:
dsg/openscad/render/tube-holder-assembly.scad
dsg/openscad/export/tube-holder-assembly.scad
No explicit builds: entries are needed for these normal targets. Use optional render.yml or export.yml only when an entrypoint needs special profiles such as multiple sizes or a non-default render size. Explicit builds: remain available for exceptional mappings, but they are not the preferred normal template pattern.
The template enables the selective build backend:
build_engine:
engine: sconsSCons tracks OpenSCAD dependencies and restores unchanged outputs from the persistent CI cache. The generated design tree is also restored from cache when its complete input set is unchanged.
tool.scad-project v0.9.8 generates bld/png/README.md as a browseable, deterministically ordered gallery whenever PNG build output is present. The generated bld/README.md links directly to that gallery.
Open:
dsg/openscad/main.scad
The reference assembly contains a mounting plate, a reusable clamp from lib.scad.clamps, and a 20 mm reference tube. The reusable clamp keeps its library-native coordinate system; the project adapter performs the mounting rotation at the assembly boundary.
Each meaningful component or assembly owns source documentation under design/design.md. Render declarations live in that document rather than in project.yml.
Example:
<!-- scad-render-defaults
module: tube_design
vpr: [60, 0, 35]
-->
<!-- scad-render
view: outer
-->The project default design image size is 640x480. Generated design documentation is materialized under bld/design/ and is never committed beside source design.md files.
The template deliberately sets:
design:
include_externals: falseExternal CAD source remains available to the project, but the consumer publishes only its project-owned design documentation.
A small PythonSCAD component under dsg/pythonscad/ remains as an end-to-end demonstration of the multi-engine design pipeline.
The root bootstrap and update scripts are exact copies of the canonical scripts from the pinned tool release:
bootstrap.ps1
bootstrap.sh
update-repo.ps1
update-repo.sh
Bootstrap deliberately needs only Git plus PowerShell/bash. It restores the direct submodules declared in .gitmodules:
tools/tool.scad-project
dsg/openscad/ext/lib.scad.clamps
Normal dependency policy lives in project.yml. To advance configured dependencies intentionally, run:
.\update-repo.ps1or:
bash ./update-repo.shThe updater leaves gitlink/workflow changes uncommitted for normal review. From v0.9.6 it advances the Build, Verify and Release callers together with the tool dependency; from v0.9.8 those workflow callers are written as the exact checked-out tool commit SHA instead of the semantic tag text. Direct dependency checkout is intentionally non-recursive; a consumer does not initialize development dependencies nested inside its libraries.
After bootstrap, use the pinned local tool:
.\tools\tool.scad-project\scad-project.ps1 config-lint
.\tools\tool.scad-project\scad-project.ps1 externals-check
.\tools\tool.scad-project\scad-project.ps1 docs-lint
.\tools\tool.scad-project\scad-project.ps1 design-lint
.\tools\tool.scad-project\scad-project.ps1 design-build
.\tools\tool.scad-project\scad-project.ps1 build
.\tools\tool.scad-project\scad-project.ps1 verifyThe repository keeps thin workflow callers pinned to the exact tool commit corresponding to the semantic release in project.yml:
jobs:
build:
uses: brainboxemb/tool.scad-project/.github/workflows/project-build.yml@360b6aa950288adfad845fffccd0ffa41becd45cBuild owns configuration/external/source/design linting, generated-design cache handling, dependency-selective PNG/STL generation, build indexing, provenance and publication. Verify owns generic build/source verification, project-specific verification commands, provenance and verification publication.
Generated output stays off main.
main
source and project configuration
prod/build
prod/verification
latest successful generated production snapshots
dev/build
dev/verification
latest successful generated development snapshots
rel/vX.Y.Z/build
rel/vX.Y.Z/verification
immutable browseable project-release snapshots
Pull requests remain artifact-only. A coordinated project release is created from the exact current production-branch HEAD only after Build and Verify both succeed. A GitHub Release then contains deterministic build/verification/STL bundles plus SHA256SUMS.txt and links back to the immutable browseable rel/* branches.
Every generated snapshot includes publication-info.txt with source commit, tool/toolchain versions, submodule pins and runtime provenance.
Structured OpenSCAD comments use openscad_docsgen conventions and start with // File: or // LibFile: before structured module/function blocks. scad-project docs-lint validates this in CI.
The model and documentation were developed with the assistance of ChatGPT.