From 3e7d8a5a947cd47956ce3119bd6dd4ec58ad93eb Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 16 Jul 2026 15:35:11 +0000 Subject: [PATCH 1/3] move to code section --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 86b00d39..6e88933d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,6 +15,7 @@ This project is a Copier template used to generate other copier templates. It is - When disabling a linting rule with an inline directive, provide a comment at the end of the line (or on the line above for tools that don't allow extra text after an inline directive) describing the reasoning for disabling the rule. - Avoid telling the type checker what a type is rather than letting it prove it. This includes type assertions (`as SomeType` in TypeScript, `cast()` in Python) and variable annotations that override inference. Prefer approaches that let the type checker verify the type itself: `isinstance`/`instanceof` narrowing, restructuring code so the correct type flows naturally, or using discriminated unions. When there is genuinely no alternative, add a comment explaining why the workaround is necessary and why it is safe. - Avoid `||` (TypeScript) or `or` (Python) in `if`/`elif` conditions, and avoid `x in ['a', 'b']`-style membership tests in implementation code — coverage tools treat these as a single branch, silently masking untested paths and producing false 100% branch coverage. Use separate `if`/`elif` branches instead so each condition is independently covered. +- When filtering logic combines multiple `and`-joined guards (e.g. a null check alongside a value check), prefer a loop with explicit `if`/`continue` branches over a single-line comprehension. A compound boolean filter on one line hides individual branches from line coverage — each guard condition should be its own statement so missing test cases are surfaced. ## Testing @@ -24,7 +25,6 @@ This project is a Copier template used to generate other copier templates. It is - Avoid magic values in comparisons in tests in all languages (like ruff rule PLR2004 specifies). Note: `1` and `0` are not magic numbers (according to PLR2004) - Prefer using random values in tests rather than arbitrary ones (e.g. the faker library, uuids, random.randint) when possible. For enums, pick randomly rather than hardcoding one value. - Avoid loops in tests — assert each item explicitly so failures pinpoint the exact element. When verifying a condition across all items in a collection, collect the violations into a list and assert it's empty (e.g., assert [x for x in items if bad_condition(x)] == []). -- When filtering logic combines multiple `and`-joined guards (e.g. a null check alongside a value check), prefer a loop with explicit `if`/`continue` branches over a single-line comprehension. A compound boolean filter on one line hides individual branches from line coverage — each guard condition should be its own statement so missing test cases are surfaced. - When a test's final assertion is an absence (e.g., element is `null`, list is empty, modal is closed), include a prior presence assertion confirming the expected state existed before the action that removed it. A test whose only assertion is an absence check can pass vacuously if setup silently failed. - When asserting a mock or spy was called with specific arguments, always constrain as tightly as possible. In order of preference: (1) assert called exactly once with those args (`assert_called_once_with` in Python, `toHaveBeenCalledExactlyOnceWith` in Vitest/Jest); (2) if multiple calls are expected, assert the total call count and use a positional or last-call assertion (`nthCalledWith`, `lastCalledWith` / `assert_has_calls` with `call_args_list[n]`); (3) plain "called with at any point" (`toHaveBeenCalledWith`, `assert_called_with`) is a last resort only when neither the call count nor the call order can reasonably be constrained. - When asserting an exception is raised, verify the error message includes all key constructor arguments — not just one identifying field. This ensures the error message is fully populated and catches cases where arguments are swapped or missing. In Python: use the `match` parameter in `pytest.raises`. In TypeScript: use a regex or substring in `toThrow`, or catch and assert on error properties individually. From 2ecd799d6f22c38459d075cc6e935b185e24630f Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 16 Jul 2026 15:39:55 +0000 Subject: [PATCH 2/3] bump --- .devcontainer/devcontainer.json | 10 +++++----- .pre-commit-config.yaml | 10 +++++----- template/.devcontainer/devcontainer.json.jinja-base | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6292d505..659919dd 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -28,15 +28,15 @@ "-AmazonWebServices.aws-toolkit-vscode", // the AWS CLI feature installs this automatically, but it's causing problems in VS Code // basic tooling // "eamodio.gitlens@15.5.1", - "coderabbit.coderabbit-vscode@0.20.7", + "coderabbit.coderabbit-vscode@0.21.0", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905", - "anthropic.claude-code@2.1.205", + "anthropic.claude-code@2.1.211", // Python "ms-python.python@2026.5.2026052901", - "meta.pyrefly@1.1.9001", + "meta.pyrefly@1.1.9002", "ms-vscode-remote.remote-containers@0.414.0", - "charliermarsh.ruff@2026.56.0", + "charliermarsh.ruff@2026.60.0", // Misc file formats "bierner.markdown-mermaid@1.29.0", "samuelcolvin.jinjahtml@0.20.0", @@ -70,5 +70,5 @@ "initializeCommand": "sh .devcontainer/initialize-command.sh", "onCreateCommand": "sh .devcontainer/on-create-command.sh", "postStartCommand": "sh .devcontainer/post-start-command.sh" - // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): 007af1ff # spellchecker:disable-line + // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): cfc3f04c # spellchecker:disable-line } diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c95472b..8678d37a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,7 +42,7 @@ repos: # Reformatting (should generally come before any file format or other checks, because reformatting can change things) - repo: https://github.com/crate-ci/typos - rev: 359573a3ff38f71c93e160f2ace96d118f6ff42e # frozen: v1 + rev: 96d9af6217dc2855210655af7e1ff19d23d4e593 # frozen: v1 hooks: - id: typos args: [--write-changes, --force-exclude, --config, .config/_typos.toml] @@ -106,7 +106,7 @@ repos: )$ - repo: https://github.com/rbubley/mirrors-prettier - rev: 515f543f5718ebfd6ce22e16708bb32c68ff96e1 # frozen: v3.8.3 + rev: 9337a74165b178ae2c766f60bee7252a0f06f3e8 # frozen: v3.9.5 hooks: - id: prettier args: [--config, .config/.prettierrc] @@ -178,7 +178,7 @@ repos: - id: check-case-conflict - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 943377262562a12b57292fc98fabd7dbf81451fe # frozen: 0.37.2 + rev: 1a4bb160cab6417b3045e1b37b6b72449243e658 # frozen: 0.37.4 hooks: - id: check-github-workflows @@ -232,7 +232,7 @@ repos: description: Runs hadolint to lint Dockerfiles - repo: https://github.com/astral-sh/ruff-pre-commit - rev: 6fec9b7edb08fd9989088709d864a7826dc74e80 # frozen: v0.15.12 + rev: 2700fd5671c633760d912769c041bfcde2b9a01b # frozen: v0.15.22 hooks: - id: ruff name: ruff-src @@ -263,7 +263,7 @@ repos: )$ - repo: https://github.com/pylint-dev/pylint - rev: 88e1ab7545a4af4aea15c305a154c164a95ab842 # frozen: v4.0.5 + rev: 8a396357098337ba8be714fffdf2d00947a9778c # frozen: v4.0.6 hooks: - id: pylint name: pylint diff --git a/template/.devcontainer/devcontainer.json.jinja-base b/template/.devcontainer/devcontainer.json.jinja-base index 731d2345..93091070 100644 --- a/template/.devcontainer/devcontainer.json.jinja-base +++ b/template/.devcontainer/devcontainer.json.jinja-base @@ -34,16 +34,16 @@ "-AmazonWebServices.aws-toolkit-vscode", // the AWS CLI feature installs this automatically, but it's causing problems in VS Code{% endraw %}{% endif %}{% raw %} // basic tooling // "eamodio.gitlens@15.5.1", - "coderabbit.coderabbit-vscode@0.20.7", + "coderabbit.coderabbit-vscode@0.21.0", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905",{% endraw %}{% if install_claude_cli %}{% raw %} - "anthropic.claude-code@2.1.205",{% endraw %}{% endif %}{% raw %}{% endraw %}{% if (is_child_of_copier_base_template is defined and is_child_of_copier_base_template is sameas(true)) or (is_child_of_copier_base_template is not defined and template_uses_python is defined and template_uses_python is sameas(true)) %}{% raw %} + "anthropic.claude-code@2.1.211",{% endraw %}{% endif %}{% raw %}{% endraw %}{% if (is_child_of_copier_base_template is defined and is_child_of_copier_base_template is sameas(true)) or (is_child_of_copier_base_template is not defined and template_uses_python is defined and template_uses_python is sameas(true)) %}{% raw %} // Python "ms-python.python@2026.5.2026052901", - "meta.pyrefly@1.1.9001", + "meta.pyrefly@1.1.9002", "ms-vscode-remote.remote-containers@0.414.0", - "charliermarsh.ruff@2026.56.0",{% endraw %}{% endif %}{% raw %} + "charliermarsh.ruff@2026.60.0",{% endraw %}{% endif %}{% raw %} {% endraw %}{% if is_child_of_copier_base_template is not defined and template_uses_vuejs is defined and template_uses_vuejs is sameas(true) %}{% raw %} // VueJS "vue.volar@3.2.5", From 456e23611f1bb1cb111a2489b536a4fdee451e96 Mon Sep 17 00:00:00 2001 From: Eli Fine Date: Thu, 16 Jul 2026 16:08:32 +0000 Subject: [PATCH 3/3] codecov --- extensions/context.py | 1 + template/extensions/context.py.jinja-base | 1 + 2 files changed, 2 insertions(+) diff --git a/extensions/context.py b/extensions/context.py index 76367b75..b801f7f7 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -113,6 +113,7 @@ def hook( # noqa: PLR0915 # yes, this is a lot of statements, but it's all just context["gha_configure_aws_credentials"] = "v6.1.0" context["gha_amazon_ecr_login"] = "v2.1.5" context["gha_action_gh_release"] = "v3.0.0" + context["gha_codecov"] = "v7.0.0" context["gha_mutex"] = "1ebad517141198e08d47cf72f3c0975316620a65 # v1.0.0-alpha.10" context["gha_pypi_publish"] = "v1.14.0" context["gha_sleep"] = "v2.0.3" diff --git a/template/extensions/context.py.jinja-base b/template/extensions/context.py.jinja-base index f319432a..dddcbe5c 100644 --- a/template/extensions/context.py.jinja-base +++ b/template/extensions/context.py.jinja-base @@ -103,6 +103,7 @@ class ContextUpdater(ContextHook): context["gha_amazon_ecr_login"] = "{{ gha_amazon_ecr_login }}" context["gha_setup_node"] = "{{ gha_setup_node }}" context["gha_action_gh_release"] = "{{ gha_action_gh_release }}" + context["gha_codecov"] = "{{ gha_codecov }}" context["gha_mutex"] = "{{ gha_mutex }}" context["gha_pypi_publish"] = "{{ gha_pypi_publish }}" context["gha_sleep"] = "{{ gha_sleep }}"