Explorar el Código

release(v0.2.0-2): ship follow-up fixes

xcad hace 2 meses
padre
commit
8b73479d9b

+ 29 - 9
AGENTS.md

@@ -4,7 +4,12 @@ Guidance for AI Agents working with this repository.
 
 ## Project Overview
 
-A sophisticated collection of infrastructure templates (boilerplates) with a Python CLI for management. Supports Terraform, Docker, Ansible, Kubernetes, etc. Built with Typer (CLI) and Jinja2 (templating).
+A Python CLI for managing infrastructure boilerplates, plus archetypes and template-loading logic. Built with Typer (CLI) and Jinja2 (templating).
+
+**Important library location note:**
+- The canonical template library does **not** live in this repository for modern development.
+- The checked-in `library/` directory here is **legacy/backward-compatibility content for versions older than `0.2.0`**.
+- For `0.2.0+`, the active template library lives in the separate GitHub repository `boilerplates-library`.
 
 ## Development Setup
 
@@ -35,12 +40,17 @@ For detailed information about testing boilerplates in a production-like environ
 
 ### Linting and Formatting
 
-Should **always** happen before pushing anything to the repository.
+Should **always** happen before pushing anything to the repository and before making a release.
 
 - Use `ruff` for Python code:
   - `ruff check --fix .` - Check and auto-fix linting errors (including unused imports)
   - `ruff format .` - Format code according to style guidelines
   - Both commands must be run before committing
+- Minimum pre-release verification:
+  - `ruff check --fix .`
+  - `ruff format .`
+  - `python3 -m pytest`
+- Agents should treat these as release gates, not optional cleanup.
 
 ### Project Management and Git
 
@@ -59,13 +69,9 @@ The project is stored in a public GitHub Repository, use issues, and branches fo
   - `cli/core/` - Core Components of the CLI application
   - `cli/modules/` - Modules implementing technology-specific functions
   - `cli/__main__.py` - CLI entry point, auto-discovers modules and registers commands
-- `library/` - Template collections organized by module
-  - `library/ansible/` - Ansible playbooks and configurations
-  - `library/compose/` - Docker Compose configurations
-  - `library/docker/` - Docker templates
-  - `library/kubernetes/` - Kubernetes deployments
-  - `library/packer/` - Packer templates
-  - `library/terraform/` - OpenTofu/Terraform templates and examples
+- `library/` - Legacy in-repo template content kept only for backward compatibility with versions older than `0.2.0`
+  - Do not treat this directory as the canonical source for new template work
+  - The active `0.2.0+` library is maintained in the separate GitHub repository `boilerplates-library`
 - `archetypes/` - Testing tool for template snippets (archetype development)
   - `archetypes/__init__.py` - Package initialization
   - `archetypes/__main__.py` - CLI tool entry point
@@ -103,6 +109,17 @@ The project is stored in a public GitHub Repository, use issues, and branches fo
 
 ### Modules
 
+**Currently supported kinds in code:**
+- `ansible`
+- `compose`
+- `helm`
+- `kubernetes`
+- `packer`
+- `swarm`
+- `terraform`
+
+These are the kinds supported by the registered CLI modules in `cli/modules/`. When answering "what kinds do we support?", prefer this code-level list over whatever legacy content happens to exist under `library/`.
+
 **Module Structure:**
 Modules can be either single files or packages:
 - **Single file**: `cli/modules/modulename.py` (for simple modules)
