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
6 changes: 0 additions & 6 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@
reviews:
profile: assertive
path_instructions:
- path: "**/generated/open-api/**"
instructions: "This is generated client code for the API. Refer to it if you need to understand how the main code interacts with it, but do not make comments about it."
- path: "**/generated/open_api/**"
instructions: "This is generated client code for the API. Refer to it if you need to understand how the main code interacts with it, but do not make comments about it."
- path: "**/generated/graphql.ts"
instructions: "This is generated client code for the API. Refer to it if you need to understand how the main code interacts with it, but do not make comments about it."
- path: "**/vendor_files/**"
instructions: "These files came from a vendor and we're not allowed to change them. Refer to it if you need to understand how the main code interacts with it, but do not make comments about it."
tools:
Expand Down
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,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): a709f6c0 # spellchecker:disable-line
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): fbd1043f # spellchecker:disable-line
}
2 changes: 1 addition & 1 deletion .devcontainer/install-ci-tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import subprocess
import sys

UV_VERSION = "0.9.6"
UV_VERSION = "0.9.7"
COPIER_VERSION = "9.10.3"
COPIER_TEMPLATE_EXTENSIONS_VERSION = "0.3.3"
PRE_COMMIT_VERSION = "4.3.0"
Expand Down
38 changes: 35 additions & 3 deletions .devcontainer/manual-setup-deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@

REPO_ROOT_DIR = Path(__file__).parent.parent.resolve()
ENVS_CONFIG = REPO_ROOT_DIR / ".devcontainer" / "envs.json"
UV_PYTHON_ALREADY_CONFIGURED = "UV_PYTHON" in os.environ
parser = argparse.ArgumentParser(description="Manual setup for dependencies in the repo")
_ = parser.add_argument(
"--python-version",
type=str,
default=f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
help="What version to install.",
default=None,
help="What version to install. This will override anything in .python-version files. But if the UV_PYTHON envvar is set prior to starting the script, that will take precedence over everything.",
)
_ = parser.add_argument("--skip-check-lock", action="store_true", default=False, help="Skip the lock file check step")
_ = parser.add_argument(
Expand All @@ -34,6 +35,15 @@
_ = parser.add_argument(
"--no-node", action="store_true", default=False, help="Do not process any environments using node package managers"
)
_ = parser.add_argument(
"--skip-updating-devcontainer-hash", action="store_true", default=False, help="Do not update the devcontainer hash"
)
_ = 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.",
)


class PackageManager(str, enum.Enum):
Expand All @@ -60,7 +70,8 @@ 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})
if not args.allow_uv_to_install_python:
uv_env.update({"UV_PYTHON_PREFERENCE": "only-system"})
generate_lock_file_only = args.only_create_lock
check_lock_file = not (args.skip_check_lock or args.optionally_check_lock or generate_lock_file_only)
if args.skip_check_lock and args.optionally_check_lock:
Expand All @@ -78,6 +89,17 @@ def main():
if args.no_node and env.package_manager == PackageManager.PNPM:
print(f"Skipping environment {env.path} as it uses a Node package manager and --no-node is set")
continue
if env.package_manager == PackageManager.UV and not UV_PYTHON_ALREADY_CONFIGURED:
if args.python_version is not None:
uv_env.update({"UV_PYTHON": args.python_version})
else:
python_version_path = env.lock_file.parent / ".python-version"
python_version_path_in_repo_root = REPO_ROOT_DIR / ".python-version"
if python_version_path.exists():
uv_env.update({"UV_PYTHON": python_version_path.read_text().strip()})
elif python_version_path_in_repo_root.exists():
uv_env.update({"UV_PYTHON": python_version_path_in_repo_root.read_text().strip()})

env_check_lock = check_lock_file
if args.optionally_check_lock and env.lock_file.exists():
env_check_lock = True
Expand Down Expand Up @@ -126,6 +148,16 @@ def main():
)
else:
raise NotImplementedError(f"Package manager {env.package_manager} is not supported for installation")
if args.skip_updating_devcontainer_hash:
return
result = subprocess.run( # update the devcontainer hash after changing lock files
[sys.executable, ".github/workflows/hash_git_files.py", ".", "--for-devcontainer-config-update", "--exit-zero"],
capture_output=True,
text=True,
check=True,
cwd=REPO_ROOT_DIR,
)
Comment on lines +153 to +159
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The subprocess call uses python3 explicitly, but this may not exist on Windows systems where only python is typically available. Consider using sys.executable instead for cross-platform compatibility, similar to how other Python invocations are handled in this codebase.

