Hands-off Time: spec planner, auto-merge on Approve + green checks, next card, update workflow
- spec issues (label spec) become queued cards, parsed deterministically, seat fallback - TIME_AUTOMERGE=on: squash-merge when the latest trusted verdict is Approve and all checks pass - Object, red or missing checks, or protected paths go to needs-human - merged card frees the slot; the next unblocked queued card gets ready and dispatches in the same run - update.yml pulls the engine from teahubxyz/time into project repos via PR - ci.yml runs Time's own tests Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UpT7eWzeLhRwuYmsSQnbRb
This commit is contained in:
1 parent
9108adf4c6
commit
889e93799e
9 files changed
+379
-14
No files matched your search
@@ -1,21 +1,32 @@
|
||||
name: heartbeat
|
||||
# Time's clock: hourly, and right away when a card gets the `ready` label (dry-run until TIME_MODE=live).
|
||||
# Time's clock: hourly, right away when a card gets `ready` or a spec gets `spec`, and when a PR is reviewed
|
||||
# (dry-run until TIME_MODE=live; merges only with TIME_AUTOMERGE=on).
|
||||
on:
|
||||
schedule:
|
||||
- cron: "7 * * * *"
|
||||
workflow_dispatch:
|
||||
issues:
|
||||
types: [labeled]
|
||||
pull_request_review:
|
||||
types: [submitted]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
permissions:
|
||||
contents: read
|
||||
contents: write # squash-merge approved, green PRs
|
||||
issues: write
|
||||
pull-requests: write
|
||||
checks: read
|
||||
concurrency:
|
||||
group: heartbeat
|
||||
cancel-in-progress: false
|
||||
jobs:
|
||||
tick:
|
||||
if: github.event_name != 'issues' || github.event.label.name == 'ready'
|
||||
# issues: only `ready`/`spec` labels. comments: only on PRs, only a reviewer verdict (Approve/Object).
|
||||
if: >-
|
||||
(github.event_name != 'issues' || contains(fromJSON('["ready","spec"]'), github.event.label.name)) &&
|
||||
(github.event_name != 'issue_comment' || (github.event.issue.pull_request &&
|
||||
(startsWith(github.event.comment.body, '**Approve') || startsWith(github.event.comment.body, 'Approve') ||
|
||||
startsWith(github.event.comment.body, '**Object') || startsWith(github.event.comment.body, 'Object'))))
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
@@ -32,3 +43,8 @@ jobs:
|
||||
TIME_CURSOR_MODEL: ${{ vars.TIME_CURSOR_MODEL }}
|
||||
TIME_REVIEW: ${{ vars.TIME_REVIEW }}
|
||||
TIME_STUCK_HOURS: ${{ vars.TIME_STUCK_HOURS }}
|
||||
TIME_AUTOMERGE: ${{ vars.TIME_AUTOMERGE }}
|
||||
TIME_REQUIRE_CHECKS: ${{ vars.TIME_REQUIRE_CHECKS }}
|
||||
TIME_PROTECTED: ${{ vars.TIME_PROTECTED }}
|
||||
TIME_PARALLEL: ${{ vars.TIME_PARALLEL }}
|
||||
TIME_PLANNER: ${{ vars.TIME_PLANNER }}
|
||||
Reference in new issue
Block a user