@@ -203,6 +220,8 @@ Older Python-based `spec_v*.py` files have been migrated to JSON. The module `__
 - Uses sparse-checkout to clone only template directories for git-based libraries (avoiding unnecessary files)
 - Supports two library types: **git** (synced from repos) and **static** (local directories)
 - Priority determined by config order (first = highest)
+- In this repository, the checked-in `library/` directory is legacy compatibility data only and should not be treated as the primary source for current template development
+- For current `0.2.0+` template work, use the external GitHub repository `boilerplates-library`
 
 **Library Types:**
 - `git`: Requires `url`, `branch`, `directory` fields
@@ -313,6 +332,7 @@ Templates are directory-based. Each template is a directory containing all the n
 **Key Architecture Points:**
 - Variable visibility is dynamic based on `needs` constraints (evaluated at prompt/render time)
 - Jinja2 templates support `{% include %}` and `{% import %}` for composition
+- Template loading can read configured libraries from disk, but the checked-in `library/` tree in this repo is legacy compatibility data, not the canonical `0.2.0+` library source
 
 ### Template Structure
 

+ 8 - 0
CHANGELOG.md

@@ -16,6 +16,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Default library migration now rewrites the built-in repository from `christianlempa/boilerplates` to `christianlempa/boilerplates-library`, with startup notices and legacy `/library` path fallback (#1762)
 - Variable definitions now use the `secret` type and nested `config` metadata for options, placeholders, sliders, and secret autogeneration across the runtime, schemas, and migrated template specs (#1767)
 
+## [0.2.0-2] - 2026-04-23
+
+### Fixed
+- Release workflow now publishes a tag-matching hotfix source archive such as `boilerplates-0.2.0-2.tar.gz` even when Python packaging normalizes the internal post-release version.
+
+### Changed
+- Clarified `AGENTS.md` guidance around the canonical template library location and required pre-release verification steps.
+
 ## [0.2.0-1] - 2026-04-23
 
 ### Fixed

+ 1 - 1
cli/__init__.py

@@ -2,6 +2,6 @@
 Boilerplates CLI - A sophisticated command-line tool for managing infrastructure boilerplates.
 """
 
-__version__ = "0.2.0-1"
+__version__ = "0.2.0-2"
 __author__ = "Christian Lempa"
 __description__ = "CLI tool for managing infrastructure boilerplates"

+ 6 - 1
cli/core/input/prompt_manager.py

@@ -121,7 +121,12 @@ class PromptHandler:
         default_value = variable.get_normalized_default()
         has_explicit_default = "default" in variable._explicit_fields or "value" in variable._explicit_fields
         has_applied_default = variable.origin in {"config", "var-file", "cli"}
-        if not has_explicit_default and not has_applied_default and not variable.autogenerated and not variable.is_required():
+        if (
+            not has_explicit_default
+            and not has_applied_default
+            and not variable.autogenerated
+            and not variable.is_required()
+        ):
             default_value = None
 
         # Add lock icon before default value for secret or autogenerated variables

+ 2 - 1
cli/core/module/base_commands.py

@@ -501,7 +501,8 @@ def generate_template(module_instance, config: GenerationConfig) -> None:  # noq
                 total_files, overwrite_files, size_str = dry_run_stats
                 if used_implicit_dry_run_destination:
                     display.success(
-                        f"Dry run complete: boilerplate rendered successfully ({total_files} files, {size_str}, preview only)"
+                        "Dry run complete: boilerplate rendered successfully "
+                        f"({total_files} files, {size_str}, preview only)"
                     )
                 elif overwrite_files > 0:
                     display.warning(

+ 2 - 1
pyproject.toml

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
 
 [project]
 name = "boilerplates"
-version = "0.2.0-1"
+version = "0.2.0-2"
 description = "CLI tool for managing infrastructure boilerplates"
 readme = "README.md"
 requires-python = ">=3.9"
@@ -93,6 +93,7 @@ line-ending = "lf"
 # CLI command functions need many parameters for command-line arguments
 "cli/core/module/base_module.py" = ["PLR0913"]  # generate() needs all CLI options
 "cli/core/repo.py" = ["PLR0913"]                # add() needs all library config options
+"tests/test_repo.py" = ["PLR0913", "ARG001"]   # monkeypatched repo helpers mirror production call signatures
 
 [tool.pytest.ini_options]
 testpaths = ["tests"]

+ 19 - 10
tests/test_base_commands.py

@@ -7,14 +7,26 @@ from types import SimpleNamespace
 from cli.core.module.base_commands import GenerationConfig, generate_template, list_templates
 
 
+def _noop(*_args, **_kwargs) -> None:
+    return None
+
+
+def _raise_destination_prompt(slug: str):
+    raise AssertionError(f"prompt_generation_destination called for {slug}")
+
+
+def _raise_output_check(*_args, **_kwargs):
+    raise AssertionError("check_output_directory should not run")
+
+
 class _DisplayCapture:
     def __init__(self) -> None:
         self.lines: list[str] = []
         self.templates = SimpleNamespace(
-            render_template_header=lambda *args, **kwargs: None,
-            render_file_tree=lambda *args, **kwargs: None,
+            render_template_header=_noop,
+            render_file_tree=_noop,
         )
-        self.variables = SimpleNamespace(render_variables_table=lambda *args, **kwargs: None)
+        self.variables = SimpleNamespace(render_variables_table=_noop)
 
     def text(self, value: str, style: str | None = None) -> None:
         del style
@@ -74,18 +86,15 @@ def test_generate_template_dry_run_skips_destination_prompt_and_overwrite_check(
     template = SimpleNamespace(id="whoami", slug="whoami")
     module_instance = SimpleNamespace(name="compose", display=display)
 
-    monkeypatch.setattr("cli.core.module.base_commands._prepare_template", lambda *args, **kwargs: template)
+    monkeypatch.setattr("cli.core.module.base_commands._prepare_template", lambda *_args, **_kwargs: template)
     monkeypatch.setattr(
         "cli.core.module.base_commands._render_template",
-        lambda *args, **kwargs: ({"compose.yaml": "services:\n"}, {}),
-    )
-    monkeypatch.setattr(
-        "cli.core.module.base_commands.prompt_generation_destination",
-        lambda slug: (_ for _ in ()).throw(AssertionError(f"prompt_generation_destination called for {slug}")),
+        lambda *_args, **_kwargs: ({"compose.yaml": "services:\n"}, {}),
     )
+    monkeypatch.setattr("cli.core.module.base_commands.prompt_generation_destination", _raise_destination_prompt)
     monkeypatch.setattr(
         "cli.core.module.base_commands.check_output_directory",
-        lambda *args, **kwargs: (_ for _ in ()).throw(AssertionError("check_output_directory should not run")),
+        _raise_output_check,
     )
 
     generate_template(

+ 3 - 1
tests/test_repo.py

@@ -62,7 +62,9 @@ def test_clone_or_pull_repo_replaces_checkout_after_diverged_pull(monkeypatch, t
 
     clone_calls: list[str] = []
 
-    monkeypatch.setattr(repo, "_get_repo_remote_url", lambda _target_path: "git@github.com:ChristianLempa/boilerplates-library.git")
+    monkeypatch.setattr(
+        repo, "_get_repo_remote_url", lambda _target_path: "git@github.com:ChristianLempa/boilerplates-library.git"
+    )
     monkeypatch.setattr(
         repo,
         "_pull_repo_updates",