PBI-8 (vervolg): Sprint-aware branch + SPRINT-mode draft-PR
T-22 — sprint-aware branch-resolutie (resolveBranchForJob):
- SPRINT-mode → feat/sprint-<sprint_run_id-suffix> (één branch voor hele run)
- STORY-mode → feat/story-<story_id-suffix> (één per story)
- Legacy (zonder sprint_run_id): bestaand gedrag
Sibling-detection herbruikt branch wanneer een eerdere job in dezelfde
scope al de branch heeft.
T-24 — SPRINT-mode draft-PR + ready-bij-DONE:
- createPullRequest accepteert nu draft + enableAutoMerge flags
- Nieuwe markPullRequestReady-helper voor draft → ready transitie
- maybeCreateAutoPr in SPRINT-mode: opent één draft-PR per SprintRun met
sprint_goal als titel; geen auto-merge; sibling-tasks hergebruiken de
PR
- update-job-status detecteert sprint-DONE via PropagationResult en zet
de draft-PR via markPullRequestReady ready-for-review (mens reviewt en
mergt zelf)
T-23 — STORY-mode dekking: bestaande createPullRequest + auto-merge gedrag
ongewijzigd. Tests uitgebreid met sprint-aware mocks; 6 nieuwe
branch-resolution tests + 2 sprint-mode auto-pr tests + 4 markPullRequest
Ready/draft-PR tests.
Tests: 195/195 groen (180 → 195; 15 nieuwe scenario's voor sprint-aware
branch + SPRINT-mode draft-PR + markPullRequestReady).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b135e12dd
commit
454d96ee04
7 changed files with 359 additions and 24 deletions
|
|
@ -12,7 +12,7 @@ vi.mock('node:util', () => ({
|
|||
),
|
||||
}))
|
||||
|
||||
import { createPullRequest } from '../../src/git/pr.js'
|
||||
import { createPullRequest, markPullRequestReady } from '../../src/git/pr.js'
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
|
|
@ -66,4 +66,80 @@ describe('createPullRequest', () => {
|
|||
|
||||
expect(result).toMatchObject({ error: expect.stringContaining('gh pr create failed') })
|
||||
})
|
||||
|
||||
it('passes --draft when draft=true en slaat auto-merge over', async () => {
|
||||
const calls: string[][] = []
|
||||
mockExecFile.mockImplementation(
|
||||
(
|
||||
_cmd: string,
|
||||
args: string[],
|
||||
_opts: unknown,
|
||||
cb: (err: null, res: { stdout: string; stderr: string }) => void,
|
||||
) => {
|
||||
calls.push(args)
|
||||
cb(null, {
|
||||
stdout: 'Creating draft pull request...\nhttps://github.com/org/repo/pull/100\n',
|
||||
stderr: '',
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
const result = await createPullRequest({
|
||||
worktreePath: '/wt/sprint-1',
|
||||
branchName: 'feat/sprint-12345678',
|
||||
title: 'Sprint: Cascade-flow live',
|
||||
body: 'Sprint draft',
|
||||
draft: true,
|
||||
enableAutoMerge: false,
|
||||
})
|
||||
|
||||
expect(result).toEqual({ url: 'https://github.com/org/repo/pull/100' })
|
||||
expect(calls.some((a) => a.includes('--draft'))).toBe(true)
|
||||
// gh pr merge --auto mag NIET gestart zijn voor draft + auto-merge=false
|
||||
expect(calls.some((a) => a[0] === 'pr' && a[1] === 'merge')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('markPullRequestReady', () => {
|
||||
it('roept gh pr ready aan met de PR-URL', async () => {
|
||||
const calls: string[][] = []
|
||||
mockExecFile.mockImplementation(
|
||||
(
|
||||
_cmd: string,
|
||||
args: string[],
|
||||
_opts: unknown,
|
||||
cb: (err: null, res: { stdout: string; stderr: string }) => void,
|
||||
) => {
|
||||
calls.push(args)
|
||||
cb(null, { stdout: '', stderr: '' })
|
||||
},
|
||||
)
|
||||
|
||||
const result = await markPullRequestReady({ prUrl: 'https://github.com/org/repo/pull/100' })
|
||||
|
||||
expect(result).toEqual({ ok: true })
|
||||
expect(calls[0]).toEqual(['pr', 'ready', 'https://github.com/org/repo/pull/100'])
|
||||
})
|
||||
|
||||
it('behandelt "already ready" als success', async () => {
|
||||
mockExecFile.mockImplementation(
|
||||
(_cmd: string, _args: string[], _opts: unknown, cb: (err: Error) => void) =>
|
||||
cb(Object.assign(new Error(''), { stderr: 'Pull request is not in draft state' })),
|
||||
)
|
||||
|
||||
const result = await markPullRequestReady({ prUrl: 'https://github.com/org/repo/pull/100' })
|
||||
|
||||
expect(result).toEqual({ ok: true })
|
||||
})
|
||||
|
||||
it('retourneert error op onverwachte gh-fout', async () => {
|
||||
mockExecFile.mockImplementation(
|
||||
(_cmd: string, _args: string[], _opts: unknown, cb: (err: Error) => void) =>
|
||||
cb(new Error('rate limit exceeded')),
|
||||
)
|
||||
|
||||
const result = await markPullRequestReady({ prUrl: 'https://github.com/org/repo/pull/100' })
|
||||
|
||||
expect(result).toMatchObject({ error: expect.stringContaining('gh pr ready failed') })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue