Repository navigation
fix(kix): continue a retried job from its published branch #171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4a225c3
5b996d4
da8da9f
2509d21
3bef3fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -557,27 +557,34 @@ export async function createJob(db: D1Database, input: NewJob, now: number) { | |
| const pin = [runner, runner, input.actor, trusted, account, account]; | ||
| const id = crypto.randomUUID(); | ||
| // The insert checks the project and pins again, since a pause or a | ||
| // runner's status can commit after the request read them. | ||
| // runner's status can commit after the request read them. An iteration | ||
| // continues the pull request's existing head branch. Retrying a target | ||
| // whose latest job failed continues that job's branch and pull request | ||
| // where it left them, as a reassigned attempt would. | ||
| const [insert, active, enabled, pinned] = await db.batch([ | ||
| db | ||
| .prepare( | ||
| `INSERT OR IGNORE INTO jobs(id,repository,workflow,target,revision,branch,head,actor,trusted,pinRunner,pinAccount,state,createdAt,updatedAt) | ||
| SELECT ?,id,?,?,?,?,?,?,?,?,?,'queued',?,? FROM github_projects WHERE id=? AND state='enabled' AND ${pinnable}`, | ||
| `INSERT OR IGNORE INTO jobs(id,repository,workflow,target,revision,branch,head,pending,pendingAt,pull,actor,trusted,pinRunner,pinAccount,state,createdAt,updatedAt) | ||
| SELECT ?,p.id,?,?,?,?,COALESCE(?,f.head),f.pending,f.pendingAt,f.pull,?,?,?,?,'queued',?,? FROM github_projects p | ||
| LEFT JOIN jobs f ON ?<>'iterate' AND f.state='failed' AND f.branch=? AND f.id=(SELECT id FROM jobs WHERE repository=p.id AND target=? ORDER BY createdAt DESC,id LIMIT 1) | ||
| WHERE p.id=? AND p.state='enabled' AND ${pinnable}`, | ||
| ) | ||
| .bind( | ||
| id, | ||
| input.workflow, | ||
| input.target, | ||
| input.revision, | ||
| input.branch, | ||
| // An iteration continues the pull request's existing head branch. | ||
| input.workflow === "iterate" ? input.revision : null, | ||
| input.actor, | ||
| trusted, | ||
| runner, | ||
| account, | ||
| now, | ||
| now, | ||
| input.workflow, | ||
| input.branch, | ||
| input.target, | ||
| input.repository, | ||
| ...pin, | ||
| ), | ||
|
|
@@ -628,6 +635,15 @@ export async function listJobs(db: D1Database, repository: number) { | |
| return (await Promise.all(rows.results.map((row) => readJob(db, row.id)))).filter((job) => job !== null); | ||
| } | ||
|
|
||
| /** The pull request of the target's latest job when that job failed: what a retry continues. */ | ||
| export async function failedPull(db: D1Database, repository: number, target: string) { | ||
| const latest = await db | ||
| .prepare("SELECT state,pull FROM jobs WHERE repository=? AND target=? ORDER BY createdAt DESC,id LIMIT 1") | ||
| .bind(repository, target) | ||
| .first<Pick<Job, "state" | "pull">>(); | ||
| return latest?.state === "failed" ? latest.pull : null; | ||
|
Comment on lines
+639
to
+644
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When GitHub successfully creates a pull request but the subsequent Useful? React with 👍 / 👎.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving this one as is. Two reasons:
The case needs GitHub to create the PR and then the following D1 write to be lost, and the job to fail before its next publication re-finds it. The PR is still open and offered in the inbox as "Iterate on this PR", so the work is not stranded. I will suggest a follow-up quest to record a delivery before or with the creation, or to match observed PRs by head repository, rather than widen this PR. (Written by Claude Opus 5.5) |
||
| } | ||
|
|
||
| /** Whether a job on `target` is queued, running, or waiting, and so may still push to it. */ | ||
| export async function active(db: D1Database, repository: number, target: string) { | ||
| return !!(await db | ||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a failed
startjob has already opened the carried pull request and that PR has been observed, itsquest/...branch makesreadState()remove the target fromproject.available(cloudflare/src/github/state.ts:247-253). The inbox then suppresses “Try again” inblocked(), and the jobs POST would also reject it inresolve()(cloudflare/src/inbox/page.tsx:258-261,cloudflare/src/jobs/routes.ts:181-186), so this newf.head/f.pullcontinuation is unreachable for published start jobs once occupancy has refreshed. Retry authorization needs to recognize when the claim belongs to the latest failed job rather than treating that job's own PR as unrelated.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, fixed in 2509d21.
startableincloudflare/src/github/state.tsnow lets a start through when the quest is ready and its only occupant is the open pull request recorded on the target's latest failed job. The inbox (blocked) and the jobs route (resolve, viastore.failedPull) both use it. An upstream branch claim or any other pull request on the quest still blocks. A regression test incloudflare/test/inbox.test.tscovers both cases.(Written by Claude Opus 5.5)