The queue: parking, the operator's order, blocked items (M2.2)
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 3m26s
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 3m26s
Several work items on the new loop (L1, D4): - Switching parks the item on the workspace: its work is committed and its branch pushed; resuming checks the item's branch back out. Branches of open items are never set aside by a fresh workspace. - Next item: the operator's "do #N next" first, otherwise the oldest. - Issues with open Gitea dependencies are blocked until they close, checked at intake and on every round; status shows blocked items and the line. Tests: queue unit tests, the property walk over several issues with dependencies and a new parked_work_safe property (it catches parking disabled), and an end-to-end test with two issues where B depends on A. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
d504588a57
commit
cceb30c729
11 files changed
+657
-85
No files matched your search
@@ -57,11 +57,14 @@ class Milestones:
|
||||
|
||||
# -- a work item's workspace (D3) ------------------------------------------
|
||||
|
||||
def prepare(self, item_branch: str) -> list[str]:
|
||||
def prepare(self, item_branch: str, *, keep: tuple[str, ...] = ()) -> list[str]:
|
||||
"""A fresh workspace for a work item: fetch, set aside (never
|
||||
discard) whatever was left, check out a clean default branch, and put
|
||||
the item on a branch of its own. Returns what was set aside."""
|
||||
the item on a branch of its own. Branches starting with a ``keep``
|
||||
prefix belong to open work items, which parking has pushed: they are
|
||||
left alone. Returns what was set aside."""
|
||||
git = self._git
|
||||
self.park(keep=keep)
|
||||
git.fetch(credential=self._credential)
|
||||
stamp = time.strftime("%Y%m%d-%H%M%S")
|
||||
notes: list[str] = []
|
||||
@@ -73,6 +76,8 @@ class Milestones:
|
||||
for branch in git.local_branches():
|
||||
if branch == self._base or branch.startswith(f"{SET_ASIDE}/"):
|
||||
continue
|
||||
if keep and branch.startswith(keep):
|
||||
continue
|
||||
git.rename_branch(branch, f"{SET_ASIDE}/{stamp}/{branch}")
|
||||
notes.append(f"branch {branch}, as {SET_ASIDE}/{stamp}/{branch}")
|
||||
if self._base in git.local_branches() and self._ahead_of_origin():
|
||||
@@ -83,6 +88,42 @@ class Milestones:
|
||||
git.checkout_new_branch(item_branch)
|
||||
return notes
|
||||
|
||||
# -- parking and resuming (L1, D4) -----------------------------------------
|
||||
|
||||
def park(self, *, keep: tuple[str, ...]) -> str | None:
|
||||
"""Before another item uses the workspace: commit whatever the item
|
||||
on it left, and push its branch, so nothing of a parked item lives
|
||||
only on the build VM. Only a harness branch of an open item (one
|
||||
starting with a ``keep`` prefix) is parked; returns its name."""
|
||||
git = self._git
|
||||
branch = git.current_branch()
|
||||
if not keep or not branch.startswith(keep):
|
||||
return None
|
||||
git.commit_all("WIP: parked while another work item runs")
|
||||
if git.remote_sha(self._remote, branch, credential=self._credential) != (
|
||||
git.head_sha()
|
||||
):
|
||||
git.push(self._remote, branch, credential=self._credential)
|
||||
return branch
|
||||
|
||||
def resume(self, branch: str, *, keep: tuple[str, ...], mine: str = "") -> None:
|
||||
"""Back to a parked item: park whatever is on the workspace now, then
|
||||
check out the item's branch. The local branch wins when it exists (it
|
||||
can only be ahead: parking pushed it); otherwise it comes from origin.
|
||||
A workspace already on one of the item's own branches (``mine``, a
|
||||
prefix) is where it left off, and stays."""
|
||||
git = self._git
|
||||
current = git.current_branch()
|
||||
if current == branch or (mine and current.startswith(mine)):
|
||||
return
|
||||
self.park(keep=keep)
|
||||
if branch in git.local_branches():
|
||||
git.checkout_existing_branch(branch)
|
||||
git.reset_to(branch, branch)
|
||||
else:
|
||||
git.fetch(credential=self._credential)
|
||||
git.reset_to(branch, f"origin/{branch}")
|
||||
|
||||
def _ahead_of_origin(self) -> bool:
|
||||
current = self._git.current_branch()
|
||||
try:
|
||||
|
||||
Reference in new issue
Block a user