Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
20 changes: 11 additions & 9 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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",
Expand All @@ -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"
Expand All @@ -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
}
14 changes: 11 additions & 3 deletions .devcontainer/install-ci-tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ pytest.log
tests/__coverage__
test/__coverage__
coverage-report-pytest
.pytest_cache/
.mypy_cache/
.coverage
.coverage.*
coverage.xml
Expand Down
21 changes: 16 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand All @@ -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
Expand All @@ -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
Expand All @@ -85,6 +88,7 @@ repos:
.*pyrightconfig.json|
.*tsconfig.json|
.*biome.jsonc|
.*/openapi_codegen/.*|
.*tests/.*/__snapshots__/.*|
.*/vendor_files/.*|
)$
Expand All @@ -98,6 +102,7 @@ repos:
exclude: |
(?x)^(
.*generated/graphql.ts|
.*/openapi_codegen/.*|
.*/schema.graphql|
.*pyrightconfig\.json|
)$
Expand All @@ -124,6 +129,7 @@ repos:
.*.jsonc|
.*/vendor_files/.*|
.*/schema.graphql|
.*/openapi_codegen/.*|
.*generated/graphql.ts|
template/.*|
)$
Expand All @@ -148,6 +154,7 @@ repos:
(?x)^(
.*/__snapshots__/.*|
.*/vendor_files/.*|
.*\.svg|
)$

# Invalid File Checks
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -244,6 +253,7 @@ repos:
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
template/.*|
)$
- id: ruff
name: ruff-tests
Expand All @@ -253,6 +263,7 @@ repos:
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
template/.*|
)$
- id: ruff-format
exclude: |
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
]
5 changes: 5 additions & 0 deletions copier.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
52 changes: 28 additions & 24 deletions extensions/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
2 changes: 1 addition & 1 deletion ruff-test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
Loading