diff --git a/.copier-answers.yml b/.copier-answers.yml index 0d351f97..6dce6305 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,7 +1,8 @@ # Changes here will be overwritten by Copier -_commit: v0.0.74 +_commit: v0.0.77 _src_path: gh:LabAutomationAndScreening/copier-base-template.git description: Copier template for creating Python libraries and executables +install_claude_cli: false python_ci_versions: - 3.12.7 - 3.13.2 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2f3c5514..7a98cb14 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,10 +3,10 @@ "service": "devcontainer", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { - "ghcr.io/devcontainers/features/aws-cli:1.1.1": { + "ghcr.io/devcontainers/features/aws-cli:1.1.2": { // https://github.com/devcontainers/features/blob/main/src/aws-cli/devcontainer-feature.json // view latest version https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst - "version": "2.27.14" + "version": "2.31.11" }, "ghcr.io/devcontainers/features/python:1.7.1": { // https://github.com/devcontainers/features/blob/main/src/python/devcontainer-feature.json @@ -20,17 +20,18 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ // basic tooling - "eamodio.gitlens@15.5.1", + // "eamodio.gitlens@15.5.1", + "coderabbit.coderabbit-vscode@0.15.2", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905", - "github.copilot@1.366.1775", - "github.copilot-chat@0.31.2025090401", + "github.copilot@1.380.1802", + "github.copilot-chat@0.33.2025101401", // Python - "ms-python.python@2025.13.2025090201", - "ms-python.vscode-pylance@2025.7.102", + "ms-python.python@2025.17.2025100201", + "ms-python.vscode-pylance@2025.8.3", "ms-vscode-remote.remote-containers@0.414.0", - "charliermarsh.ruff@2025.24.0", + "charliermarsh.ruff@2025.28.0", // Misc file formats "bierner.markdown-mermaid@1.28.0", @@ -44,6 +45,7 @@ "extensions.autoUpdate": false, "extensions.autoCheckUpdates": false, "livePreview.portNumber": 3025, // arbitrary not to conflict with default 3000 Nuxt port number + "github.copilot.nextEditSuggestions.allowWhitespaceOnlyChanges": false, "[python]": { "editor.formatOnSave": true, "editor.defaultFormatter": "charliermarsh.ruff" @@ -61,5 +63,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): 735908f4 # spellchecker:disable-line + // Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): a5dbeab3 # spellchecker:disable-line } diff --git a/.devcontainer/install-ci-tooling.py b/.devcontainer/install-ci-tooling.py index e0239278..5c6e684a 100644 --- a/.devcontainer/install-ci-tooling.py +++ b/.devcontainer/install-ci-tooling.py @@ -7,8 +7,8 @@ import tempfile from pathlib import Path -UV_VERSION = "0.8.22" -PNPM_VERSION = "10.17.1" +UV_VERSION = "0.9.2" +PNPM_VERSION = "10.18.3" COPIER_VERSION = "9.10.2" COPIER_TEMPLATE_EXTENSIONS_VERSION = "0.3.3" PRE_COMMIT_VERSION = "4.3.0" @@ -36,13 +36,21 @@ default=False, help="Skip installing the SSM plugin for AWS CLI", ) +_ = parser.add_argument( + "--allow-uv-to-install-python", + action="store_true", + default=False, + help="Allow uv to install new versions of Python on the fly. This is typically only needed when instantiating the copier template.", +) def main(): args = parser.parse_args(sys.argv[1:]) is_windows = platform.system() == "Windows" uv_env = dict(os.environ) - uv_env.update({"UV_PYTHON_PREFERENCE": "only-system", "UV_PYTHON": args.python_version}) + uv_env.update({"UV_PYTHON": args.python_version}) + if not args.allow_uv_to_install_python: + uv_env.update({"UV_PYTHON_PREFERENCE": "only-system"}) uv_path = ((GITHUB_WINDOWS_RUNNER_BIN_PATH + "\\") if is_windows else "") + "uv" if is_windows: pwsh = shutil.which("pwsh") or shutil.which("powershell") diff --git a/.gitignore b/.gitignore index aa359644..fa36212d 100644 --- a/.gitignore +++ b/.gitignore @@ -44,8 +44,6 @@ pytest.log tests/__coverage__ test/__coverage__ coverage-report-pytest -.pytest_cache/ -.mypy_cache/ .coverage .coverage.* coverage.xml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 249101a5..66531bc6 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: edb4e206047e89b93ebe08f1a2ccc3d581a70cc7 # frozen: v1 + rev: 6573587991823ef75e4d6ca97fe895f45e9f14e4 # frozen: v1 hooks: - id: typos exclude: | @@ -59,6 +59,7 @@ repos: (?x)^( .*/vendor_files/.*| .*tests/.*/__snapshots__/.*| + .*/openapi_codegen/.*| )$ - id: end-of-file-fixer # the XML formatter hook doesn't leave a blank line at the end, so excluding XML files from this hook to avoid conflicts @@ -70,10 +71,12 @@ repos: template/template/.copier-answers.yml.jinja| template/.copier-answers.yml.jinja| .*generated/graphql.ts| + .*/openapi_codegen/.*| .*tests/.*/__snapshots__/.*| .devcontainer/devcontainer-lock.json| .copier-answers.yml| .*\.xml| + .*\.svg| .*/vendor_files/.*| )$ - id: pretty-format-json @@ -85,6 +88,7 @@ repos: .*pyrightconfig.json| .*tsconfig.json| .*biome.jsonc| + .*/openapi_codegen/.*| .*tests/.*/__snapshots__/.*| .*/vendor_files/.*| )$ @@ -98,6 +102,7 @@ repos: exclude: | (?x)^( .*generated/graphql.ts| + .*/openapi_codegen/.*| .*/schema.graphql| .*pyrightconfig\.json| )$ @@ -124,6 +129,7 @@ repos: .*.jsonc| .*/vendor_files/.*| .*/schema.graphql| + .*/openapi_codegen/.*| .*generated/graphql.ts| template/.*| )$ @@ -148,6 +154,7 @@ repos: (?x)^( .*/__snapshots__/.*| .*/vendor_files/.*| + .*\.svg| )$ # Invalid File Checks @@ -170,17 +177,19 @@ repos: - id: check-yaml # .copier-answers.yml is an autogenerated YAML file by Copier that throws 'found unhashable key' errors # Helm charts contain other non-YAML markers that cause errors here. they should be checked with helm-lint instead + # VCRpy cassettes sometimes contain non-YAML markers that cause errors---but they're autogenerated anyway exclude: | (?x)^( .copier-answers.yml| - (.*/helm/.*)| + (.*/?helm/.*)| + (.*/tests/unit/.*/?cassettes/.*)| )$ - id: check-xml - id: check-merge-conflict - id: check-case-conflict - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 83987cd6ad8943c7f029b500b14aaf82c00a01fa # frozen: 0.34.0 + rev: 83b816d020105076daac266dbf6bfed199a2da93 # frozen: 0.34.1 hooks: - id: check-github-workflows @@ -234,7 +243,7 @@ repos: description: Runs hadolint to lint Dockerfiles - repo: https://github.com/astral-sh/ruff-pre-commit - rev: a113f03edeabb71305f025e6e14bd2cd68660e29 # frozen: v0.13.1 + rev: f9351c924055bf6c7b4a4670237d3ce141e9f57c # frozen: v0.14.0 hooks: - id: ruff name: ruff-src @@ -244,6 +253,7 @@ repos: (?x)^( .*/graphql_codegen/.*| .*/openapi_codegen/.*| + template/.*| )$ - id: ruff name: ruff-tests @@ -253,6 +263,7 @@ repos: (?x)^( .*/graphql_codegen/.*| .*/openapi_codegen/.*| + template/.*| )$ - id: ruff-format exclude: | @@ -262,7 +273,7 @@ repos: )$ - repo: https://github.com/pylint-dev/pylint - rev: 98942ba4126a6fe1657bad77027bcc11016d16da # frozen: v3.3.8 + rev: 9a3035053154ba0c3ca3b300d6bc9fa72b95d552 # frozen: v4.0.1 hooks: - id: pylint name: pylint diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cd88f1f5..8272cfab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ By participating in this project, you agree to abide by our [Code of Conduct](./ 1. **Fork the repository** on GitHub. 2. **Set up the Dev Container (Recommended Method)** - - Create a Github Codespace (`Code`->`Codespaces` in the Github web console of your cloned repository) OR click on the "Open in Devcontainer" link in the [Readme](./README.md) + - Create a GitHub Codespace (`Code`->`Codespaces` in the GitHub web console of your cloned repository) OR click on the "Open in Devcontainer" link in the [Readme](./README.md) 3. **Make Your Changes** - Create a branch for your feature or bug fix: diff --git a/README.md b/README.md index 107bb072..966577ce 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ To create a new repository using this template: 1. Inside that devcontainer, run `python .devcontainer/install-ci-tooling.py` to install necessary tooling to instantiate the template (you can copy/paste the script from this repo...and you can paste it in the root of the repo if you want) 1. Delete all files currently in the repository. Optional...but makes it easiest to avoid git conflicts. 1. Run copier to instantiate the template: `copier copy --trust gh:LabAutomationAndScreening/copier-python-package-template.git .` -1. Run `python .devcontainer/manual-setup-deps.py --only-create-lock` to generate the lock file(s) +1. Run `python .devcontainer/manual-setup-deps.py --only-create-lock --allow-uv-to-install-python` to generate the lock file(s) 1. Stage all files to prepare for commit (`git add .`) 1. Run `python3 .github/workflows/hash_git_files.py . --for-devcontainer-config-update` to update the hash for your devcontainer file 1. Commit the changes (optional) diff --git a/_typos.toml b/_typos.toml index 37a91521..cf8a11d2 100644 --- a/_typos.toml +++ b/_typos.toml @@ -22,5 +22,5 @@ extend-exclude = [ ".copier-answers.yml", # this is an autogenerated file, and sometimes the commit sha gets confused as being a word "**/__snapshots__/**", # Snapshots need to remain static "**/tests/**/cassettes/**/*.yaml", # URLs and other responses in VCR.py generated files should not be altered - "**/vendor_files/**" # if vendors mispell things, there may be other implications in other parts of their code, just leave vendor files alone + "**/vendor_files/**" # if vendors misspell things, there may be other implications in other parts of their code, just leave vendor files alone ] diff --git a/copier.yml b/copier.yml index e9d91b77..aa9b4645 100644 --- a/copier.yml +++ b/copier.yml @@ -11,6 +11,11 @@ description: type: str help: What is the description of this repository? +install_claude_cli: + type: bool + help: Should the Claude CLI be installed in the devcontainer? + default: no + is_open_source: type: bool help: Is this library open source? diff --git a/extensions/context.py b/extensions/context.py index 5caa5108..ab7081a1 100644 --- a/extensions/context.py +++ b/extensions/context.py @@ -10,54 +10,55 @@ class ContextUpdater(ContextHook): @override def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: - context["uv_version"] = "0.8.22" - context["pnpm_version"] = "10.17.1" + context["uv_version"] = "0.9.2" + context["pnpm_version"] = "10.18.3" context["pre_commit_version"] = "4.3.0" - context["pyright_version"] = "1.1.405" + context["pyright_version"] = "1.1.406" context["pytest_version"] = "8.4.2" context["pytest_randomly_version"] = "4.0.1" context["pytest_cov_version"] = "7.0.0" context["copier_version"] = "9.10.2" context["copier_template_extensions_version"] = "0.3.3" context["sphinx_version"] = "8.1.3" - context["pulumi_version"] = "3.197.0" - context["pulumi_aws_version"] = "7.7.0" - context["pulumi_aws_native_version"] = "1.33.0" - context["pulumi_command_version"] = "1.1.0" - context["pulumi_github_version"] = "6.7.3" - context["pulumi_okta_version"] = "5.2.0" - context["boto3_version"] = "1.40.41" + context["pulumi_version"] = "3.203.0" + context["pulumi_aws_version"] = "7.8.0" + context["pulumi_aws_native_version"] = "1.37.0" + context["pulumi_command_version"] = "1.1.3" + context["pulumi_github_version"] = "6.7.4" + context["pulumi_okta_version"] = "6.0.0" + context["boto3_version"] = "1.40.51" context["ephemeral_pulumi_deploy_version"] = "0.0.5" - context["pydantic_version"] = "2.11.7" + context["pydantic_version"] = "2.12.2" context["pyinstaller_version"] = "6.16.0" context["setuptools_version"] = "80.7.1" - context["strawberry_graphql_version"] = "0.282.0" - context["fastapi_version"] = "0.118.0" + context["strawberry_graphql_version"] = "0.283.3" + context["fastapi_version"] = "0.119.0" context["fastapi_offline_version"] = "1.7.4" context["uvicorn_version"] = "0.37.0" - context["lab_auto_pulumi_version"] = "0.1.16" + context["lab_auto_pulumi_version"] = "0.1.17" context["ariadne_codegen_version"] = "0.15.2" - context["pytest_mock_version"] = "3.15.0" + context["pytest_mock_version"] = "3.15.1" context["uuid_utils_version"] = "0.11.0" + context["syrupy_version"] = "5.0.0" context["node_version"] = "24.7.0" - context["nuxt_ui_version"] = "^4.0.0" + context["nuxt_ui_version"] = "^4.0.1" context["nuxt_version"] = "^4.1.0" context["nuxt_icon_version"] = "^2.0.0" - context["typescript_version"] = "^5.8.2" - context["playwright_version"] = "^1.55.0" + context["typescript_version"] = "^5.9.3" + context["playwright_version"] = "^1.56.0" context["vue_version"] = "^3.5.21" - context["vue_tsc_version"] = "^3.1.0" + context["vue_tsc_version"] = "^3.1.1" context["vue_devtools_api_version"] = "^8.0.0" - context["vue_router_version"] = "^4.5.1" + context["vue_router_version"] = "^4.6.0" context["dotenv_cli_version"] = "^10.0.0" - context["faker_version"] = "^10.0.0" + context["faker_version"] = "^10.1.0" context["vitest_version"] = "^3.2.4" - context["eslint_version"] = "^9.36.0" + context["eslint_version"] = "^9.37.0" context["nuxt_eslint_version"] = "^1.9.0" context["zod_version"] = "^4.1.5" context["zod_from_json_schema_version"] = "^0.5.0" - context["types_node_version"] = "^24.6.0" + context["types_node_version"] = "^24.7.2" context["nuxt_apollo_version"] = "5.0.0-alpha.15" context["graphql_codegen_cli_version"] = "^6.0.0" context["graphql_codegen_typescript_version"] = "^5.0.0" @@ -68,7 +69,10 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]: context["nuxt_fonts_version"] = "^0.11.4" context["nuxtjs_color_mode_version"] = "^3.5.2" context["vue_test_utils_version"] = "^2.4.6" - context["nuxt_test_utils_version"] = "^3.17.2" + context["nuxt_test_utils_version"] = "3.19.1" + context["vue_eslint_parser_version"] = "^10.1.3" + context["happy_dom_version"] = "^20.0.2" + context["node_kiota_bundle_version"] = "1.0.0-preview.99" context["gha_checkout"] = "v5.0.0" context["gha_setup_python"] = "v6.0.0" diff --git a/pyproject.toml b/pyproject.toml index c228c919..6e0f8e16 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,7 @@ dependencies = [ "pytest>=8.4.2", "pytest-cov>=7.0.0", "pytest-randomly>=4.0.1", - "pyright[nodejs]>=1.1.405", + "pyright[nodejs]>=1.1.406", "copier>=9.10.2", "copier-template-extensions>=0.3.3" diff --git a/ruff-test.toml b/ruff-test.toml index 9994e410..407ecf89 100644 --- a/ruff-test.toml +++ b/ruff-test.toml @@ -12,7 +12,7 @@ ignore = [ "S101", # assert is definitely needed in test cases "S311", # pseudo-randomness is fine for test cases "TID252", # sometimes you can't use absolute imports in test cases for importing things within the tests, because they're not a true package or have conflicting namespaces - "TRY003", # tests dont need to create a custom exception classes, generally you want to throw an AssertionError with a message anyway + "TRY003", # tests don't need to create custom exception classes, generally you want to throw an AssertionError with a message anyway ] unfixable = [ diff --git a/template/.devcontainer/devcontainer.json.jinja b/template/.devcontainer/devcontainer.json.jinja index b69eddd9..123279c8 100644 --- a/template/.devcontainer/devcontainer.json.jinja +++ b/template/.devcontainer/devcontainer.json.jinja @@ -3,10 +3,10 @@ "service": "devcontainer", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { - "ghcr.io/devcontainers/features/aws-cli:1.1.1": { + "ghcr.io/devcontainers/features/aws-cli:1.1.2": { // https://github.com/devcontainers/features/blob/main/src/aws-cli/devcontainer-feature.json // view latest version https://raw.githubusercontent.com/aws/aws-cli/v2/CHANGELOG.rst - "version": "2.27.14" + "version": "2.31.11" }, "ghcr.io/devcontainers/features/python:1.7.1": { // https://github.com/devcontainers/features/blob/main/src/python/devcontainer-feature.json @@ -15,28 +15,31 @@ "installTools": false, "optimize": true }{% endraw %}{% if is_child_of_copier_base_template is not defined and template_uses_javascript is defined and template_uses_javascript is sameas(true) %}{% raw %}, - "ghcr.io/devcontainers/features/node:1.6.1": { + "ghcr.io/devcontainers/features/node:1.6.3": { // https://github.com/devcontainers/features/tree/main/src/node "version": "{% endraw %}{{ node_version }}{% raw %}", "pnpmVersion": "{% endraw %}{{ pnpm_version }}{% raw %}" - }{% endraw %}{% endif %}{% raw %} + }{% endraw %}{% endif %}{% raw %}{% endraw %}{% if install_claude_cli %}{% raw %}, + "ghcr.io/anthropics/devcontainer-features/claude-code:1.0.5": {}{% endraw %}{% endif %}{% raw %} }, "customizations": { "vscode": { // Add the IDs of extensions you want installed when the container is created. "extensions": [ // basic tooling - "eamodio.gitlens@15.5.1", + // "eamodio.gitlens@15.5.1", + "coderabbit.coderabbit-vscode@0.15.2", "ms-vscode.live-server@0.5.2025051301", "MS-vsliveshare.vsliveshare@1.0.5905", - "github.copilot@1.366.1775", - "github.copilot-chat@0.31.2025090401", + "github.copilot@1.380.1802", + "github.copilot-chat@0.33.2025101401",{% endraw %}{% if install_claude_cli %}{% raw %} + "anthropic.claude-code@2.0.10",{% endraw %}{% endif %}{% raw %} // Python - "ms-python.python@2025.13.2025090201", - "ms-python.vscode-pylance@2025.7.102", + "ms-python.python@2025.17.2025100201", + "ms-python.vscode-pylance@2025.8.3", "ms-vscode-remote.remote-containers@0.414.0", - "charliermarsh.ruff@2025.24.0", + "charliermarsh.ruff@2025.28.0", {% 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.0.6", @@ -57,6 +60,7 @@ "extensions.autoUpdate": false, "extensions.autoCheckUpdates": false, "livePreview.portNumber": 3025, // arbitrary not to conflict with default 3000 Nuxt port number + "github.copilot.nextEditSuggestions.allowWhitespaceOnlyChanges": false, "[python]": { "editor.formatOnSave": true, "editor.defaultFormatter": "charliermarsh.ruff" diff --git a/template/.devcontainer/docker-compose.yml.jinja b/template/.devcontainer/docker-compose.yml.jinja index 28dfd1af..17d94259 100644 --- a/template/.devcontainer/docker-compose.yml.jinja +++ b/template/.devcontainer/docker-compose.yml.jinja @@ -16,7 +16,8 @@ - "{% endraw %}{{ ssh_port_number }}{% raw %}:2222" environment: - AWS_PROFILE=localstack - - AWS_DEFAULT_REGION={% endraw %}{{ aws_region_for_stack if (aws_region_for_stack is defined and aws_region_for_stack != "") else "us-east-1" }}{% raw %} + - AWS_DEFAULT_REGION={% endraw %}{{ aws_region_for_stack if (aws_region_for_stack is defined and aws_region_for_stack != "") else "us-east-1" }}{% raw %}{% endraw %}{% if install_claude_cli %}{% raw %} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}{% endraw %}{% endif %}{% raw %} volumes: diff --git a/template/.devcontainer/install-ci-tooling.py.jinja b/template/.devcontainer/install-ci-tooling.py.jinja index 194d1580..0623c0c9 100644 --- a/template/.devcontainer/install-ci-tooling.py.jinja +++ b/template/.devcontainer/install-ci-tooling.py.jinja @@ -36,13 +36,21 @@ _ = parser.add_argument( default=False, help="Skip installing the SSM plugin for AWS CLI", ) +_ = parser.add_argument( + "--allow-uv-to-install-python", + action="store_true", + default=False, + help="Allow uv to install new versions of Python on the fly. This is typically only needed when instantiating the copier template.", +) def main(): args = parser.parse_args(sys.argv[1:]) is_windows = platform.system() == "Windows" uv_env = dict(os.environ) - uv_env.update({"UV_PYTHON_PREFERENCE": "only-system", "UV_PYTHON": args.python_version}) + uv_env.update({"UV_PYTHON": args.python_version}) + if not args.allow_uv_to_install_python: + uv_env.update({"UV_PYTHON_PREFERENCE": "only-system"}) uv_path = ((GITHUB_WINDOWS_RUNNER_BIN_PATH + "\\") if is_windows else "") + "uv" if is_windows: pwsh = shutil.which("pwsh") or shutil.which("powershell") diff --git a/template/.gitignore b/template/.gitignore index aa359644..fa36212d 100644 --- a/template/.gitignore +++ b/template/.gitignore @@ -44,8 +44,6 @@ pytest.log tests/__coverage__ test/__coverage__ coverage-report-pytest -.pytest_cache/ -.mypy_cache/ .coverage .coverage.* coverage.xml diff --git a/template/.pre-commit-config.yaml b/template/.pre-commit-config.yaml index 249101a5..66531bc6 100644 --- a/template/.pre-commit-config.yaml +++ b/template/.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: edb4e206047e89b93ebe08f1a2ccc3d581a70cc7 # frozen: v1 + rev: 6573587991823ef75e4d6ca97fe895f45e9f14e4 # frozen: v1 hooks: - id: typos exclude: | @@ -59,6 +59,7 @@ repos: (?x)^( .*/vendor_files/.*| .*tests/.*/__snapshots__/.*| + .*/openapi_codegen/.*| )$ - id: end-of-file-fixer # the XML formatter hook doesn't leave a blank line at the end, so excluding XML files from this hook to avoid conflicts @@ -70,10 +71,12 @@ repos: template/template/.copier-answers.yml.jinja| template/.copier-answers.yml.jinja| .*generated/graphql.ts| + .*/openapi_codegen/.*| .*tests/.*/__snapshots__/.*| .devcontainer/devcontainer-lock.json| .copier-answers.yml| .*\.xml| + .*\.svg| .*/vendor_files/.*| )$ - id: pretty-format-json @@ -85,6 +88,7 @@ repos: .*pyrightconfig.json| .*tsconfig.json| .*biome.jsonc| + .*/openapi_codegen/.*| .*tests/.*/__snapshots__/.*| .*/vendor_files/.*| )$ @@ -98,6 +102,7 @@ repos: exclude: | (?x)^( .*generated/graphql.ts| + .*/openapi_codegen/.*| .*/schema.graphql| .*pyrightconfig\.json| )$ @@ -124,6 +129,7 @@ repos: .*.jsonc| .*/vendor_files/.*| .*/schema.graphql| + .*/openapi_codegen/.*| .*generated/graphql.ts| template/.*| )$ @@ -148,6 +154,7 @@ repos: (?x)^( .*/__snapshots__/.*| .*/vendor_files/.*| + .*\.svg| )$ # Invalid File Checks @@ -170,17 +177,19 @@ repos: - id: check-yaml # .copier-answers.yml is an autogenerated YAML file by Copier that throws 'found unhashable key' errors # Helm charts contain other non-YAML markers that cause errors here. they should be checked with helm-lint instead + # VCRpy cassettes sometimes contain non-YAML markers that cause errors---but they're autogenerated anyway exclude: | (?x)^( .copier-answers.yml| - (.*/helm/.*)| + (.*/?helm/.*)| + (.*/tests/unit/.*/?cassettes/.*)| )$ - id: check-xml - id: check-merge-conflict - id: check-case-conflict - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 83987cd6ad8943c7f029b500b14aaf82c00a01fa # frozen: 0.34.0 + rev: 83b816d020105076daac266dbf6bfed199a2da93 # frozen: 0.34.1 hooks: - id: check-github-workflows @@ -234,7 +243,7 @@ repos: description: Runs hadolint to lint Dockerfiles - repo: https://github.com/astral-sh/ruff-pre-commit - rev: a113f03edeabb71305f025e6e14bd2cd68660e29 # frozen: v0.13.1 + rev: f9351c924055bf6c7b4a4670237d3ce141e9f57c # frozen: v0.14.0 hooks: - id: ruff name: ruff-src @@ -244,6 +253,7 @@ repos: (?x)^( .*/graphql_codegen/.*| .*/openapi_codegen/.*| + template/.*| )$ - id: ruff name: ruff-tests @@ -253,6 +263,7 @@ repos: (?x)^( .*/graphql_codegen/.*| .*/openapi_codegen/.*| + template/.*| )$ - id: ruff-format exclude: | @@ -262,7 +273,7 @@ repos: )$ - repo: https://github.com/pylint-dev/pylint - rev: 98942ba4126a6fe1657bad77027bcc11016d16da # frozen: v3.3.8 + rev: 9a3035053154ba0c3ca3b300d6bc9fa72b95d552 # frozen: v4.0.1 hooks: - id: pylint name: pylint diff --git a/template/CONTRIBUTING.md b/template/CONTRIBUTING.md index cd88f1f5..8272cfab 100644 --- a/template/CONTRIBUTING.md +++ b/template/CONTRIBUTING.md @@ -27,7 +27,7 @@ By participating in this project, you agree to abide by our [Code of Conduct](./ 1. **Fork the repository** on GitHub. 2. **Set up the Dev Container (Recommended Method)** - - Create a Github Codespace (`Code`->`Codespaces` in the Github web console of your cloned repository) OR click on the "Open in Devcontainer" link in the [Readme](./README.md) + - Create a GitHub Codespace (`Code`->`Codespaces` in the GitHub web console of your cloned repository) OR click on the "Open in Devcontainer" link in the [Readme](./README.md) 3. **Make Your Changes** - Create a branch for your feature or bug fix: diff --git a/template/_typos.toml b/template/_typos.toml index 3c948b8a..cc0ab6a0 100644 --- a/template/_typos.toml +++ b/template/_typos.toml @@ -22,5 +22,5 @@ extend-exclude = [ ".copier-answers.yml", # this is an autogenerated file, and sometimes the commit sha gets confused as being a word "**/__snapshots__/**", # Snapshots need to remain static "**/tests/**/cassettes/**/*.yaml", # URLs and other responses in VCR.py generated files should not be altered - "**/vendor_files/**" # if vendors mispell things, there may be other implications in other parts of their code, just leave vendor files alone + "**/vendor_files/**" # if vendors misspell things, there may be other implications in other parts of their code, just leave vendor files alone ] diff --git a/template/ruff-test.toml b/template/ruff-test.toml index 9994e410..407ecf89 100644 --- a/template/ruff-test.toml +++ b/template/ruff-test.toml @@ -12,7 +12,7 @@ ignore = [ "S101", # assert is definitely needed in test cases "S311", # pseudo-randomness is fine for test cases "TID252", # sometimes you can't use absolute imports in test cases for importing things within the tests, because they're not a true package or have conflicting namespaces - "TRY003", # tests dont need to create a custom exception classes, generally you want to throw an AssertionError with a message anyway + "TRY003", # tests don't need to create custom exception classes, generally you want to throw an AssertionError with a message anyway ] unfixable = [ diff --git a/tests/copier_data/data1.yaml b/tests/copier_data/data1.yaml index 38068589..20fb4737 100644 --- a/tests/copier_data/data1.yaml +++ b/tests/copier_data/data1.yaml @@ -3,6 +3,7 @@ repo_name: the_best_repo repo_org_name: great-company is_open_source: true description: Doing amazing things +install_claude_cli: false ssh_port_number: 12345 use_windows_in_ci: false install_aws_ssm_port_forwarding_plugin: true diff --git a/tests/copier_data/data2.yaml b/tests/copier_data/data2.yaml index 524fc1de..f47f8460 100644 --- a/tests/copier_data/data2.yaml +++ b/tests/copier_data/data2.yaml @@ -3,6 +3,7 @@ repo_name: another_repo repo_org_name: initech is_open_source: false description: Doing crazy things! So many things! +install_claude_cli: true ssh_port_number: 54321 use_windows_in_ci: true install_aws_ssm_port_forwarding_plugin: false diff --git a/tests/copier_data/data3.yaml b/tests/copier_data/data3.yaml index 6d80956c..0bf6f907 100644 --- a/tests/copier_data/data3.yaml +++ b/tests/copier_data/data3.yaml @@ -3,6 +3,7 @@ repo_name: the_best_repo repo_org_name: great-company is_open_source: true description: Doing amazing things +install_claude_cli: false ssh_port_number: 12345 use_windows_in_ci: false install_aws_ssm_port_forwarding_plugin: false diff --git a/uv.lock b/uv.lock index 9a612094..8c21b321 100644 --- a/uv.lock +++ b/uv.lock @@ -61,7 +61,7 @@ dependencies = [ requires-dist = [ { name = "copier", specifier = ">=9.10.2" }, { name = "copier-template-extensions", specifier = ">=0.3.3" }, - { name = "pyright", extras = ["nodejs"], specifier = ">=1.1.405" }, + { name = "pyright", extras = ["nodejs"], specifier = ">=1.1.406" }, { name = "pytest", specifier = ">=8.4.2" }, { name = "pytest-cov", specifier = ">=7.0.0" }, { name = "pytest-randomly", specifier = ">=4.0.1" }, @@ -384,15 +384,15 @@ wheels = [ [[package]] name = "pyright" -version = "1.1.405" +version = "1.1.406" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/6c/ba4bbee22e76af700ea593a1d8701e3225080956753bee9750dcc25e2649/pyright-1.1.405.tar.gz", hash = "sha256:5c2a30e1037af27eb463a1cc0b9f6d65fec48478ccf092c1ac28385a15c55763", size = 4068319, upload-time = "2025-09-04T03:37:06.776Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1a/524f832e1ff1962a22a1accc775ca7b143ba2e9f5924bb6749dce566784a/pyright-1.1.405-py3-none-any.whl", hash = "sha256:a2cb13700b5508ce8e5d4546034cb7ea4aedb60215c6c33f56cec7f53996035a", size = 5905038, upload-time = "2025-09-04T03:37:04.913Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" }, ] [package.optional-dependencies]