CI / checks (push) Skipped
CI / checks (pull_request) Successful in 2m17s
The first live run of the new loop's e2e test found that a fact recorded while start_milestone was in flight landed between the tool call and its result; both API formats reject that, so every later request in the run failed. Views now keep each result right after its call. Scripted test models check the APIs' ordering rules, so this can't pass unit tests again. The e2e tests no longer depend on the sandbox's history: each run asks for a uniquely named function and works against a base branch of its own, deleted afterwards. The review step asks for a change that can't already be there. The scripted operator gives up after five fruitless answers, and each run keeps its state store for inspection. The driver's prompt says review fixes stay in the current milestone. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
43 lines
1.4 KiB
Python
43 lines
1.4 KiB
Python
"""Shared by the end-to-end tests: each run gets work that can't already be
|
|
done, and a base branch of its own, so runs never depend on one another or
|
|
on what earlier runs merged."""
|
|
|
|
import contextlib
|
|
import os
|
|
from collections.abc import Iterator
|
|
|
|
from nisse_dev.gitea import GiteaClient, GiteaError
|
|
|
|
|
|
def task(run: str) -> str:
|
|
"""A request no earlier run can have fulfilled."""
|
|
return (
|
|
f"Add a function vowels_{run}(text) to the sandbox package that returns "
|
|
"how many of a, e, i, o, u (either case) the text contains, with tests."
|
|
)
|
|
|
|
|
|
def operator_gitea(url: str) -> GiteaClient:
|
|
token = os.environ.get("NISSE_OPERATOR_TOKEN", "")
|
|
assert token.strip(), (
|
|
"NISSE_OPERATOR_TOKEN is not set: the test operator's Gitea token"
|
|
)
|
|
return GiteaClient(url, token)
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def base_branch(operator: GiteaClient, repo: str, run: str) -> Iterator[str]:
|
|
"""A branch off main for this run's PRs to target and merge into, so
|
|
nothing accumulates in main; deleted afterwards."""
|
|
name = f"e2e-base-{run}"
|
|
operator._request(
|
|
"POST",
|
|
f"/repos/{repo}/branches",
|
|
json={"new_branch_name": name, "old_branch_name": "main"},
|
|
)
|
|
try:
|
|
yield name
|
|
finally:
|
|
with contextlib.suppress(GiteaError):
|
|
operator._request("DELETE", f"/repos/{repo}/branches/{name}")
|