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
26 changes: 26 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
reviews:
profile: assertive
path_instructions:
- 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:
eslint: # when the code contains typescript, eslint will be run by pre-commit, and coderabbit often generates false positives
enabled: false
ruff: # when the code contains python, ruff will be run by pre-commit, and coderabbit often generates false positives
enabled: false
pylint: # when the code contains python, pylint will be run by pre-commit, and coderabbit often generates false positives
enabled: false
flake8: # we use ruff instead (when we use Python)
enabled: false
poem: false
# the commit status is driven by our repository config and required checks, we don't want CodeRabbit messing with it
commit_status: false
auto_review:
# a main purpose of opening a draft PR might be to get CodeRabbit feedback early
drafts: true
finishing_touches:
docstrings:
enabled: false # if we wanted AI to generate docstrings, it would be via CLI, not in the GitHub interface
unit_tests:
enabled: false # Quis custodiet ipsos custodes? not something we want AI doing, especially not via the GitHub interface
2 changes: 1 addition & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Changes here will be overwritten by Copier
_commit: v0.0.77
_commit: v0.0.80-10-gbbb2ef4
_src_path: gh:LabAutomationAndScreening/copier-base-template.git
description: Copier template for creating Python libraries and executables
install_claude_cli: false
Expand Down
6 changes: 3 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"coderabbit.coderabbit-vscode@0.15.2",
"ms-vscode.live-server@0.5.2025051301",
"MS-vsliveshare.vsliveshare@1.0.5905",
"github.copilot@1.380.1802",
"github.copilot-chat@0.33.2025101401",
"github.copilot@1.388.0",
"github.copilot-chat@0.33.2025102701",

// Python
"ms-python.python@2025.17.2025100201",
Expand Down Expand Up @@ -63,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): a5dbeab3 # spellchecker:disable-line
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): ac3ca44a # spellchecker:disable-line
}
16 changes: 4 additions & 12 deletions .devcontainer/install-ci-tooling.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import tempfile
from pathlib import Path

UV_VERSION = "0.9.2"
PNPM_VERSION = "10.18.3"
COPIER_VERSION = "9.10.2"
UV_VERSION = "0.9.7"
PNPM_VERSION = "10.20.0"
COPIER_VERSION = "9.10.3"
COPIER_TEMPLATE_EXTENSIONS_VERSION = "0.3.3"
PRE_COMMIT_VERSION = "4.3.0"
GITHUB_WINDOWS_RUNNER_BIN_PATH = r"C:\Users\runneradmin\.local\bin"
Expand All @@ -36,21 +36,13 @@
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
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,
)
print(result.stdout)


if __name__ == "__main__":
Expand Down
11 changes: 8 additions & 3 deletions .github/actions/install_deps/action.yml
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 All @@ -59,7 +64,7 @@ runs:

- name: Setup node
if: ${{ inputs.node-version != 'notUsing' }}
uses: actions/setup-node@v5.0.0
uses: actions/setup-node@v6.0.0
with:
node-version: ${{ inputs.node-version }}

Expand All @@ -70,13 +75,13 @@ runs:

- name: OIDC Auth for CodeArtifact
if: ${{ inputs.code-artifact-auth-role-name != 'no-code-artifact' }}
uses: aws-actions/configure-aws-credentials@v5.0.0
uses: aws-actions/configure-aws-credentials@v5.1.0
with:
role-to-assume: arn:aws:iam::${{ inputs.code-artifact-auth-role-account-id }}:role/${{ inputs.code-artifact-auth-role-name }}
aws-region: ${{ inputs.code-artifact-auth-region }}

- 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
6 changes: 3 additions & 3 deletions .github/reusable_workflows/build-docker-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:

- name: OIDC Auth for ECR
if: ${{ inputs.push-role-name != 'no-push' }}
uses: aws-actions/configure-aws-credentials@v5.0.0
uses: aws-actions/configure-aws-credentials@v5.1.0
with:
role-to-assume: arn:aws:iam::${{ steps.parse_ecr_url.outputs.aws_account_id }}:role/${{ inputs.push-role-name }}
aws-region: ${{ steps.parse_ecr_url.outputs.aws_region }}
Expand Down Expand Up @@ -128,7 +128,7 @@ jobs:

- name: Build Docker Image
if: ${{ (inputs.save-as-artifact && inputs.push-role-name == 'no-push') || steps.check-if-exists.outputs.status == 'notfound' }}
uses: docker/build-push-action@v6.16.0
uses: docker/build-push-action@v6.18.0
with:
context: ${{ inputs.context }}
push: ${{ inputs.push-role-name != 'no-push' && steps.check-if-exists.outputs.status == 'notfound' }}
Expand All @@ -155,7 +155,7 @@ jobs:

- name: Upload Docker Image Artifact
if: ${{ inputs.save-as-artifact }}
uses: actions/upload-artifact@v4.6.2
uses: actions/upload-artifact@v5.0.0
with:
name: ${{ steps.calculate-build-context-hash.outputs.image_name_no_slashes }}
path: ${{ steps.calculate-build-context-hash.outputs.image_name_no_slashes }}.tar
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,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
24 changes: 12 additions & 12 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ repos:
(?x)^(
.*/vendor_files/.*|
.*tests/.*/__snapshots__/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
)$
- 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 @@ -71,7 +71,7 @@ repos:
template/template/.copier-answers.yml.jinja|
template/.copier-answers.yml.jinja|
.*generated/graphql.ts|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
.*tests/.*/__snapshots__/.*|
.devcontainer/devcontainer-lock.json|
.copier-answers.yml|
Expand All @@ -88,7 +88,7 @@ repos:
.*pyrightconfig.json|
.*tsconfig.json|
.*biome.jsonc|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
.*tests/.*/__snapshots__/.*|
.*/vendor_files/.*|
)$
Expand All @@ -102,7 +102,7 @@ repos:
exclude: |
(?x)^(
.*generated/graphql.ts|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
.*/schema.graphql|
.*pyrightconfig\.json|
)$
Expand All @@ -129,7 +129,7 @@ repos:
.*.jsonc|
.*/vendor_files/.*|
.*/schema.graphql|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
.*generated/graphql.ts|
template/.*|
)$
Expand Down Expand Up @@ -243,7 +243,7 @@ repos:
description: Runs hadolint to lint Dockerfiles

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: f9351c924055bf6c7b4a4670237d3ce141e9f57c # frozen: v0.14.0
rev: 3db93a2be6f214ed722bf7bce095ec1b1715422a # frozen: v0.14.2
hooks:
- id: ruff
name: ruff-src
Expand All @@ -252,7 +252,7 @@ repos:
exclude: |
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
template/.*|
)$
- id: ruff
Expand All @@ -262,26 +262,26 @@ repos:
exclude: |
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
template/.*|
)$
- id: ruff-format
exclude: |
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
)$

- repo: https://github.com/pylint-dev/pylint
rev: 9a3035053154ba0c3ca3b300d6bc9fa72b95d552 # frozen: v4.0.1
rev: 0eb92d25fd38ba5bad2f8d2ea7df63ad23e18ae3 # frozen: v4.0.2
hooks:
- id: pylint
name: pylint
# exclude the template files---duplication within them will be discovered during CI of that template instantiation
exclude: |
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
template/.*|
)$
args:
Expand All @@ -297,7 +297,7 @@ repos:
exclude: |
(?x)^(
.*/graphql_codegen/.*|
.*/openapi_codegen/.*|
.*/generated/open[-_]api/.*|
)$
# don't pass filenames else the command line sees them twice
pass_filenames: false
Expand Down
Loading