Skip to content

Commit 96393d1

Browse files
authored
feat: implement custom dependency manager and renovate preset (#106)
This PR introduces **scadm** - a standalone OpenSCAD dependency manager published to PyPI, replacing legacy shell scripts with a modern Python package. ## 🚀 New Features ### scadm Package (PyPI) - **Published Package**: `cmd/scadm/` - Standalone Python package for managing OpenSCAD installations and library dependencies - Install: `pip install scadm` - Zero external dependencies (stdlib only) - Cross-platform support (Windows, Linux, macOS) - Python 3.11+ required - **CLI Interface**: Simple commands for installation management - `scadm install` - Install OpenSCAD (nightly default) + libraries - `scadm check` - Verify installation status - `scadm install --stable` - Install stable release - `scadm install --force` - Force reinstall - **Configuration**: `scadm.json` in project root (moved from `cmd/setup/dependencies.json`) - Defines library dependencies with Git SHAs or semver tags - Supports GitHub sources for libraries (BOSL2, MCAD, etc.) - Automatic workspace detection (searches parent dirs) ### Release & Publishing - **Release-Please**: Configured monorepo support for dual releases - `homeracker` (main project) at root - `scadm` (Python package) at `cmd/scadm/` - **GitHub Actions**: Automated PyPI publishing workflow - Triggers on `scadm-v*` tags - Uses PyPI trusted publishing (OIDC) - Manual dispatch option for testing ### Renovate Integration - **Reusable Preset**: `renovate-dependencies.json` for tracking `scadm.json` dependencies - Other OpenSCAD projects can use: `"extends": ["github>kellervater/homeracker:renovate-dependencies"]` - Supports both Git commit SHAs and semver tags - **Enhanced Tracking**: Updated `renovate.json5` to track: - OpenSCAD versions in `cmd/scadm/scadm/constants.py` - Python versions in GitHub Actions (built-in Renovate support confirmed) ## 🔧 Improvements ### Code Quality - **Exception Handling**: Replaced broad `Exception` catches with specific types - `OSError, subprocess.SubprocessError` for process execution - `zipfile.BadZipFile, tarfile.TarError` for archive operations - Added debug logging for suppressed exceptions with explanatory comments ### Documentation - **README**: Comprehensive scadm documentation with Renovate integration example - **Copilot Instructions**: Updated with: - scadm usage guidelines - Renovate version pinning requirements (mandatory) - Pre-commit hooks in mandatory workflow - **CONTRIBUTING.md**: Updated quick start to use `scadm install` ## 🗑️ Removed - **Legacy Scripts**: Deleted `cmd/setup/install-dependencies.sh` and `cmd/setup/install-openscad.sh` ## 📝 Updated - **CI Workflows**: `pre-commit.yml` and `validate-models.yml` now use `scadm install` - **Git Ignore**: Added `cmd/scadm/dist/` and `*.egg-info/` (build artifacts) ## 🧪 Testing - All pre-commit hooks pass - Package builds successfully with setuptools - Metadata validated with twine - Ready for PyPI publication after merge
1 parent c4c1a02 commit 96393d1

23 files changed

+907
-562
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2-
".": "1.2.0"
2+
".": "1.2.0",
3+
"cmd/scadm": "0.1.0"
34
}

.github/config/release-please-config.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,14 @@
1515
"extra-label": "automerge",
1616
"include-v-in-tag": true,
1717
"packages": {
18-
".": {}
19-
},
20-
"release-type": "simple"
18+
".": {
19+
"release-type": "simple",
20+
"package-name": "homeracker"
21+
},
22+
"cmd/scadm": {
23+
"release-type": "python",
24+
"package-name": "scadm",
25+
"component": "scadm"
26+
}
27+
}
2128
}

.github/copilot-instructions.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,14 @@ HomeRacker is a modular 3D-printable rack-building system. Core components use p
55

