* fix: lots of fixes and name refactoring * feat: Add workbench preferences * fix: MCP bridge status widget and just command fixes * fix(tests): Use the correct mesa-glx package * fix(ci): Add fontconfig to GUI test dependencies FreeCAD GUI was failing to start with: "Fontconfig error: Cannot load default config file: No such file" Added fontconfig and fonts-dejavu-core packages to the GUI test job dependencies to resolve the font configuration issue. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(addon): Extract path utilities into shared module Create path_utils.py module that consolidates duplicated path-finding logic from commands.py and InitGui.py: - get_addon_path(): Find addon directory with caching and fallbacks - get_icon_path(): Get full path to an icon file - get_icons_dir(): Get path to icons directory - get_workbench_icon(): Get path to workbench main icon This removes ~100 lines of duplicated code while preserving the same behavior including _addon_path_cache and all fallback methods. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(addon): Prevent stale plugin state on startup failure The StartMCPBridgeCommand.Activated method could leave _mcp_plugin in a partially initialized state if FreecadMCPPlugin.start() failed after the plugin was instantiated. Changes: - Create plugin in a local variable first - Only assign to _mcp_plugin after start() succeeds - Explicitly clear _mcp_plugin and _running_config in exception handlers to ensure clean state for subsequent retry attempts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: Lot of broad improvements * fix(ci): Use blocking headless_server.py for GUI tests The GUI test was using startup_bridge.py which is non-blocking (designed for interactive use). For CI, even in GUI mode, we need the blocking headless_server.py that calls run_forever() to keep FreeCAD running. GUI features are still available since we use the 'freecad' executable instead of 'freecadcmd'. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(addon): Rename headless_server.py to blocking_bridge.py The old name was misleading because: - It works with both GUI (freecad) and headless (freecadcmd) modes - The key characteristic is that it BLOCKS with run_forever() New naming convention clarifies the difference: - blocking_bridge.py: Starts bridge and blocks (for CI, servers) - startup_bridge.py: Starts bridge and returns (for interactive GUI) Updated all references across: - GitHub workflow (macro-test.yaml) - Just commands (freecad.just) - Unit tests (test_addon_structure.py) - Documentation (5 files) - CLAUDE.md Also improved the script to detect GUI mode dynamically using FreeCAD.GuiUp and display the appropriate status message. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(just): Remove erroneous rm of startup_bridge.py on error The startup script is now a permanent source file in the repository, not a generated temporary file. The rm -f would have deleted source code if FreeCAD wasn't found. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: General improvements * fix: Lots of general fixes and only stable to PyPi * fix: small cleanup * fix: Small fixes and hopefully fixes the GUI tests * fix: Add proper library paths for FreeCAD GUI in CI - Create wrapper scripts instead of symlinks for AppImage binaries - Set LD_LIBRARY_PATH, QT_PLUGIN_PATH for GUI mode - Add diagnostic output to identify startup failures * fix: Use apprun for GUI tests in CI * fix: Improving Xvfb tests * fix: GUI tests worlk * chore: remove invalid --no-splash comments * fix: ARM64 architecture support and other fixes * fix: cleanup * test: just commands test suite * test: improve just command tests * fix: more general improvements * fix: more cleanup * fix: more updates * fix: small tweaks --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
317 lines
11 KiB
YAML
317 lines
11 KiB
YAML
# Pre-commit hooks configuration
|
|
# https://pre-commit.com/
|
|
|
|
default_language_version:
|
|
python: python3.11 # Must match FreeCAD's bundled Python version
|
|
|
|
repos:
|
|
# ==========================================================================
|
|
# General File Hygiene
|
|
# ==========================================================================
|
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
rev: v6.0.0
|
|
hooks:
|
|
- id: trailing-whitespace
|
|
exclude: \.md$ # Allow trailing spaces in markdown for line breaks
|
|
- id: end-of-file-fixer
|
|
exclude: \.safety-project\.ini$ # Safety CLI manages its own formatting
|
|
- id: check-xml
|
|
- id: check-yaml
|
|
args: [--unsafe]
|
|
- id: check-toml
|
|
- id: check-json
|
|
exclude: ^\.vscode/.*\.json$ # VS Code uses JSONC (JSON with Comments)
|
|
- id: check-added-large-files
|
|
args: [--maxkb=1000]
|
|
- id: check-merge-conflict
|
|
- id: check-case-conflict
|
|
- id: check-symlinks
|
|
- id: check-executables-have-shebangs
|
|
- id: check-shebang-scripts-are-executable
|
|
- id: detect-private-key
|
|
- id: mixed-line-ending
|
|
args: [--fix=lf]
|
|
- id: no-commit-to-branch
|
|
args: [--branch, main, --branch, master]
|
|
- id: check-ast # Check Python syntax
|
|
types: [text]
|
|
files: \.(py|FCMacro)$
|
|
|
|
# JSON5/JSONC validation for VS Code config files (supports comments)
|
|
- repo: https://github.com/maresb/check-json5
|
|
rev: v1.0.1
|
|
hooks:
|
|
- id: check-json5
|
|
files: ^\.vscode/.*\.json$ # Only check VS Code JSONC files
|
|
|
|
# ==========================================================================
|
|
# Python - Linting and Formatting
|
|
# ==========================================================================
|
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
rev: v0.14.11
|
|
hooks:
|
|
- id: ruff
|
|
args: [--fix, --exit-non-zero-on-fix]
|
|
types_or: [python, text]
|
|
files: \.(py|FCMacro)$
|
|
- id: ruff-format
|
|
types_or: [python, text]
|
|
files: \.(py|FCMacro)$
|
|
|
|
# ==========================================================================
|
|
# Python - Type Checking
|
|
# ==========================================================================
|
|
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
rev: v1.19.1
|
|
hooks:
|
|
- id: mypy
|
|
additional_dependencies:
|
|
- pydantic>=2.10.0
|
|
- pydantic-settings>=2.7.0
|
|
- mcp>=1.25.0
|
|
# Note: mypy doesn't natively support .FCMacro, so we skip those files
|
|
# FCMacro files are checked by ruff and bandit instead
|
|
args: [--config-file=pyproject.toml]
|
|
|
|
# ==========================================================================
|
|
# Python - Security Scanning
|
|
# ==========================================================================
|
|
- repo: https://github.com/PyCQA/bandit
|
|
rev: 1.9.2
|
|
hooks:
|
|
- id: bandit
|
|
args: [-c, pyproject.toml, -r, src, macros]
|
|
additional_dependencies: ["bandit[toml]"]
|
|
types: [text]
|
|
files: \.(py|FCMacro)$
|
|
|
|
# Safety - Dependency vulnerability scanning
|
|
# Checks installed packages against known security vulnerabilities
|
|
# Local: Requires free safetycli.com account. Run `uv run safety auth` first.
|
|
# CI: Uses SAFETY_API_KEY secret passed via environment variable.
|
|
# Config: .safety-policy.yml (excludes .venv, node_modules, etc.)
|
|
- repo: local
|
|
hooks:
|
|
- id: safety
|
|
name: safety (dependency vulnerabilities)
|
|
entry: uv run safety scan --policy-file .safety-policy.yml --detailed-output
|
|
language: system
|
|
pass_filenames: false
|
|
files: ^(pyproject\.toml|uv\.lock|\.safety-policy\.yml)$
|
|
|
|
# ==========================================================================
|
|
# Secrets Detection - Multi-Layer Approach
|
|
# ==========================================================================
|
|
|
|
# Layer 1: Gitleaks - Fast, comprehensive secrets scanner
|
|
# Scans git history and current files using regex patterns
|
|
# Config: .gitleaks.toml
|
|
- repo: https://github.com/gitleaks/gitleaks
|
|
rev: v8.30.0
|
|
hooks:
|
|
- id: gitleaks
|
|
name: gitleaks (secrets scanner)
|
|
args: [--config, .gitleaks.toml, --verbose]
|
|
|
|
# Layer 2: detect-secrets - Yelp's enterprise-grade secrets detector
|
|
# Uses baseline file to track known/approved secrets
|
|
# Config: .secrets.baseline
|
|
- repo: https://github.com/Yelp/detect-secrets
|
|
rev: v1.5.0
|
|
hooks:
|
|
- id: detect-secrets
|
|
name: detect-secrets (baseline scan)
|
|
args:
|
|
- --baseline
|
|
- .secrets.baseline
|
|
- --exclude-files
|
|
- '\.secrets\.baseline$'
|
|
- --exclude-files
|
|
- '\.gitleaks\.toml$'
|
|
- --exclude-files
|
|
- 'uv\.lock$'
|
|
- --exclude-files
|
|
- 'poetry\.lock$'
|
|
- --exclude-files
|
|
- 'package-lock\.json$'
|
|
|
|
# Layer 3: TruffleHog - Deep secrets scanner with verification
|
|
# Verifies secrets are actually valid (e.g., tests AWS keys)
|
|
# Note: TruffleHog has wasm/go-re2 panic bugs in GitHub Actions.
|
|
# It's skipped in CI (via SKIP env var) but runs locally.
|
|
# See: https://github.com/trufflesecurity/trufflehog/issues/3321
|
|
- repo: https://github.com/trufflesecurity/trufflehog
|
|
rev: v3.92.4
|
|
hooks:
|
|
- id: trufflehog
|
|
name: trufflehog (verified secrets scan)
|
|
args:
|
|
- --no-update
|
|
exclude: '(^|/)uv\.lock$|\.secrets\.baseline$'
|
|
|
|
# ==========================================================================
|
|
# Markdown Linting
|
|
# ==========================================================================
|
|
|
|
# markdownlint-cli2 - Comprehensive markdown linter with auto-fix
|
|
# Config: .markdownlint.yaml
|
|
- repo: https://github.com/DavidAnson/markdownlint-cli2
|
|
rev: v0.20.0
|
|
hooks:
|
|
- id: markdownlint-cli2
|
|
name: markdownlint (linter)
|
|
args: [--fix]
|
|
|
|
# Tertiary: md-toc - Table of contents generator
|
|
# Automatically updates TOC between <!--TOC--> markers
|
|
- repo: https://github.com/frnmst/md-toc
|
|
rev: 9.0.0
|
|
hooks:
|
|
- id: md-toc
|
|
name: md-toc (table of contents)
|
|
args: ["-p", "github", "-l", "6"] # GitHub parser, max 6 levels
|
|
files: ^(README|docs/development/architecture-detailed)\.md$
|
|
|
|
# ==========================================================================
|
|
# Spell Checking
|
|
# ==========================================================================
|
|
- repo: https://github.com/codespell-project/codespell
|
|
rev: v2.4.1
|
|
hooks:
|
|
- id: codespell
|
|
additional_dependencies:
|
|
- tomli
|
|
args:
|
|
- --ignore-words
|
|
- .codespell-ignore-words.txt
|
|
- --skip
|
|
- "*.lock,*.json,.secrets.baseline"
|
|
|
|
# ==========================================================================
|
|
# Configuration Validation
|
|
# ==========================================================================
|
|
- repo: https://github.com/abravalheri/validate-pyproject
|
|
rev: v0.24.1
|
|
hooks:
|
|
- id: validate-pyproject
|
|
|
|
- repo: https://github.com/python-jsonschema/check-jsonschema
|
|
rev: 0.36.0
|
|
hooks:
|
|
- id: check-github-workflows
|
|
name: validate GitHub workflows
|
|
- id: check-dependabot
|
|
name: validate Dependabot config
|
|
|
|
# ==========================================================================
|
|
# GitHub Actions Linting
|
|
# ==========================================================================
|
|
- repo: https://github.com/rhysd/actionlint
|
|
rev: v1.7.10
|
|
hooks:
|
|
- id: actionlint
|
|
name: actionlint (GitHub Actions linter)
|
|
|
|
# ==========================================================================
|
|
# Shell Script Linting
|
|
# ==========================================================================
|
|
- repo: https://github.com/shellcheck-py/shellcheck-py
|
|
rev: v0.11.0.1
|
|
hooks:
|
|
- id: shellcheck
|
|
name: shellcheck (shell linter)
|
|
args: [--severity=warning]
|
|
|
|
# ==========================================================================
|
|
# Dockerfile Linting
|
|
# ==========================================================================
|
|
# hadolint-py: Python wrapper that auto-downloads hadolint binary
|
|
# No Docker or system installation required
|
|
- repo: https://github.com/AleksaC/hadolint-py
|
|
rev: v2.14.0
|
|
hooks:
|
|
- id: hadolint
|
|
|
|
# ==========================================================================
|
|
# Dockerfile Security Scanning (Misconfigurations)
|
|
# ==========================================================================
|
|
# Uses mise-managed trivy binary instead of pre-commit repo.
|
|
# This avoids case-conflicting git refs in pre-commit-trivy repo that break
|
|
# `pre-commit autoupdate` on case-insensitive filesystems (macOS).
|
|
# Version is managed in .mise.toml - update with `mise upgrade trivy`
|
|
- repo: local
|
|
hooks:
|
|
- id: trivy
|
|
name: trivy (Dockerfile misconfig)
|
|
entry: trivy
|
|
args:
|
|
- config
|
|
- --severity
|
|
- HIGH,CRITICAL
|
|
- --exit-code
|
|
- "1"
|
|
language: system
|
|
files: (Dockerfile|\.dockerfile)$
|
|
pass_filenames: true
|
|
|
|
# ==========================================================================
|
|
# Documentation Build Validation
|
|
# ==========================================================================
|
|
- repo: local
|
|
hooks:
|
|
- id: mkdocs-build
|
|
name: mkdocs (documentation build)
|
|
entry: uv run mkdocs build --strict
|
|
language: system
|
|
pass_filenames: false
|
|
files: ^(docs/|mkdocs\.yaml)
|
|
|
|
# ==========================================================================
|
|
# Commit Message Linting
|
|
# ==========================================================================
|
|
- repo: https://github.com/commitizen-tools/commitizen
|
|
rev: v4.11.1
|
|
hooks:
|
|
- id: commitizen
|
|
name: commitizen (commit format)
|
|
stages: [commit-msg]
|
|
|
|
# ==========================================================================
|
|
# AI Code Review (Local Only)
|
|
# ==========================================================================
|
|
# CodeRabbit CLI - AI-powered code review
|
|
# https://www.coderabbit.ai/cli
|
|
#
|
|
# SETUP REQUIRED:
|
|
# 1. Install: just coderabbit::install
|
|
# 2. Authenticate: just coderabbit::login
|
|
#
|
|
# USAGE:
|
|
# - Run manually: just coderabbit::review
|
|
# - Run via pre-commit: uv run pre-commit run coderabbit --all-files
|
|
#
|
|
# NOTE: This hook uses 'manual' stage so it doesn't run automatically.
|
|
# The CodeRabbit GitHub App already reviews PRs, so CLI is for local use.
|
|
# Rate limits: Free=1/hour, Lite=1/hour, Pro=5/hour
|
|
- repo: local
|
|
hooks:
|
|
- id: coderabbit
|
|
name: coderabbit (AI code review)
|
|
entry: coderabbit review --plain --type uncommitted
|
|
language: system
|
|
pass_filenames: false
|
|
stages: [manual]
|
|
verbose: true
|
|
|
|
# ==========================================================================
|
|
# CI Configuration
|
|
# ==========================================================================
|
|
ci:
|
|
autoupdate_schedule: monthly
|
|
autoupdate_commit_msg: "chore(deps): update pre-commit hooks"
|
|
skip:
|
|
- mypy # Needs dependencies installed
|
|
- trivy # Uses mise-managed binary (local repo)
|
|
- trufflehog # Can be slow in CI
|
|
- coderabbit # GitHub App handles PR reviews; CLI is for local use
|