From 44e69fc193bf24f133ed64151f851fcd9eacdfe1 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 13 May 2026 06:19:40 +0000 Subject: [PATCH 1/3] fix(cli): strip .github/workflows/ from workspace-bundled sample module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `smpy create-module` ships .github/workflows/{ci.yml, publish.yml} so authors who publish a module as its own repo get CI + PyPI trusted publishing out of the box. But `smpy new` calls create_module() to drop a sample `hello` module under modules/hello/ in a workspace — GitHub only reads workflows from the repo root, so the bundled copies were dead files masquerading as active CI. Strip the sample's .github/ tree after scaffolding, mirroring how _strip_workspace_owned_files drops host files the workspace root owns. https://claude.ai/code/session_01LfX6sdezX5NFAH3v1eixUq --- framework/cli/simple_module_cli/app_project.py | 6 ++++++ framework/cli/tests/test_cli_new.py | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/framework/cli/simple_module_cli/app_project.py b/framework/cli/simple_module_cli/app_project.py index 0ce9fe22..9fe9ecb5 100644 --- a/framework/cli/simple_module_cli/app_project.py +++ b/framework/cli/simple_module_cli/app_project.py @@ -15,6 +15,7 @@ import json as _json import secrets as _secrets +import shutil as _shutil from collections.abc import Sequence from importlib.metadata import PackageNotFoundError from importlib.metadata import version as _pkg_version @@ -181,6 +182,11 @@ def _scaffold_sample_module(target: Path) -> None: if sample_dest.exists(): return create_module(sample_dest, name=_SAMPLE_MODULE_NAME) + # The module template ships .github/workflows/ for standalone-repo use + # (`smpy create-module`); inside a workspace GitHub only reads workflows + # from the repo root, so these files are dead — drop them to avoid + # confusing authors who think they'd ever run. + _shutil.rmtree(sample_dest / ".github", ignore_errors=True) _pin_sample_module_deps(sample_dest) _seed_static_dist_placeholder(sample_dest / _SAMPLE_MODULE_NAME / "static" / "dist") diff --git a/framework/cli/tests/test_cli_new.py b/framework/cli/tests/test_cli_new.py index e067eeee..049fa702 100644 --- a/framework/cli/tests/test_cli_new.py +++ b/framework/cli/tests/test_cli_new.py @@ -217,6 +217,19 @@ def test_sm_new_default_scaffolds_sample_hello_module(tmp_path: Path) -> None: assert (target / "modules" / "hello" / "hello" / "module.py").is_file() +def test_sm_new_strips_sample_module_github_workflows(tmp_path: Path) -> None: + """The bundled sample module must not ship .github/workflows/ — GitHub only + reads workflows from the repo root, so leaving them under modules/hello/ + creates files that look active but never run.""" + runner = CliRunner() + target = tmp_path / "demo" + runner.invoke( + app, + ["new", "demo", "--yes", "--db", "sqlite", "--no-install", "--dest", str(target)], + ) + assert not (target / "modules" / "hello" / ".github").exists() + + def test_sm_new_default_lays_down_workspace_layout(tmp_path: Path) -> None: runner = CliRunner() target = tmp_path / "demo" From f6277edbafabbdb2896a285fcd353ca057cae137 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 13 May 2026 06:21:19 +0000 Subject: [PATCH 2/3] test(cli): fold .github strip assertion into existing workspace-layout test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dedicated test pushed test_cli_new.py past the 300-line cap. Move the regression assertion next to the other "files we don't ship at host/" assertions in test_sm_new_default_lays_down_workspace_layout — both check the same workspace-mode trimming behavior. https://claude.ai/code/session_01LfX6sdezX5NFAH3v1eixUq --- framework/cli/tests/test_cli_new.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/framework/cli/tests/test_cli_new.py b/framework/cli/tests/test_cli_new.py index 049fa702..15615f37 100644 --- a/framework/cli/tests/test_cli_new.py +++ b/framework/cli/tests/test_cli_new.py @@ -217,19 +217,6 @@ def test_sm_new_default_scaffolds_sample_hello_module(tmp_path: Path) -> None: assert (target / "modules" / "hello" / "hello" / "module.py").is_file() -def test_sm_new_strips_sample_module_github_workflows(tmp_path: Path) -> None: - """The bundled sample module must not ship .github/workflows/ — GitHub only - reads workflows from the repo root, so leaving them under modules/hello/ - creates files that look active but never run.""" - runner = CliRunner() - target = tmp_path / "demo" - runner.invoke( - app, - ["new", "demo", "--yes", "--db", "sqlite", "--no-install", "--dest", str(target)], - ) - assert not (target / "modules" / "hello" / ".github").exists() - - def test_sm_new_default_lays_down_workspace_layout(tmp_path: Path) -> None: runner = CliRunner() target = tmp_path / "demo" @@ -249,6 +236,7 @@ def test_sm_new_default_lays_down_workspace_layout(tmp_path: Path) -> None: assert (target / "host" / relpath).is_file(), f"missing host file: {relpath}" for relpath in (".env.example", "README.md", ".gitignore", "Makefile"): assert not (target / "host" / relpath).exists() + assert not (target / "modules" / "hello" / ".github").exists() def test_sm_new_default_wires_workspace_in_pyproject(tmp_path: Path) -> None: From bc8e71f3994e71986f1f0bc9713a03edf4b0e65f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 13 May 2026 06:25:06 +0000 Subject: [PATCH 3/3] refactor(cli): tighten the workspace-mode .github strip MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Trim the 4-line comment to one line covering only the non-obvious WHY (workflows under a sub-path don't run). - Drop ignore_errors=True — the template guarantees .github/ exists immediately after create_module(), so silent error-swallowing only hides real OS-level failures. https://claude.ai/code/session_01LfX6sdezX5NFAH3v1eixUq --- framework/cli/simple_module_cli/app_project.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/framework/cli/simple_module_cli/app_project.py b/framework/cli/simple_module_cli/app_project.py index 9fe9ecb5..434aa89b 100644 --- a/framework/cli/simple_module_cli/app_project.py +++ b/framework/cli/simple_module_cli/app_project.py @@ -182,11 +182,9 @@ def _scaffold_sample_module(target: Path) -> None: if sample_dest.exists(): return create_module(sample_dest, name=_SAMPLE_MODULE_NAME) - # The module template ships .github/workflows/ for standalone-repo use - # (`smpy create-module`); inside a workspace GitHub only reads workflows - # from the repo root, so these files are dead — drop them to avoid - # confusing authors who think they'd ever run. - _shutil.rmtree(sample_dest / ".github", ignore_errors=True) + # GitHub only reads workflows from the repo root, so the template's + # .github/ is dead inside a workspace. + _shutil.rmtree(sample_dest / ".github") _pin_sample_module_deps(sample_dest) _seed_static_dist_placeholder(sample_dest / _SAMPLE_MODULE_NAME / "static" / "dist")