From 6d256ee43c7da35b90b7192f6ea0088496845f47 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Apr 2026 00:13:44 +0200 Subject: [PATCH 1/7] chore(ci): standardize and lock workflow mappings - standardize root/template workflow guardrails (permissions/concurrency/version pinning) - add template labeler workflow counterpart - lock labeler workflow in root-template sync policy/map - add committed filepaths tracker csv Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 4 + .github/workflows/labeler.yml | 12 +- .github/workflows/pre-commit-update.yml | 4 + .github/workflows/stale.yml | 4 + .github/workflows/sync-skip-if-exists.yml | 4 + docs/root-template-sync-map.yaml | 4 + docs/root-template-sync-policy.md | 1 + temp_docs/committed_filepaths.csv | 281 ++++++++++++++++++ .../workflows/dependency-review.yml.jinja | 4 + template/.github/workflows/docs.yml.jinja | 2 +- template/.github/workflows/labeler.yml.jinja | 27 ++ .../workflows/pre-commit-update.yml.jinja | 4 + 12 files changed, 346 insertions(+), 5 deletions(-) create mode 100644 temp_docs/committed_filepaths.csv create mode 100644 template/.github/workflows/labeler.yml.jinja diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 5c45204..e9f5f86 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -16,6 +16,10 @@ on: permissions: contents: read +concurrency: + group: dependency-review-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: dependency-review: name: Review Dependencies diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index f0bb30a..83fc326 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -8,13 +8,17 @@ name: Labeler on: [pull_request_target] +permissions: + contents: read + pull-requests: write + +concurrency: + group: labeler-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: label: - runs-on: ubuntu-latest - permissions: - contents: read - pull-requests: write steps: - uses: actions/labeler@v6 diff --git a/.github/workflows/pre-commit-update.yml b/.github/workflows/pre-commit-update.yml index 6568d73..c264a26 100644 --- a/.github/workflows/pre-commit-update.yml +++ b/.github/workflows/pre-commit-update.yml @@ -18,6 +18,10 @@ permissions: contents: write pull-requests: write +concurrency: + group: pre-commit-update-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: autoupdate: name: Update pre-commit hooks diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 57d4858..cc26739 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -17,6 +17,10 @@ permissions: issues: write pull-requests: write +concurrency: + group: stale-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: stale: runs-on: ubuntu-latest diff --git a/.github/workflows/sync-skip-if-exists.yml b/.github/workflows/sync-skip-if-exists.yml index d1e13ae..29d356d 100644 --- a/.github/workflows/sync-skip-if-exists.yml +++ b/.github/workflows/sync-skip-if-exists.yml @@ -10,6 +10,10 @@ on: permissions: contents: read +concurrency: + group: sync-skip-if-exists-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: sync: runs-on: ubuntu-latest diff --git a/docs/root-template-sync-map.yaml b/docs/root-template-sync-map.yaml index bc8882e..050615e 100644 --- a/docs/root-template-sync-map.yaml +++ b/docs/root-template-sync-map.yaml @@ -24,6 +24,10 @@ { "root": ".github/workflows/dependency-review.yml", "template": "template/.github/workflows/dependency-review.yml.jinja" + }, + { + "root": ".github/workflows/labeler.yml", + "template": "template/.github/workflows/labeler.yml.jinja" } ] }, diff --git a/docs/root-template-sync-policy.md b/docs/root-template-sync-policy.md index a783bb2..b6bde4a 100644 --- a/docs/root-template-sync-policy.md +++ b/docs/root-template-sync-policy.md @@ -41,6 +41,7 @@ Use these rules in order: | `.github/workflows/pre-commit-update.yml` | `template/.github/workflows/pre-commit-update.yml.jinja` | sync_structure_only | bidirectional versions | | `.github/workflows/release.yml` | `template/.github/workflows/release.yml.jinja` | sync_structure_only | bidirectional versions | | `.github/workflows/dependency-review.yml` | `template/.github/workflows/dependency-review.yml.jinja` | sync_structure_only | bidirectional versions | +| `.github/workflows/labeler.yml` | `template/.github/workflows/labeler.yml.jinja` | sync_structure_only | bidirectional versions | ## Intentionally divergent areas diff --git a/temp_docs/committed_filepaths.csv b/temp_docs/committed_filepaths.csv new file mode 100644 index 0000000..325dbd3 --- /dev/null +++ b/temp_docs/committed_filepaths.csv @@ -0,0 +1,281 @@ +filepath +.claude/CLAUDE.md +.claude/commands/ci-fix.md +.claude/commands/ci.md +.claude/commands/coverage.md +.claude/commands/dependency-check.md +.claude/commands/docs-check.md +.claude/commands/generate.md +.claude/commands/release.md +.claude/commands/review.md +.claude/commands/standards.md +.claude/commands/tdd-green.md +.claude/commands/tdd-red.md +.claude/commands/test.md +.claude/commands/update-claude-md.md +.claude/commands/validate-release.md +.claude/hooks/README.md +.claude/hooks/post-bash-pr-created.sh +.claude/hooks/post-edit-copier-migration.sh +.claude/hooks/post-edit-jinja.sh +.claude/hooks/post-edit-markdown.sh +.claude/hooks/post-edit-python.sh +.claude/hooks/post-edit-refactor-test-guard.sh +.claude/hooks/post-edit-template-mirror.sh +.claude/hooks/pre-bash-block-no-verify.sh +.claude/hooks/pre-bash-commit-quality.sh +.claude/hooks/pre-bash-coverage-gate.sh +.claude/hooks/pre-bash-git-push-reminder.sh +.claude/hooks/pre-compact-save-state.sh +.claude/hooks/pre-config-protection.sh +.claude/hooks/pre-protect-uv-lock.sh +.claude/hooks/pre-suggest-compact.sh +.claude/hooks/pre-write-doc-file-warning.sh +.claude/hooks/pre-write-jinja-syntax.sh +.claude/hooks/pre-write-src-require-test.sh +.claude/hooks/pre-write-src-test-reminder.sh +.claude/hooks/session-start-bootstrap.sh +.claude/hooks/stop-cost-tracker.sh +.claude/hooks/stop-desktop-notify.sh +.claude/hooks/stop-evaluate-session.sh +.claude/hooks/stop-session-end.sh +.claude/rules/README.md +.claude/rules/bash/coding-style.md +.claude/rules/bash/security.md +.claude/rules/common/code-review.md +.claude/rules/common/coding-style.md +.claude/rules/common/development-workflow.md +.claude/rules/common/git-workflow.md +.claude/rules/common/hooks.md +.claude/rules/common/security.md +.claude/rules/common/testing.md +.claude/rules/copier/template-conventions.md +.claude/rules/jinja/coding-style.md +.claude/rules/jinja/testing.md +.claude/rules/markdown/conventions.md +.claude/rules/python/coding-style.md +.claude/rules/python/hooks.md +.claude/rules/python/patterns.md +.claude/rules/python/security.md +.claude/rules/python/testing.md +.claude/rules/yaml/conventions.md +.claude/settings.json +.claude/skills/tdd-test-planner/SKILL.md +.claude/skills/tdd-test-planner/references/pytest-patterns.md +.claude/skills/tdd-test-planner/references/test-doubles.md +.claude/skills/tdd-workflow/SKILL.md +.claude/skills/tdd-workflow/references/ci-detection.md +.claude/skills/tdd-workflow/references/skill-fallbacks.md +.claude/skills/tdd-workflow/references/test-patterns.md +.claude/skills/test-quality-reviewer/SKILL.md +.claude/skills/test-quality-reviewer/references/advanced-patterns.md +.claude/skills/test-quality-reviewer/references/examples.md +.github/CLAUDE.md +.github/PULL_REQUEST_TEMPLATE.md +.github/dependabot.yml +.github/labeler.yml +.github/renovate.json +.github/workflows/dependency-review.yml +.github/workflows/file-freshness.yml +.github/workflows/labeler.yml +.github/workflows/lint.yml +.github/workflows/pr-policy.yml +.github/workflows/pre-commit-update.yml +.github/workflows/release.yml +.github/workflows/security.yml +.github/workflows/stale.yml +.github/workflows/sync-skip-if-exists.yml +.github/workflows/tests.yml +.gitignore +.gitmessage +.pre-commit-config.yaml +.secrets.baseline +.vscode/extensions.json +.vscode/launch.json +.vscode/settings.json +CLAUDE.md +LICENSE +README.md +assets/file_freshness.json +assets/freshness_ignore.json +assets/freshness_summary.json +copier.yml +docs/file_locking_plan.md +docs/git-history-maintenance.md +docs/github-repository-settings.md +docs/repo_file_status_report.md +docs/root-template-sync-map.yaml +docs/root-template-sync-policy.md +env.example +justfile +pyproject.toml +scripts/CLAUDE.md +scripts/bump_version.py +scripts/check_root_template_sync.py +scripts/pr_commit_policy.py +scripts/repo_file_freshness.py +scripts/sync_skip_if_exists.py +template/.claude/commands/ci-fix.md +template/.claude/commands/ci.md +template/.claude/commands/coverage.md.jinja +template/.claude/commands/docs-check.md.jinja +template/.claude/commands/generate.md +template/.claude/commands/guided-template-update.md.jinja +template/.claude/commands/release.md.jinja +template/.claude/commands/review.md.jinja +template/.claude/commands/standards.md.jinja +template/.claude/commands/tdd-green.md +template/.claude/commands/tdd-red.md +template/.claude/commands/test.md +template/.claude/hooks/README.md +template/.claude/hooks/post-edit-markdown.sh +template/.claude/hooks/post-edit-python.sh +template/.claude/hooks/post-edit-refactor-test-guard.sh +template/.claude/hooks/pre-bash-block-no-verify.sh +template/.claude/hooks/pre-bash-commit-quality.sh +template/.claude/hooks/pre-bash-coverage-gate.sh +template/.claude/hooks/pre-bash-git-push-reminder.sh +template/.claude/hooks/pre-config-protection.sh +template/.claude/hooks/pre-protect-uv-lock.sh +template/.claude/hooks/pre-write-src-require-test.sh +template/.claude/hooks/pre-write-src-test-reminder.sh +template/.claude/rules/README.md +template/.claude/rules/bash/coding-style.md +template/.claude/rules/bash/security.md +template/.claude/rules/common/code-review.md +template/.claude/rules/common/coding-style.md +template/.claude/rules/common/development-workflow.md +template/.claude/rules/common/git-workflow.md +template/.claude/rules/common/hooks.md +template/.claude/rules/common/security.md +template/.claude/rules/common/testing.md +template/.claude/rules/markdown/conventions.md +template/.claude/rules/python/coding-style.md.jinja +template/.claude/rules/python/hooks.md +template/.claude/rules/python/patterns.md.jinja +template/.claude/rules/python/security.md +template/.claude/rules/python/testing.md +template/.claude/settings.json +template/.claude/skills/cron-scheduling/SKILL.md +template/.claude/skills/cron-scheduling/references/environments.md +template/.claude/skills/cron-scheduling/references/managing-jobs.md +template/.claude/skills/cron-scheduling/references/monitoring.md +template/.claude/skills/cron-scheduling/references/syntax-reference.md +template/.claude/skills/markdown/SKILL.md +template/.claude/skills/markdown/references/anti-patterns-cheatsheet.md +template/.claude/skills/markdown/references/code-and-links.md +template/.claude/skills/markdown/references/document-structure.md +template/.claude/skills/markdown/references/extended-syntax.md +template/.claude/skills/markdown/references/file-management.md +template/.claude/skills/markdown/references/formatting-syntax.md +template/.claude/skills/markdown/references/tables-images-html.md +template/.claude/skills/prepare_pr/SKILL.md +template/.claude/skills/prepare_pr/references/section-rules.md +template/.claude/skills/pytest/SKILL.md +template/.claude/skills/pytest/references/anti-patterns.md +template/.claude/skills/pytest/references/assertions.md +template/.claude/skills/pytest/references/ci-and-plugins.md +template/.claude/skills/pytest/references/fixtures.md +template/.claude/skills/pytest/references/mocking.md +template/.claude/skills/pytest/references/parametrize-and-markers.md +template/.claude/skills/pytest/references/test-organization.md +template/.claude/skills/pytest/references/test-types.md +template/.claude/skills/pytest/scripts/find_slow_tests.py +template/.claude/skills/pytest/scripts/mark_slow_tests.py +template/.claude/skills/python-code-quality/SKILL.md +template/.claude/skills/python-code-quality/references/bandit.md +template/.claude/skills/python-code-quality/references/basedpyright.md +template/.claude/skills/python-code-quality/references/complete-configs.md +template/.claude/skills/python-code-quality/references/pre-commit.md +template/.claude/skills/python-code-quality/references/ruff.md +template/.claude/skills/python-code-quality/references/semgrep.md +template/.claude/skills/python-code-reviewer/SKILL.md +template/.claude/skills/python-code-reviewer/references/checklist.md +template/.claude/skills/python-code-reviewer/references/output-format.md +template/.claude/skills/python-code-reviewer/references/python-patterns.md +template/.claude/skills/python-docstrings/SKILL.md +template/.claude/skills/python-docstrings/references/auditing.md +template/.claude/skills/python-docstrings/references/classes.md +template/.claude/skills/python-docstrings/references/examples.md +template/.claude/skills/python-docstrings/references/functions.md +template/.claude/skills/python-docstrings/references/generators.md +template/.claude/skills/python-docstrings/references/modules.md +template/.claude/skills/python-docstrings/references/overrides.md +template/.claude/skills/python-docstrings/references/properties.md +template/.claude/skills/python-docstrings/references/sections.md +template/.claude/skills/skill-maintainer/SKILL.md +template/.claude/skills/skill-maintainer/references/audit-checklist.md +template/.claude/skills/skill-maintainer/references/audit-examples.md +template/.claude/skills/skill-maintainer/references/maintenance-log.md +template/.claude/skills/tdd-test-planner/SKILL.md +template/.claude/skills/tdd-test-planner/references/pytest-patterns.md +template/.claude/skills/tdd-test-planner/references/test-doubles.md +template/.claude/skills/tdd-workflow/SKILL.md +template/.claude/skills/tdd-workflow/references/ci-detection.md +template/.claude/skills/tdd-workflow/references/skill-fallbacks.md +template/.claude/skills/tdd-workflow/references/test-patterns.md +template/.claude/skills/test-quality-reviewer/SKILL.md +template/.claude/skills/test-quality-reviewer/references/advanced-patterns.md +template/.claude/skills/test-quality-reviewer/references/examples.md +template/.github/CODEOWNERS.jinja +template/.github/CODE_OF_CONDUCT.md.jinja +template/.github/ISSUE_TEMPLATE/bug_report.md.jinja +template/.github/ISSUE_TEMPLATE/config.yml.jinja +template/.github/ISSUE_TEMPLATE/feature_request.md.jinja +template/.github/PULL_REQUEST_TEMPLATE.md.jinja +template/.github/renovate.json.jinja +template/.github/workflows/ci.yml.jinja +template/.github/workflows/dependency-review.yml.jinja +template/.github/workflows/docs.yml.jinja +template/.github/workflows/lint.yml.jinja +template/.github/workflows/pr-policy.yml.jinja +template/.github/workflows/pre-commit-update.yml.jinja +template/.github/workflows/release.yml.jinja +template/.github/workflows/security.yml.jinja +template/.gitignore.jinja +template/.gitmessage +template/.pre-commit-config.yaml.jinja +template/.secrets.baseline +template/.vscode/extensions.json.jinja +template/.vscode/launch.json.jinja +template/.vscode/settings.json.jinja +template/CLAUDE.md +template/CLAUDE.md.jinja +template/CONTRIBUTING.md.jinja +template/LICENSE.jinja +template/README.md.jinja +template/SECURITY.md.jinja +template/docs/github-repository-settings.md.jinja +template/docs/{% if include_docs %}ci.md{% endif %}.jinja +template/docs/{% if include_docs %}index.md{% endif %}.jinja +template/env.example.jinja +template/justfile.jinja +template/pyproject.toml.jinja +template/scripts/pr_commit_policy.py.jinja +template/src/{{ package_name }}/__init__.py.jinja +template/src/{{ package_name }}/common/__init__.py.jinja +template/src/{{ package_name }}/common/bump_version.py.jinja +template/src/{{ package_name }}/common/decorators.py.jinja +template/src/{{ package_name }}/common/file_manager.py.jinja +template/src/{{ package_name }}/common/logging_manager.py.jinja +template/src/{{ package_name }}/common/utils.py.jinja +template/src/{{ package_name }}/core.py.jinja +template/src/{{ package_name }}/{% if include_cli %}cli.py{% endif %}.jinja +template/tests/__init__.py.jinja +template/tests/conftest.py.jinja +template/tests/test_imports.py.jinja +template/tests/{{ package_name }}/__init__.py.jinja +template/tests/{{ package_name }}/test_core.py.jinja +template/tests/{{ package_name }}/test_support.py.jinja +template/{% if include_docs %}mkdocs.yml{% endif %}.jinja +template/{% if include_git_cliff %}cliff.toml{% endif %}.jinja +template/{{_copier_conf.answers_file}}.jinja +tests/CLAUDE.md +tests/test_bump_version.py +tests/test_check_root_template_sync.py +tests/test_pr_commit_policy.py +tests/test_repo_file_freshness.py +tests/test_root_template_sync.py +tests/test_sync_skip_if_exists.py +tests/test_template.py +uv.lock diff --git a/template/.github/workflows/dependency-review.yml.jinja b/template/.github/workflows/dependency-review.yml.jinja index 5c45204..31becff 100644 --- a/template/.github/workflows/dependency-review.yml.jinja +++ b/template/.github/workflows/dependency-review.yml.jinja @@ -16,6 +16,10 @@ on: permissions: contents: read +concurrency: + group: dependency-review-{% raw %}${{ github.workflow }}-${{ github.ref }}{% endraw %} + cancel-in-progress: true + jobs: dependency-review: name: Review Dependencies diff --git a/template/.github/workflows/docs.yml.jinja b/template/.github/workflows/docs.yml.jinja index 3fa7a13..45668d3 100644 --- a/template/.github/workflows/docs.yml.jinja +++ b/template/.github/workflows/docs.yml.jinja @@ -42,7 +42,7 @@ jobs: - uses: actions/checkout@v6 - name: Install uv - uses: astral-sh/setup-uv@v8 + uses: astral-sh/setup-uv@v8.0.0 with: enable-cache: true diff --git a/template/.github/workflows/labeler.yml.jinja b/template/.github/workflows/labeler.yml.jinja new file mode 100644 index 0000000..ac232cf --- /dev/null +++ b/template/.github/workflows/labeler.yml.jinja @@ -0,0 +1,27 @@ +# This workflow will triage pull requests and apply a label based on the +# paths that are modified in the pull request. +# +# To use this workflow, you will need to set up a .github/labeler.yml +# file with configuration. For more information, see: +# https://github.com/actions/labeler + +name: Labeler +on: [pull_request_target] + +permissions: + contents: read + pull-requests: write + +concurrency: + group: labeler-{% raw %}${{ github.workflow }}-${{ github.ref }}{% endraw %} + cancel-in-progress: true + +jobs: + label: + runs-on: ubuntu-latest + + steps: + - uses: actions/labeler@v6 + with: + repo-token: "{% raw %}${{ secrets.GITHUB_TOKEN }}{% endraw %}" + dot: true diff --git a/template/.github/workflows/pre-commit-update.yml.jinja b/template/.github/workflows/pre-commit-update.yml.jinja index 0b383cb..5d266c3 100644 --- a/template/.github/workflows/pre-commit-update.yml.jinja +++ b/template/.github/workflows/pre-commit-update.yml.jinja @@ -18,6 +18,10 @@ permissions: contents: write pull-requests: write +concurrency: + group: pre-commit-update-{% raw %}${{ github.workflow }}-${{ github.ref }}{% endraw %} + cancel-in-progress: true + jobs: autoupdate: name: Update pre-commit hooks From 80cd0ea42c1fc668b31f4041e42f3fc7eaf19533 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Apr 2026 00:37:44 +0200 Subject: [PATCH 2/7] chore(tests): standardize meta-repo tests layout - Move Copier suite to tests/integration/test_template.py and mirror scripts/ under tests/scripts/ - Add tests/_paths.py, package __init__, and pytest pythonpath for nested imports - Document layout in CLAUDE.md, rules, hooks, README; refresh freshness artifacts - Include workflow policy template sync updates on this branch Made-with: Cursor --- .claude/hooks/post-edit-copier-migration.sh | 2 +- .claude/rules/copier/template-conventions.md | 2 +- .claude/rules/jinja/testing.md | 4 +- .claude/rules/python/testing.md | 17 + .github/workflows/pr-policy.yml | 4 +- CLAUDE.md | 19 +- README.md | 2 +- assets/file_freshness.json | 1194 +++++++++-------- assets/freshness_summary.json | 8 +- docs/git-history-maintenance.md | 2 +- docs/repo_file_status_report.md | 559 ++++---- pyproject.toml | 1 + scripts/CLAUDE.md | 6 +- .../.github/workflows/pr-policy.yml.jinja | 4 +- template/CLAUDE.md | 2 +- tests/CLAUDE.md | 23 +- tests/__init__.py | 1 + tests/_paths.py | 10 + tests/{ => integration}/test_template.py | 13 +- tests/{ => scripts}/test_bump_version.py | 5 +- .../test_check_root_template_sync.py | 8 +- tests/{ => scripts}/test_pr_commit_policy.py | 5 +- .../{ => scripts}/test_repo_file_freshness.py | 4 +- .../{ => scripts}/test_root_template_sync.py | 4 +- .../{ => scripts}/test_sync_skip_if_exists.py | 7 +- 25 files changed, 1003 insertions(+), 903 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/_paths.py rename tests/{ => integration}/test_template.py (99%) rename tests/{ => scripts}/test_bump_version.py (96%) rename tests/{ => scripts}/test_check_root_template_sync.py (70%) rename tests/{ => scripts}/test_pr_commit_policy.py (98%) rename tests/{ => scripts}/test_repo_file_freshness.py (98%) rename tests/{ => scripts}/test_root_template_sync.py (98%) rename tests/{ => scripts}/test_sync_skip_if_exists.py (92%) diff --git a/.claude/hooks/post-edit-copier-migration.sh b/.claude/hooks/post-edit-copier-migration.sh index 88a5059..48ab720 100755 --- a/.claude/hooks/post-edit-copier-migration.sh +++ b/.claude/hooks/post-edit-copier-migration.sh @@ -44,7 +44,7 @@ echo "│" echo "│ □ _migrations — add a migration block if renaming or removing a" echo "│ variable so existing generated projects can upgrade" echo "│" -echo "│ □ tests/test_template.py — add or update parametrized tests that cover" +echo "│ □ tests/integration/test_template.py — add or update parametrized tests that cover" echo "│ the new variable behaviour" echo "│" echo "│ □ CLAUDE.md — update 'Copier variable conventions' section if" diff --git a/.claude/rules/copier/template-conventions.md b/.claude/rules/copier/template-conventions.md index 1de0968..8c40e38 100644 --- a/.claude/rules/copier/template-conventions.md +++ b/.claude/rules/copier/template-conventions.md @@ -173,7 +173,7 @@ When adding or modifying hooks, commands, or rules: ## Testing template changes Every change to `copier.yml` or a template file requires a test update in -`tests/test_template.py`. Run: +`tests/integration/test_template.py`. Run: ```bash just test # run all template tests diff --git a/.claude/rules/jinja/testing.md b/.claude/rules/jinja/testing.md index 404b299..0f1feff 100644 --- a/.claude/rules/jinja/testing.md +++ b/.claude/rules/jinja/testing.md @@ -6,7 +6,7 @@ ## What to test -Every Jinja2 template change requires a corresponding test in `tests/test_template.py`. +Every Jinja2 template change requires a corresponding test in `tests/integration/test_template.py`. Tests render the template with `copier copy` and assert on the output. Scenarios to cover for each template file: @@ -82,7 +82,7 @@ rm -rf /tmp/test-output ## Update testing Test `copier update` scenarios when changing `_skip_if_exists` or the `.copier-answers.yml` -template. The `tests/test_template.py` file includes update scenario tests; add new ones +template. The `tests/integration/test_template.py` file includes update scenario tests; add new ones when you add new `_skip_if_exists` entries. ## Coverage for template branches diff --git a/.claude/rules/python/testing.md b/.claude/rules/python/testing.md index 887c1eb..8c2e2e0 100644 --- a/.claude/rules/python/testing.md +++ b/.claude/rules/python/testing.md @@ -21,6 +21,23 @@ tests/ └── test_imports.py # smoke test: every public symbol is importable ``` +### Meta-repo (this template repository) + +Generated projects follow the layout above. **This Copier meta-repository** has no `src/` tree; +Python under test lives in `scripts/`. Keep pytest modules organized as: + +``` +tests/ +├── _paths.py # REPO_ROOT, TEMPLATE_ROOT, COPIER_YAML (import from nested tests) +├── integration/ +│ └── test_template.py # Copier copy/update integration suite +└── scripts/ + └── test_