🐛 fix(vscode): 摘修复按 Gitea PR 提交列表分组
This commit is contained in:
1 parent
c0f8da5514
commit
4d3b2a0d67
6 files changed
+193
-34
No files matched your search
@@ -362,6 +362,67 @@ export async function getPullRequest(opts: {
|
||||
}
|
||||
}
|
||||
|
||||
export async function listClosedPullsPage(opts: {
|
||||
host: string
|
||||
token: string
|
||||
owner: string
|
||||
repo: string
|
||||
page: number
|
||||
}): Promise<Array<{ number: number, title: string, merged: boolean, mergeCommitSha: string | null }>> {
|
||||
const url = new URL(`${baseUrl(opts.host)}/repos/${opts.owner}/${opts.repo}/pulls`)
|
||||
url.searchParams.set('state', 'closed')
|
||||
url.searchParams.set('sort', 'recentupdate')
|
||||
url.searchParams.set('limit', String(PAGE_SIZE))
|
||||
url.searchParams.set('page', String(opts.page))
|
||||
const res = await fetch(url.toString(), { headers: authHeaders(opts.token) })
|
||||
await ensureOk(res)
|
||||
const batch = await res.json() as Array<{
|
||||
number?: unknown
|
||||
title?: unknown
|
||||
merged?: unknown
|
||||
merge_commit_sha?: unknown
|
||||
}>
|
||||
if (!Array.isArray(batch))
|
||||
return []
|
||||
return batch.map(p => ({
|
||||
number: typeof p.number === 'number' ? p.number : Number(p.number),
|
||||
title: typeof p.title === 'string' ? p.title : '',
|
||||
merged: p.merged === true,
|
||||
mergeCommitSha: typeof p.merge_commit_sha === 'string' && p.merge_commit_sha.length > 0
|
||||
? p.merge_commit_sha
|
||||
: null,
|
||||
}))
|
||||
}
|
||||
|
||||
export async function listPullRequestCommitShas(opts: {
|
||||
host: string
|
||||
token: string
|
||||
owner: string
|
||||
repo: string
|
||||
index: number
|
||||
}): Promise<string[]> {
|
||||
const out: string[] = []
|
||||
let page = 1
|
||||
while (true) {
|
||||
const url = new URL(`${baseUrl(opts.host)}/repos/${opts.owner}/${opts.repo}/pulls/${opts.index}/commits`)
|
||||
url.searchParams.set('limit', String(PAGE_SIZE))
|
||||
url.searchParams.set('page', String(page))
|
||||
const res = await fetch(url.toString(), { headers: authHeaders(opts.token) })
|
||||
await ensureOk(res)
|
||||
const batch = await res.json() as Array<{ sha?: unknown }>
|
||||
if (!Array.isArray(batch) || batch.length === 0)
|
||||
break
|
||||
for (const c of batch) {
|
||||
if (typeof c.sha === 'string' && c.sha.length > 0)
|
||||
out.push(c.sha)
|
||||
}
|
||||
if (batch.length < PAGE_SIZE)
|
||||
break
|
||||
page += 1
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export async function getIssue(opts: {
|
||||
host: string
|
||||
token: string
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { indexCommitsByPull } from './commitPulls'
|
||||
|
||||
describe('indexCommitsByPull', () => {
|
||||
it('用已合并 PR 的提交列表把 sha 对上 PR,不看 commit message', async () => {
|
||||
const map = await indexCommitsByPull(
|
||||
['3e519ea', '5572c4f', 'orphan'],
|
||||
async (page) => {
|
||||
if (page !== 1)
|
||||
return []
|
||||
return [
|
||||
{ number: 260, title: '连续包月会员订阅体系', merged: true, mergeCommitSha: 'merge260' },
|
||||
{ number: 99, title: '还没合', merged: false, mergeCommitSha: null },
|
||||
]
|
||||
},
|
||||
async (index) => {
|
||||
if (index === 260)
|
||||
return ['3e519ea', '5572c4f', 'other']
|
||||
throw new Error(`should not fetch commits for PR ${index}`)
|
||||
},
|
||||
)
|
||||
expect(map.get('3e519ea')).toEqual({ number: 260, title: '连续包月会员订阅体系' })
|
||||
expect(map.get('5572c4f')).toEqual({ number: 260, title: '连续包月会员订阅体系' })
|
||||
expect(map.has('orphan')).toBe(false)
|
||||
})
|
||||
|
||||
it('squash 合入时用 mergeCommitSha 对上', async () => {
|
||||
const map = await indexCommitsByPull(
|
||||
['squashsha'],
|
||||
async () => [{ number: 8, title: 'squash pr', merged: true, mergeCommitSha: 'squashsha' }],
|
||||
async () => ['original-on-branch'],
|
||||
)
|
||||
expect(map.get('squashsha')).toEqual({ number: 8, title: 'squash pr' })
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,57 @@
|
||||
export interface PullRef {
|
||||
number: number
|
||||
title: string
|
||||
merged: boolean
|
||||
mergeCommitSha: string | null
|
||||
}
|
||||
|
||||
export type ListPullsPage = (page: number) => Promise<PullRef[]>
|
||||
export type ListPullCommits = (index: number) => Promise<string[]>
|
||||
|
||||
/**
|
||||
* 把未发布提交的 sha 对上已合并 PR。
|
||||
* 只认 Gitea 的 PR 提交列表 / squash 的 mergeCommitSha,不扫 commit message。
|
||||
*/
|
||||
export async function indexCommitsByPull(
|
||||
shas: readonly string[],
|
||||
listPulls: ListPullsPage,
|
||||
listCommits: ListPullCommits,
|
||||
): Promise<Map<string, { number: number, title: string }>> {
|
||||
const needed = new Set(shas)
|
||||
const out = new Map<string, { number: number, title: string }>()
|
||||
if (needed.size === 0)
|
||||
return out
|
||||
|
||||
for (let page = 1; page <= 20; page++) {
|
||||
const batch = await listPulls(page)
|
||||
if (batch.length === 0)
|
||||
break
|
||||
for (const pr of batch) {
|
||||
if (!pr.merged)
|
||||
continue
|
||||
const ref = { number: pr.number, title: pr.title }
|
||||
if (pr.mergeCommitSha && needed.has(pr.mergeCommitSha))
|
||||
out.set(pr.mergeCommitSha, ref)
|
||||
const commits = await listCommits(pr.number)
|
||||
for (const sha of commits) {
|
||||
if (needed.has(sha))
|
||||
out.set(sha, ref)
|
||||
}
|
||||
if (out.size === needed.size)
|
||||
return out
|
||||
}
|
||||
if (batch.length < 50)
|
||||
break
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export function attachPulls<T extends { sha: string }>(
|
||||
commits: T[],
|
||||
index: Map<string, { number: number, title: string }>,
|
||||
): Array<T & { pr?: number, prTitle?: string }> {
|
||||
return commits.map((c) => {
|
||||
const hit = index.get(c.sha)
|
||||
return hit ? { ...c, pr: hit.number, prTitle: hit.title } : c
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user