66
## Tools & Structure
77
- **Languages**: OpenSCAD (.scad), Python, Bash
8+
- **Preferred Tooling**: GitHub MCP Server, Context7 MCP Server
89
- **Key Dirs**: `/models/` (SCAD files), `/bin/` (tools), `/scripts/` (Fusion 360 automation)
910
- **HomeRacker Standards**: 15mm base unit, 4mm lock pins, 2mm walls, 0.2mm tolerance. See `README.md` for details.
11+
- **Contribution Guide**: See `CONTRIBUTING.md` for setup and workflow instructions.
12+
- **Dependency Manager**: Use `scadm` to install OpenSCAD and libraries
13+
- Install: `scadm` (installs OpenSCAD + libraries from `scadm.json`)
14+
- Config: `scadm.json` in project root defines library dependencies
15+
- Help: `scadm -h` for usage info
1016

1117
## Core Principles
1218
- **Test-Driven Development**: NO change without a test. EVERY change MUST be tested before completion. No exceptions for "simple" changes.
@@ -26,7 +32,8 @@ HomeRacker is a modular 3D-printable rack-building system. Core components use p
2632
3. **Ask before proceeding** if requirements conflict with best practices
2733
4. **Provide outline** before implementation for confirmation
2834
5. **Make the change** and immediately test it - do NOT announce completion before testing
29-
6. **On errors**: Step back, check docs, ask user if stuck—don't iterate blindly
35+
6. **Run pre-commit hooks** to catch formatting/linting issues before commit. Fix any issues found (no ignores allowed).
36+
7. **On errors**: Step back, check docs, ask user if stuck—don't iterate blindly
3037

3138
## OpenSCAD Guidelines
3239
- Use BOSL2 for complex geometry
@@ -46,5 +53,9 @@ HomeRacker is a modular 3D-printable rack-building system. Core components use p
4653
- Add inline comments only for complex regex patterns or non-obvious logic
4754

4855
## Renovate Guidelines
56+
- **Version Pinning**: MANDATORY for all dependencies (Renovate manages updates)
57+
- Pin exact versions, never use version ranges or `latest`
58+
- New pinning patterns: Research Renovate docs first to ensure proper tracking
59+
- Examples: Docker tags, Python packages, GitHub Actions, OpenSCAD versions
4960
- **Testing**: Run `cmd/test/test-renovate-local.sh` to verify config changes
5061
- **Important**: Changes MUST be pushed to the current branch before running the test (script runs in Docker context)

.github/workflows/pre-commit.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ jobs:
2424
sudo apt-get update
2525
sudo apt-get install -y xvfb libglu1-mesa libfuse2 libegl1 libxcb-cursor0
2626
27-
- name: Install OpenSCAD
27+
- name: Install OpenSCAD and dependencies
2828
run: |
29-
chmod +x cmd/setup/install-openscad.sh
30-
./cmd/setup/install-openscad.sh --nightly
29+
pip install -e cmd/scadm
30+
scadm
3131
3232
- name: Make scripts executable
3333
run: chmod +x cmd/export/export-core-models.sh .githooks/makerworld-export
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Publish scadm to PyPI
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
dry_run:
9+
description: 'Dry run (build but do not publish)'
10+
required: false
11+
type: boolean
12+
default: false
13+
14+
permissions:
15+
contents: read
16+
id-token: write # Required for PyPI trusted publishing
17+
18+
jobs:
19+
publish:
20+
# Only publish scadm releases (tagged as scadm-v*)
21+
if: github.event_name == 'workflow_dispatch' || startsWith(github.event.release.tag_name, 'scadm-v')
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout code
25+
uses: actions/checkout@v4
26+
27+
- name: Set up Python
28+
uses: actions/setup-python@v5
29+
with:
30+
python-version: '3.11'
31+
32+
- name: Install build tools
33+
run: |
34+
python -m pip install --upgrade pip
35+
pip install build twine
36+
37+
- name: Build package
38+
working-directory: cmd/scadm
39+
run: python -m build
40+
41+
- name: Check package
42+
working-directory: cmd/scadm
43+
run: twine check dist/*
44+
45+
- name: Publish to PyPI
46+
if: ${{ !inputs.dry_run }}
47+
uses: pypa/gh-action-pypi-publish@release/v1
48+
with:
49+
packages-dir: cmd/scadm/dist/
50+
print-hash: true

.github/workflows/validate-models.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ on:
66
paths:
77
- 'models/**/*.scad'
88
- '.github/workflows/validate-models.yml'
9-
- 'cmd/setup/install-openscad.sh'
10-
- 'cmd/setup/install-dependencies.sh'
9+
- 'cmd/scadm/**'
10+
- 'scadm.json'
1111
- 'cmd/test/openscad-render.sh'
1212

