按 writing-alembic-migrations 的规矩判断:迁移的前任必须已在发布分支上, 且发布分支上该前任不能已有别的后继;根迁移接不上已有链、删迁移会断链也不可摘。 列表里带迁移的提交打「迁移」角标,不可摘的高亮警告色、禁用勾选并写明原因; 确认接口再校验一遍,绕过前端也摘不进去。 Claude-Session: https://claude.ai/code/session_01QWxLb6X8Vd2G5vHnp6R7qm
53 lines
1.6 KiB
TypeScript
53 lines
1.6 KiB
TypeScript
import type { ReleaseCommit, ReleaseCommitGroup } from './messages'
|
|
|
|
/** 能勾选的提交:带不兼容迁移的不算 */
|
|
export function pickableShas(commits: ReleaseCommit[]): string[] {
|
|
return commits.filter(c => !c.migration?.blocked).map(c => c.sha)
|
|
}
|
|
|
|
export function uniqueAuthors(groups: ReleaseCommitGroup[]): string[] {
|
|
const out: string[] = []
|
|
for (const g of groups) {
|
|
for (const a of g.authors) {
|
|
if (!out.includes(a))
|
|
out.push(a)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
export function filterCherryPickGroups(
|
|
groups: ReleaseCommitGroup[],
|
|
query: string,
|
|
authors: ReadonlySet<string>,
|
|
): ReleaseCommitGroup[] {
|
|
const q = query.trim().toLowerCase()
|
|
const out: ReleaseCommitGroup[] = []
|
|
for (const g of groups) {
|
|
const commits = g.commits.filter(c => authors.has(c.author))
|
|
if (commits.length === 0)
|
|
continue
|
|
if (!q) {
|
|
out.push({ ...g, authors: uniqueAuthors([{ ...g, commits }]), commits })
|
|
continue
|
|
}
|
|
const head = `#${g.pr ?? ''} ${g.title} ${g.authors.join(' ')}`.toLowerCase()
|
|
if (head.includes(q)) {
|
|
out.push({ ...g, authors: uniqueAuthors([{ ...g, commits }]), commits })
|
|
continue
|
|
}
|
|
const hit = commits.filter(c =>
|
|
`${c.subject} ${c.author} ${c.sha} ${c.date}`.toLowerCase().includes(q),
|
|
)
|
|
if (hit.length > 0)
|
|
out.push({ ...g, authors: uniqueAuthors([{ ...g, commits: hit }]), commits: hit })
|
|
}
|
|
return out
|
|
}
|
|
|
|
export function groupContainingSha(groups: ReleaseCommitGroup[], sha: string | undefined): ReleaseCommitGroup | undefined {
|
|
if (!sha)
|
|
return undefined
|
|
return groups.find(g => g.commits.some(c => c.sha === sha))
|
|
}
|