Skip to content

Commit 9194ed8

Browse files
authored
Copier update: pulumi install fix (#88)
Pull in upstream template changes <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added testing guidance for validating tests that pass immediately without implementation changes. * Added testing guideline requiring presence assertions before absence checks to prevent false passes. * **Chores** * Updated template version and development container configuration. * Enhanced development setup with improved install script existence checks. * Added timeout protection to CI workflow jobs to prevent hanging executions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 6df486c commit 9194ed8

File tree

10 files changed

+56
-10
lines changed

10 files changed

+56
-10
lines changed

.claude/commands/red.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ This phase is **not part of the regular TDD workflow** and must only be applied
9494
- Once sufficient understanding is achieved, all spike code is discarded, and normal TDD resumes starting from the **Red Phase**.
9595
- A Spike is justified only when it is impossible to define a meaningful failing test due to technical uncertainty or unknown system behavior.
9696

97+
### If a New Test Passes Immediately
98+
99+
If a newly written test passes without any implementation change, do not assume it is correct. Verify it actually exercises the intended behavior:
100+
101+
1. Identify the implementation line most likely responsible for the pass
102+
2. Temporarily remove that line
103+
3. Run the **full test suite** (not just the new test)
104+
105+
Then interpret the result:
106+
107+
- **Only the new test fails** — the line was never driven by a prior test. This is accidental over-implementation: delete the line permanently and proceed to the green phase to reintroduce it properly.
108+
- **Other existing tests also fail** — the line was already legitimately required by prior work. The new test is valid regression coverage. Restore the line; the test is confirmed correct as written.
109+
110+
In both cases, confirm the new test fails for the expected reason before proceeding (the right assertion, not a syntax or import error).
111+
97112
### General Information
98113

99114
- Sometimes the test output shows as no tests have been run when a new test is failing due to a missing import or constructor. In such cases, allow the agent to create simple stubs. Ask them if they forgot to create a stub if they are stuck.

.copier-answers.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Changes here will be overwritten by Copier
2-
_commit: v0.0.109
2+
_commit: v0.0.110
33
_src_path: gh:LabAutomationAndScreening/copier-base-template.git
44
description: Copier template for creating Python libraries and executables
55
install_claude_cli: true

.devcontainer/devcontainer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@
6565
"initializeCommand": "sh .devcontainer/initialize-command.sh",
6666
"onCreateCommand": "sh .devcontainer/on-create-command.sh",
6767
"postStartCommand": "sh .devcontainer/post-start-command.sh"
68-
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): d77a3ff3 # spellchecker:disable-line
68+
// Devcontainer context hash (do not manually edit this, it's managed by a pre-commit hook): 087a93d5 # spellchecker:disable-line
6969
}

.devcontainer/manual-setup-deps.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
REPO_ROOT_DIR = Path(__file__).parent.parent.resolve()
1313
ENVS_CONFIG = REPO_ROOT_DIR / ".devcontainer" / "envs.json"
14+
PULUMI_CLI_INSTALL_SCRIPT = REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"
1415
UV_PYTHON_ALREADY_CONFIGURED = "UV_PYTHON" in os.environ
1516
parser = argparse.ArgumentParser(description="Manual setup for dependencies in the repo")
1617
_ = parser.add_argument(
@@ -140,10 +141,15 @@ def main():
140141
and env.lock_file.exists()
141142
and '"pulumi"' in env.lock_file.read_text()
142143
):
143-
_ = subprocess.run(
144-
["sh", str(REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"), str(env.lock_file)],
145-
check=True,
146-
)
144+
if not PULUMI_CLI_INSTALL_SCRIPT.exists():
145+
print(
146+
f"Pulumi CLI install script not found at {PULUMI_CLI_INSTALL_SCRIPT}, skipping Pulumi CLI installation"
147+
)
148+
else:
149+
_ = subprocess.run(
150+
["sh", str(PULUMI_CLI_INSTALL_SCRIPT), str(env.lock_file)],
151+
check=True,
152+
)
147153
elif env.package_manager == PackageManager.PNPM:
148154
pnpm_command = ["pnpm", "install", "--dir", str(env.path)]
149155
if env_check_lock:

.github/workflows/ci.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323

2424
check-skip-duplicate:
2525
runs-on: ubuntu-24.04
26+
timeout-minutes: 2
2627
outputs:
2728
should-run: ${{ steps.check.outputs.should-run }}
2829
steps:

AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This project is a Copier template used to generate other copier templates. It is
2323
- Avoid magic values in comparisons in tests in all languages (like ruff rule PLR2004 specifies)
2424
- 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.
2525
- 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)] == []).
26+
- 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.
2627
- 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.
2728