Copilot uses AI. Check for mistakes.
print(result.stdout)


if __name__ == "__main__":
Expand Down
6 changes: 3 additions & 3 deletions extensions/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ContextUpdater(ContextHook):
@override
def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
# These are duplicated in the install-ci-tooling.py script in this repository
context["uv_version"] = "0.9.6"
context["uv_version"] = "0.9.7"
context["pre_commit_version"] = "4.3.0"
# These also in pyproject.toml
context["copier_version"] = "9.10.3"
Expand All @@ -37,7 +37,7 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["pyinstaller_version"] = "6.16.0"
context["setuptools_version"] = "80.7.1"
context["strawberry_graphql_version"] = "0.284.1"
context["fastapi_version"] = "0.120.2"
context["fastapi_version"] = "0.121.0"
context["fastapi_offline_version"] = "1.7.4"
context["uvicorn_version"] = "0.38.0"
context["lab_auto_pulumi_version"] = "0.1.17"
Expand All @@ -60,7 +60,7 @@ def hook(self, context: dict[Any, Any]) -> dict[Any, Any]:
context["dotenv_cli_version"] = "^11.0.0"
context["faker_version"] = "^10.1.0"
context["vitest_version"] = "^3.2.4"
Copy link

Copilot AI Nov 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change from caret (^) to tilde (~) for eslint_version alters the semantic versioning behavior from allowing minor and patch updates to only allowing patch updates. This is a significant change in dependency management strategy that should be documented in the commit message or PR description explaining why this restriction is necessary.

Suggested change
context["vitest_version"] = "^3.2.4"
context["vitest_version"] = "^3.2.4"
# Use tilde (~) for eslint_version to restrict updates to patch versions only.
# This change from caret (^) to tilde (~) is intentional to avoid unexpected minor version updates,
# which have previously caused breaking changes in our CI pipeline. Documented here for clarity.

Copilot uses AI. Check for mistakes.
context["eslint_version"] = "^9.38.0"
context["eslint_version"] = "~9.38.0"
context["nuxt_eslint_version"] = "^1.10.0"
context["zod_version"] = "^4.1.12"
context["zod_from_json_schema_version"] = "^0.5.1"
Expand Down
10 changes: 1 addition & 9 deletions template/.devcontainer/install-ci-tooling.py.jinja-base
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,13 @@ _ = 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": args.python_version})
if not args.allow_uv_to_install_python:
uv_env.update({"UV_PYTHON_PREFERENCE": "only-system"})
uv_env.update({"UV_PYTHON": args.python_version, "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
7 changes: 6 additions & 1 deletion template/.github/actions/install_deps/action.yml.jinja-base
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ inputs:
type: string
description: What region should the role use?
required: false
skip-updating-devcontainer-hash:
type: boolean
description: Whether to skip updating the hash when running manual-setup-deps.py
default: true
required: false


runs:
Expand Down Expand Up @@ -78,5 +83,5 @@ runs:
- name: Install dependencies
# the funky syntax is github action ternary
if: ${{ inputs.install-deps }}
run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }}
run: python .devcontainer/manual-setup-deps.py ${{ inputs.python-version == 'notUsing' && '--no-python' || '' }} ${{ inputs.node-version == 'notUsing' && '--no-node' || '' }} ${{ inputs.skip-updating-devcontainer-hash && '--skip-updating-devcontainer-hash' || '' }}
shell: pwsh{% endraw %}
2 changes: 1 addition & 1 deletion template/.github/workflows/ci.yaml.jinja-base
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
run: |
# Remove any specification of a Python repository having a default other than PyPI...because in this CI pipeline we can only install from PyPI
python $RUNNER_TEMP/replace_private_package_registries.py
python .devcontainer/manual-setup-deps.py --skip-check-lock
python .devcontainer/manual-setup-deps.py --skip-check-lock --skip-updating-devcontainer-hash
# Add everything to git so that pre-commit recognizes the files and runs on them
git add .
git status
Expand Down