1313
jobs:
@@ -27,8 +27,8 @@ jobs:
2727
2828
- name: Install OpenSCAD and dependencies
2929
run: |
30-
chmod +x cmd/setup/install-openscad.sh
31-
./cmd/setup/install-openscad.sh --nightly
30+
pip install -e cmd/scadm
31+
scadm
3232
3333
- name: Validate models
3434
run: |

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ bin/openscad/
55
bin/openscad-nightly/
66
renovate_cache/
77
renovate_base/
8+
9+
# Python
10+
__pycache__/
11+
*.py[cod]
12+
cmd/scadm/dist/
13+
cmd/scadm/*.egg-info/

CONTRIBUTING.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ Thanks for your interest in contributing! Even getting this far is already worth
99
git clone https://github.com/kellervater/homeracker.git
1010
cd homeracker
1111

12-
# Install OpenSCAD (Windows/Linux/macOS)
13-
./cmd/setup/install-openscad.sh
14-
./cmd/setup/install-dependencies.sh
12+
# Install scadm package (openscad dependency manager)
13+
pip install -e cmd/scadm
14+
15+
# Install OpenSCAD (Windows/Linux/macOS) + Dependencies
16+
scadm
17+
1518
# Optional (VSCode Integration)
1619
./cmd/setup/install-vscode-openscad.sh
1720

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ The parametric models are available in the [HomeRacker GitHub Repository](https:
2626
- [❓ Why the name?](#-why-the-name)
2727
- [📜 Licensing](#-licensing)
2828
- [🤝 Contributing](CONTRIBUTING.md)
29+
- [🛠️ Developer Tools](#%EF%B8%8F-developer-tools)
2930
- [🚀 Releases](#-releases)
3031
- [🧪 Tests](#-tests)
3132
- [⚠️ Disclaimer](#%EF%B8%8F-disclaimer)
3233
- [🔬 How I tested](#-how-i-tested)
33-
- [📋 Todos](#-todos)
3434

3535
# 🔧 Use Cases
3636
I created HomeRacker because I was dissatisfied with the existing solutions available online.
@@ -221,6 +221,23 @@ These licenses apply to the `HomeRacker - Core` system and customizable rackmoun
221221
222222
HomeRacker is an unregistered trademark of Patrick Pötz (), first used publicly on 12.04.2025.
223223

224+
# 🛠️ Developer Tools
225+
226+
HomeRacker includes custom tooling to streamline development:
227+
228+
- **[scadm](cmd/scadm/README.md)** - OpenSCAD + library dependency manager
229+
- Zero-dependency Python package for installing OpenSCAD (nightly/stable) and libraries
230+
- Cross-platform: Windows, Linux, macOS (might work, dunno)
231+
- Install: `pip install scadm``scadm`
232+
- Manages dependencies from `scadm.json`
233+
234+
- **[Renovate Preset](renovate-dependencies.json)** - Automated dependency updates
235+
- Tracks OpenSCAD versions, GitHub releases, and Python packages
236+
- Custom rules for this project's specific needs
237+
- Extend in your project: `"extends": ["github>kellervater/homeracker:renovate-dependencies"]`
238+
239+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup instructions.
240+
224241
# 🚀 Releases
225242

226243
HomeRacker uses automated releases powered by Camunda's GitHub actions:

cmd/README.md

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,67 @@
1-
# 🔧 OpenSCAD Installation Scripts
1+
# 🔧 OpenSCAD Installation and Testing
22

3-
Automated installation of OpenSCAD for the HomeRacker workspace (Windows/Linux/macOS).
3+
This directory contains testing scripts for OpenSCAD models.
4+
5+
For installation, use the **scadm** package (see `cmd/scadm/` or install via `pip install scadm`).
46

57
## 📦 Quick Start
68

79
```bash
8-
# Install or upgrade to latest nightly release (default)
9-
./cmd/setup/install-openscad.sh
10-
11-
# Install nightly build (default)
12-
./cmd/setup/install-openscad.sh --nightly
10+
# Install scadm (if not already installed)
11+
pip install -e cmd/scadm
1312

14-
# Install dependencies (BOSL2 library) - already done on a fresh install-openscad call
15-
./cmd/setup/install-dependencies.sh
13+
# Install OpenSCAD + dependencies from scadm.json
14+
scadm
1615

17-
# Check if update is available
18-
./cmd/setup/install-openscad.sh --check
16+
# Check if updates are available
17+
scadm --check
1918

2019
# Run smoke test - validates the current openscad installation against local models
21-
./cmd/setup/install-openscad.sh --test
22-
23-
# Test specific model files (e.g., after export or during development)
2420
./cmd/test/openscad-render.sh models/core/parts/connector.scad
2521

2622
# Run automated test suite (all models in test/ and makerworld/ directories)
2723
./cmd/test/test-models.sh
28-
29-
# Force reinstall
30-
./cmd/setup/install-openscad.sh --force
3124
```
3225

3326
## 🤖 Automatic Updates
3427

35-
Versions are tracked in the scripts and managed by Renovate Bot. When new releases are available, Renovate creates a PR to update the versions. After merging, run the install scripts to upgrade.
28+
OpenSCAD versions are managed by Renovate Bot in `cmd/scadm/scadm/constants.py`. When new releases are available, Renovate creates a PR to update the versions.
29+
30+
## 📦 Dependency Management
31+
32+
Dependencies are defined in `scadm.json` at the repository root. The installer supports both Git commit hashes (SHAs) and SemVer tags.
3633

37-
## 📝 Notes
34+
### Configuration Format (`scadm.json`)
3835

39-
- **Default**: Nightly snapshots - latest features and fixes
40-
- **Stable**: Release 2021.01 - use `--stable` flag for BOSL2 compatibility
41-
- **Platform Support**: Windows, Linux, and macOS (macOS treated as Linux using AppImage - untested)
42-
- **BOSL2**: Installed to bundled libraries directory
43-
- **Source**: https://files.openscad.org/
36+
```json
37+
{
38+
"dependencies": [
39+
{
40+
"name": "BOSL2",
41+
"repository": "BelfrySCAD/BOSL2",
42+
"version": "266792b2a4bbf7514e73225dfadb92da95f2afe1",
43+
"source": "github"
44+
},
45+
{
46+
"name": "homeracker",
47+
"repository": "kellervater/homeracker",
48+
"version": "v1.1.0",
49+
"source": "github"
50+
}
51+
]
52+
}
53+
```
54+
55+
### Renovate Integration
56+
57+
To enable Renovate to update these dependencies, extend the configuration from this repository in your `renovate.json`:
58+
59+
> **Note**: Use `github>...` for external repositories. Internally, this repository uses `local>...`.
60+
61+
```json
62+
{
63+
"extends": [
64+
"github>kellervater/homeracker:renovate-dependencies.json"
65+
]
66+
}
67+
```

0 commit comments

Comments
 (0)