2829
### Python Testing

template/.claude/commands/red.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ This phase is **not part of the regular TDD workflow** and must only be applied
9494
- Once sufficient understanding is achieved, all spike code is discarded, and normal TDD resumes starting from the **Red Phase**.
9595
- A Spike is justified only when it is impossible to define a meaningful failing test due to technical uncertainty or unknown system behavior.
9696

97+
### If a New Test Passes Immediately
98+
99+
If a newly written test passes without any implementation change, do not assume it is correct. Verify it actually exercises the intended behavior:
100+
101+
1. Identify the implementation line most likely responsible for the pass
102+
2. Temporarily remove that line
103+
3. Run the **full test suite** (not just the new test)
104+
105+
Then interpret the result:
106+
107+
- **Only the new test fails** — the line was never driven by a prior test. This is accidental over-implementation: delete the line permanently and proceed to the green phase to reintroduce it properly.
108+
- **Other existing tests also fail** — the line was already legitimately required by prior work. The new test is valid regression coverage. Restore the line; the test is confirmed correct as written.
109+
110+
In both cases, confirm the new test fails for the expected reason before proceeding (the right assertion, not a syntax or import error).
111+
97112
### General Information
98113

99114
- Sometimes the test output shows as no tests have been run when a new test is failing due to a missing import or constructor. In such cases, allow the agent to create simple stubs. Ask them if they forgot to create a stub if they are stuck.

template/.devcontainer/manual-setup-deps.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
REPO_ROOT_DIR = Path(__file__).parent.parent.resolve()
1313
ENVS_CONFIG = REPO_ROOT_DIR / ".devcontainer" / "envs.json"
14+
PULUMI_CLI_INSTALL_SCRIPT = REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"
1415
UV_PYTHON_ALREADY_CONFIGURED = "UV_PYTHON" in os.environ
1516
parser = argparse.ArgumentParser(description="Manual setup for dependencies in the repo")
1617
_ = parser.add_argument(
@@ -140,10 +141,15 @@ def main():
140141
and env.lock_file.exists()
141142
and '"pulumi"' in env.lock_file.read_text()
142143
):
143-
_ = subprocess.run(
144-
["sh", str(REPO_ROOT_DIR / ".devcontainer" / "install-pulumi-cli.sh"), str(env.lock_file)],
145-
check=True,
146-
)
144+
if not PULUMI_CLI_INSTALL_SCRIPT.exists():
145+
print(
146+
f"Pulumi CLI install script not found at {PULUMI_CLI_INSTALL_SCRIPT}, skipping Pulumi CLI installation"
147+
)
148+
else:
149+
_ = subprocess.run(
150+
["sh", str(PULUMI_CLI_INSTALL_SCRIPT), str(env.lock_file)],
151+
check=True,
152+
)
147153
elif env.package_manager == PackageManager.PNPM:
148154
pnpm_command = ["pnpm", "install", "--dir", str(env.path)]
149155
if env_check_lock:

template/.github/workflows/ci.yaml.jinja

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ jobs:
2323

2424
check-skip-duplicate:
2525
runs-on: {% endraw %}{{ gha_linux_runner }}{% raw %}
26+
timeout-minutes: {% endraw %}{{ gha_short_timeout_minutes }}{% raw %}
2627
permissions:
2728
contents: read
2829
pull-requests: read # needed to check if PR exists for current branch

template/AGENTS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ This project is a Python library.
2323
- Avoid magic values in comparisons in tests in all languages (like ruff rule PLR2004 specifies)
2424
- 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.
2525
- 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)] == []).
26+
- 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.
2627
- 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.
2728

2829
### Python Testing

0 commit comments

Comments
 (0)