Files
boilerplates/CONTRIBUTING.md
T
Christian Lempa f856aef030 Release v0.1.0 (#1562)
* updated version number

* chore(config): apply ruff formatting to release/v0.1.0

- Run ruff check --fix to remove unused imports and fix code issues
- Run ruff format to apply PEP 8 formatting (4 spaces for Python)
- Fix TemplateRenderError import and remove unused defaults variable

* fix(core): required sections ignore toggle and always enabled

- Modified VariableSection.is_enabled() to return True for required sections
- Hide toggle variables from display in required sections
- Add warnings when attempting to disable required section toggles via config or CLI
- Updated pihole template with better defaults and required network section

Fixes #1411

* feat(core): comprehensive improvements to variable dependencies and prompts

Major enhancements:
- Sort variables by dependencies within sections for logical display/prompt order
- Skip prompting for variables with unsatisfied needs
- Hide toggle variables in required sections from display
- Use standard prompt logic for toggle variables (supports extra text)
- Add warnings when setting values for variables with unsatisfied needs via config/CLI
- Fix section merge to preserve needs from module spec when template doesn't override
- Support semicolon-separated multiple AND conditions in needs syntax
  Example: needs: 'traefik_enabled=true;network_mode=bridge,macvlan'

Fixes and improvements for issues with:
- Required sections incorrectly showing as disabled
- Variables displayed/prompted in illogical order
- Macvlan variables prompted when network_mode=bridge
- Toggle descriptions not showing extra text
- Section needs being cleared during template merge

Related to #1411

* fix(pihole): handle host network mode correctly

Remove dependency on network_enabled toggle since Network section is now required.
Template now directly checks network_mode value for host/bridge/macvlan logic.

* feat(core): remove Jinja2 default() filter extraction (#1410) (#1416)

- Removed _extract_jinja_default_values() method from Template class
- Removed merge logic for Jinja2 defaults in variables property
- Fixed validate command to handle 3-tuple from LibraryManager.find()
- All defaults must now be explicitly defined in template/module specs
- Updated CHANGELOG.md with removal notice

* feat(core): add --var-file support for loading variables from YAML (#1331)

- Added _load_var_file() method to parse YAML variable files
- Added _apply_var_file() method to apply var file variables with proper precedence
- Added --var-file/-f parameter to generate command
- Supports both flat (var: value) and nested (section: {var: value}) YAML structures
- Proper precedence chain: module < template < config < var-file < CLI --var
- Comprehensive error handling for file not found, invalid YAML, and type errors
- Updated documentation and examples
- All existing templates validate successfully

* update changelog

* docs(quality): add comprehensive code quality analysis

* refactor(collection): add iter_active_sections() helper method

- Adds centralized iterator for sections with proper filtering
- Eliminates duplicate iteration logic in prompt.py
- Supports include_disabled and include_unsatisfied flags
- Reduces code duplication by ~30 lines

Related to #1364 (High Priority #1)

* refactor(module): deduplicate template loading logic

- Adds _load_all_templates() helper method with optional filtering
- Updates list(), search(), and validate() to use centralized helper
- Eliminates ~90 lines of duplicate code
- Improves maintainability with single source of truth for template loading

Related to #1364 (High Priority #3)

* docs: add comprehensive naming and API improvement analysis

- Identifies 6 major improvement opportunities
- Prioritizes by impact (High/Medium/Low)
- Proposes CRUD standardization across ConfigManager
- Recommends consolidating duplicate methods
- Includes breaking change mitigation strategies
- Estimates +1.0 code quality score improvement

Related to #1364

* docs: remove analysis documents (not needed for PR)

* refactor(display): split DisplayManager into specialized managers

- Refactored monolithic DisplayManager (971 lines) into 4 specialized managers:
  * VariableDisplayManager - variable and section rendering
  * TemplateDisplayManager - template display and file trees
  * StatusDisplayManager - status messages and errors
  * TableDisplayManager - all table types

- Maintained 100% backward compatibility via delegation methods
- All existing code works without modifications
- Follows Single Responsibility Principle
- Updated AGENTS.md with new architecture documentation

Previous improvements included in this commit:
- Renamed display methods for consistency (display_template, display_section)
- Reduced variable map lookups in reset_disabled_bool_variables()
- Improved exception hierarchy (VariableValidationError, VariableError)
- Extracted error context building to TemplateErrorHandler class
- Fixed VariableSection forward reference in variable.py

All ruff checks pass. Tested with compose list and compose show commands.

Relates to #1364

* refactor(display): complete optimization with settings, helpers, and method splitting

Major improvements to display.py architecture:

1. DisplaySettings Class (65 lines):
   - Centralized all hardcoded values (colors, styles, layouts, text labels)
   - Easy customization via single class
   - Constants: colors, styles, padding, sizes, labels, etc.

2. Helper Methods in DisplayManager:
   - _format_library_display() - eliminates duplicate library formatting
   - _truncate_value() - centralized value truncation logic
   - _format_file_size() - human-readable size formatting (B, KB, MB)

3. Split render_variables_table() (91 → 56 lines):
   - Extracted _render_section_header() (20 lines)
   - Extracted _render_variable_row() (35 lines)
   - Main method now cleaner coordinator logic

4. Updated All Managers to Use Settings:
   - VariableDisplayManager: uses all style/color/text constants
   - TemplateDisplayManager: uses settings and _format_library_display()
   - StatusDisplayManager: uses color scheme constants
   - TableDisplayManager: uses helpers and settings throughout

5. Removed Code Duplication:
   - Library display logic (was in 2 places)
   - File size formatting (was in 1 place)
   - Value truncation (was in 2 places with different logic)
   - Sensitive masking (consolidated)

Benefits:
- Single source of truth for all display configuration
- Easy to theme/customize CLI appearance
- Better testability (helpers can be unit tested)
- Reduced duplication
- More maintainable (change color scheme in one place)

File stats: 1343 → 1337 lines (-6 lines despite adding 65-line settings class)
All tests pass: compose list, compose show traefik
Linting: ruff checks passed

Relates to #1364

* refactor(display): split display.py into separate manager modules

- Created cli/core/display/ package structure
- Split DisplayManager into specialized managers:
  - VariableDisplayManager: variable rendering
  - TemplateDisplayManager: template display
  - StatusDisplayManager: status messages and errors
  - TableDisplayManager: table rendering
- Moved DisplaySettings and IconManager to __init__.py
- Maintained backward compatibility through delegation methods
- All imports remain unchanged (from cli.core.display import DisplayManager)
- Follows Single Responsibility Principle for better maintainability

* docs(changelog): add display module refactoring entry

* refactor(display): separate DisplaySettings, IconManager, and DisplayManager into individual files

- Moved DisplaySettings to display_settings.py
- Moved IconManager to icon_manager.py
- Moved DisplayManager to display_manager.py
- Updated __init__.py to only handle imports/exports (27 lines vs 526)
- Each file now has single, clear responsibility
- Better adherence to Single Responsibility Principle
- Updated AGENTS.md with new structure and ruff formatting instructions

* style: apply ruff formatting to entire codebase

* fix(display): simplify section disabled label logic and fix table row styling

- Fixed table row styling being added as 5th column instead of style parameter
- Simplified disabled label logic: show (disabled) if section has toggle and is not enabled
- Removed redundant has_dependencies parameter from _render_section_header
- Now all disabled toggle sections consistently show (disabled) label

* refactor(display): standardize table header styling across CLI

- Enforce consistent STYLE_TABLE_HEADER ('bold blue') for all tables via _print_table()
- Remove optional style parameter logic from table header styling
- Remove separate heading() calls before tables for cleaner output
- Ensure uniform table appearance throughout compose, repo, and config commands

* updated changelog

* updated changelog and description for code quality

* feature(ci): Add Ruff linting configuration and GitHub Actions workflow

- Add Ruff configuration to pyproject.toml with PEP 8 compliance
  - Line length: 88 characters
  - Indentation: 4 spaces (PEP 8 standard)
  - Enable comprehensive rule sets (pycodestyle, pyflakes, isort, pylint, etc.)
- Create .github/workflows/codequality-ruff.yaml
  - Runs on PRs to main and pushes to main/release/* branches
  - Checks both linting and formatting (blocking)
- Fix yamllint errors in config.yaml and release workflow
- Remove whitespace from table_display.py

Related to #1318

* fixed some ruff errors

* feat(compose): add --var and --var-file support to show command (#1421)

- Add --var and --var-file options to show command
- Apply same variable precedence as generate command
- Update CHANGELOG.md with feature description
- Users can now preview variable overrides before generating files

* started developing new functions

* critical updates to templates

* updates to the template tags

* n8n template preparation

* traefik security headers

* version pinning for twingate-connector

* template fix

* recent template updates

* traefik template publish

* n8n tags

* prometheus update

* fix(compose): use CF_API_TOKEN_FILE for Cloudflare API token in Traefik

* fix bug in schema 1.1

* renovate draft template

* make updates to renovate

* code quality updates

* feat: Add schema 1.2 with dedicated volume and resources sections

- Add spec_v1_2.py with new volume and resources sections
- Volume section: Replaces swarm_volume_* vars, works universally
- Resources section: CPU/memory limits for production deployments
- Ports section: Add ports_http and ports_https variables
- Update compose module to support schema 1.2
- Create new v2 archetypes:
  - service-volumes-v2.j2: Uses volume_mode
  - volumes-v2.j2: Top-level volumes with new section
  - service-resources-v1.j2: Resource limits

Related: #1519

* fixed #1522 and archetype improvements

* fixed issues in archetypes

* prepare other templates

* prepare other templates

* fix(variable): correct email validation regex

Fixed malformed email validation regex that was matching literal
backslash-s characters instead of whitespace. Changed from
r"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$" to
r"^[^@\s]+@[^@\s]+\.[^@\s]+$"

Fixes #1481

* fix(variable): replace regex with RFC-compliant email validation

Replaced regex-based email validation with email-validator library.
Regex cannot properly validate emails per RFC 5322/5321 - it fails
on valid addresses like "John Doe"@example.com, user+tag@example.com.

Changes:
- Added email-validator>=2.0.0 dependency to pyproject.toml
- Removed EMAIL_REGEX constant
- Updated _convert_email() to use validate_email() function
- Returns normalized email addresses
- Provides better error messages for invalid emails

Fixes #1481

* prepare migration for other modules

* ruff fixes

* fix(template): gracefully handle missing 'needs' dependencies

When a section's 'needs' dependency references a non-existent section,
the CLI now logs a warning instead of raising an error. This allows
templates to be modified without breaking when dependencies are removed.

Closes #1428

* fix(template): skip empty files during generation (#1518) (#1530)

* big update

* docs: add markdown support to changelog (#1471)

* feature(install): add auto-install for dependencies on Linux and macOS

- Auto-detects OS and Linux distribution
- Installs python3, pip, git, and pipx if missing
- Supports Ubuntu, Debian, Fedora, RHEL, CentOS, Rocky, AlmaLinux, openSUSE, Arch, Manjaro, Alpine, and macOS
- Adds --no-auto-install flag to skip automatic installation
- Improves error messages with clear installation instructions

Closes #1517

* fix(install): handle PEP 668 externally-managed environments

- Try installing pipx from system packages first
- Fall back to pip with --break-system-packages flag for PEP 668
- Add pipx package names for each distro
- Improve pipx ensurepath handling

* fix(install): improve pipx installation error handling

- Properly suppress stderr when trying system package installation
- Better conditional logic for pip installation with --break-system-packages
- Add success logging for each installation method

* fix(install): suppress pip error output by checking success

- Use grep to check for 'Successfully installed' instead of exit codes
- This suppresses PEP 668 error output when trying pip methods
- Provides helpful error message suggesting manual apt install

* fix(install): handle distros without VERSION_ID in os-release

- Arch Linux and some other rolling distros don't have VERSION_ID
- Use parameter expansion to set empty default

* fix(install): add support for archarm distribution

- OrbStack Arch Linux uses 'archarm' as distribution ID
- Add it to the Arch Linux case pattern

* chore: add build/ and dist/ to .gitignore

- Ignore Python build artifacts
- Ignore distribution packages

* fix: add 'boilerplates' prefix to command suggestions in help text

- Update help messages to show 'boilerplates repo update' instead of 'repo update'
- Makes it clearer that commands should be run with the boilerplates CLI prefix
- Addresses user feedback from issue #1517

* feat(gitlab): integrate improvements from template/1372 with schema 1.2

- Add .env.j2 for environment variables (root password)
- Add container_hostname, root_email, root_password variables
- Add initial root user configuration to gitlab.rb
- Add default_theme, default_color_mode, disable_usage_data settings
- Improve template description and next_steps documentation
- Add env_file and swarm configs/secrets support
- Update to use schema 1.2 volume section (volume_mode instead of swarm_volume_*)
- Fix registry port from 5678 to standard 5000
- Add swarm placement constraints support
- Update ports section to include ports_https

* archetype validation testing

* schema1.2-traefik_domain

* feat(traefik): add multiple DNS challenge providers

- Add support for Porkbun, GoDaddy, DigitalOcean, Route53 (AWS), Azure, GCP, and Namecheap
- Add provider-specific credential variables with conditional visibility
- Support both standard and Docker Swarm modes for all providers
- Update environment variable handling for each provider

Closes #1478

* fix repo and changelog

* feature(docs): add GitHub Action to auto-generate wiki variable documentation

- Created .github/scripts/generate_wiki_docs.py script

- Generates markdown documentation for all module variables

- Uses latest schema version for each module

- Created workflow to auto-update wiki on schema changes

- Workflow triggers on changes to module specs and script

- Runs on release/v0.1.0 branch (will switch to main later)

Relates to #1316

* docs(wiki): add prominent Contributing section with CONTRIBUTING.md link

- Added Contributing section in Developer Documentation area

- Links directly to CONTRIBUTING.md in repository

- Highlights key points: CLI requires Discord, templates welcome PRs

Relates to #1316

* Documentation

* template updates

* template updates

* fix(compose): add Loki batching configuration to Alloy template

- Add batch_wait (5s) and batch_size (1MB) to reduce request volume
- Add max_backoff (5m) and min_backoff (500ms) for retry reliability
- Prevents ingestion rate limit errors with multiple Alloy instances
- Reduces HTTP overhead and improves compression efficiency

Fixes #1556

* updates

* update schema

* update

* fix ruff

* update wiki

* fix wiki

* fix wiki

* refactor(workflows): rename and extend wiki sync workflow

- Rename docs-update-wiki-variables.yaml to docs-update-wiki.yaml
- Add syncing of static wiki pages from .wiki/ directory
- Add .wiki/** to workflow triggers
- Improve commit message and workflow description

* fix(workflows): improve wiki branch detection for new wikis

- Add fallback to current branch if symbolic ref doesn't exist
- Prevents 'invalid refspec' error on newly created wikis

* fix(workflows): simplify wiki workflow by assuming master branch

- Remove complex branch detection that was causing empty variable issues
- Hardcode master branch (GitHub wikis default)
- Remove unnecessary initialization check (wiki must exist for checkout to succeed)
- Simplify commit message

* update email settings

* fix wiki

* big template updates 1

* big template updates 1

* template refactoring 2

* working on templates 2

* working on templates 3

* refactoring updates

* release-test-1

* release-test-2

* fix(templates): resolve yamllint errors - add missing newlines and remove duplicate key

* fix(templates): resolve yamllint line-length warnings in descriptions
2025-12-10 16:02:30 +01:00

271 lines
6.6 KiB
Markdown

# Contributing to Boilerplates
Thank you for your interest in contributing to the Boilerplates project! This document provides guidelines and instructions for contributing.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [How to Contribute](#how-to-contribute)
- [CLI Development](#cli-development)
- [Template Contributions](#template-contributions)
- [Development Setup](#development-setup)
- [Code Standards](#code-standards)
- [Testing Guidelines](#testing-guidelines)
- [Pull Request Process](#pull-request-process)
## Code of Conduct
Be respectful and constructive in all interactions. We're here to build great tools together.
## How to Contribute
### CLI Development
**IMPORTANT:** Any changes to the CLI application (`cli/` directory) require coordination.
**Before making CLI changes:**
1. Join the [Discord server](https://christianlempa.de/discord)
2. Reach out to discuss your proposed changes
3. Wait for approval before opening a PR
**Rationale:** The CLI architecture is complex and tightly integrated. Coordinating changes ensures consistency and prevents conflicts.
### Template Contributions
Template contributions are welcome and encouraged! You can:
- Add new templates to `library/`
- Improve existing templates
- Fix bugs in templates
- Update template documentation
**Process:**
1. Read the [Developer Documentation](../../wiki/Developers) in the Wiki
2. Create a new branch: `feature/###-template-name` or `problem/###-fix-description`
3. Add or modify templates following the structure in `library/`
4. Test your template thoroughly
5. Open a pull request
**No prior approval needed** for template contributions, but feel free to open an issue first to discuss larger changes.
## Development Setup
### Prerequisites
- Python 3.10 or higher
- Git
- pipx (recommended) or pip
### Installation
1. Clone the repository:
```bash
git clone https://github.com/ChristianLempa/boilerplates.git
cd boilerplates
```
2. Create a virtual environment:
```bash
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```
3. Install dependencies:
```bash
pip install -e .
```
4. Run the CLI in development mode:
```bash
python3 -m cli --help
```
### Development Commands
```bash
# Run CLI with debug logging
python3 -m cli --log-level DEBUG compose list
# Test template generation
python3 -m cli compose generate template-name --dry-run
# Validate templates
python3 -m cli compose validate
```
## Code Standards
### Python Style Guide
- Follow PEP 8 conventions
- Use **2-space indentation** (project standard)
- Maximum line length: 100 characters
- Use type hints where appropriate
### Naming Conventions
- **Files:** lowercase with underscores (`variable_display.py`)
- **Classes:** PascalCase (`VariableCollection`, `DisplayManager`)
- **Functions/Methods:** snake_case (`render_template`, `get_spec`)
- **Constants:** UPPER_SNAKE_CASE (`DEFAULT_TIMEOUT`, `MAX_RETRIES`)
- **Private methods:** prefix with underscore (`_parse_section`)
### Comment Anchors
Use standardized comment anchors for important notes:
```python
# TODO: Implement feature X
# FIXME: Bug in validation logic
# NOTE: This is a workaround for issue #123
# LINK: https://docs.python.org/3/library/typing.html
```
### DisplayManager Usage
**CRITICAL RULE:**
- NEVER use `console.print()` outside of display manager classes
- NEVER import `Console` from `rich.console` except in display manager classes
- ALWAYS use `display.display_*()` methods for ALL output
```python
# GOOD
display = DisplayManager()
display.display_success("Template generated successfully")
# BAD
from rich.console import Console
console = Console()
console.print("Template generated") # Don't do this!
```
### Docstrings
Use docstrings for all public classes and methods:
```python
def render_template(self, template: Template, template_id: str) -> None:
"""Render a complete template display.
Args:
template: The Template object to render
template_id: The template identifier
"""
pass
```
## Testing Guidelines
### Linting and Formatting
**REQUIRED before committing:**
```bash
# YAML files
yamllint library/
# Python code - check and auto-fix
ruff check --fix .
# Python code - format
ruff format .
```
### Validation Commands
```bash
# Validate all templates
python3 -m cli compose validate
# Validate specific template
python3 -m cli compose validate template-name
# Validate with semantic checks
python3 -m cli compose validate --semantic
```
### Manual Testing
Before submitting a PR, test your changes:
```bash
# Test template generation
python3 -m cli compose generate your-template --dry-run
# Test interactive mode
python3 -m cli compose generate your-template
# Test non-interactive mode
python3 -m cli compose generate your-template output-dir \
--var service_name=test \
--no-interactive
```
## Pull Request Process
### Branch Naming
- **Features:** `feature/###-description` (e.g., `feature/1234-add-nginx-template`)
- **Bug fixes:** `problem/###-description` (e.g., `problem/1235-fix-validation`)
### Commit Messages
Follow the format: `type(scope): subject`
**Types:**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `refactor`: Code refactoring
- `test`: Adding tests
- `chore`: Maintenance tasks
**Examples:**
```
feat(compose): add nginx template
fix(display): correct variable rendering for enum types
docs(wiki): update installation instructions
refactor(template): simplify Jinja2 rendering logic
```
### PR Checklist
Before submitting a pull request:
- [ ] Code follows style guidelines (run `ruff check` and `ruff format`)
- [ ] YAML files pass `yamllint`
- [ ] All templates validate successfully
- [ ] Changes are tested manually
- [ ] Commit messages follow conventions
- [ ] PR description explains the changes
- [ ] Related issues are referenced (e.g., "Closes #1234")
### PR Review
- PRs require approval before merging
- Address review comments promptly
- Keep PRs focused and reasonably sized
- Squash commits if requested
## Issue Labels
When creating issues, use appropriate labels:
- `feature` - New feature requests
- `problem` - Bug reports
- `discussion` - General discussions
- `question` - Questions about usage
- `documentation` - Documentation improvements
## Getting Help
- Check the [Wiki](../../wiki) for documentation
- Join [Discord](https://christianlempa.de/discord) for discussions
- Open an issue for bugs or feature requests
- Watch [YouTube tutorials](https://www.youtube.com/@christianlempa)
## License
By contributing, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to Boilerplates!