@spaceflow/review 0.82.0 → 0.83.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/index.js +22 -8
- package/package.json +1 -1
- package/src/review-issue-filter.spec.ts +52 -0
- package/src/review-source-resolver.ts +22 -4
- package/src/review.service.spec.ts +44 -0
- package/src/review.service.ts +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.82.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.81.0...@spaceflow/review@0.82.0) (2026-04-09)
|
|
4
|
+
|
|
5
|
+
### 代码重构
|
|
6
|
+
|
|
7
|
+
* **review:** 优化 ChangedFileCollection 的防御性编程,确保数据不可变性和类型安全 ([4ce2dc8](https://github.com/Lydanne/spaceflow/commit/4ce2dc82e54df8684832bc210fe03b31a24961ea))
|
|
8
|
+
* **review:** 优化变更文件失效逻辑,在代码已变更时保留已 resolved 问题的状态 ([0fd947b](https://github.com/Lydanne/spaceflow/commit/0fd947b0e774aac52149fadcdbbc70f4091402f2))
|
|
9
|
+
* **review:** 优化统计表格格式,将有效问题细分状态合并为单行,并在修复率和解决率中显示分数详情 ([6b3fdac](https://github.com/Lydanne/spaceflow/commit/6b3fdacdae9d55557ca68b3cb2dd347ca8a0e848))
|
|
10
|
+
* **review:** 在 commits 为空时退化为变更行模式,并调整日志文案统一使用"变更行过滤"术语 ([fca208b](https://github.com/Lydanne/spaceflow/commit/fca208bf87fb80167700b10fecfe2a436b4dedf5))
|
|
11
|
+
* **review:** 将 getFileContents 方法从 ReviewIssueFilter 迁移至 ReviewSourceResolver,并在 resolve 阶段预加载文件内容 ([f861b17](https://github.com/Lydanne/spaceflow/commit/f861b17fb12a788f595229605eee1e5bfe735d27))
|
|
12
|
+
* **review:** 将统计表格中的"修复"术语统一改为"验收",提升状态语义准确性 ([e9782ac](https://github.com/Lydanne/spaceflow/commit/e9782ac89ef6cdc6f60d9683cb3c1cff0078644a))
|
|
13
|
+
* **review:** 提取 buildReviewResult 方法,将 LLM 审查和问题过滤逻辑从 execute 方法中分离 ([f981512](https://github.com/Lydanne/spaceflow/commit/f981512be9c3e8b0659eca201f67d673cd320745))
|
|
14
|
+
* **review:** 提取 ReviewSourceResolver 类,将源数据解析和前置过滤逻辑从 ReviewService 中分离 ([d40f23f](https://github.com/Lydanne/spaceflow/commit/d40f23f9f9c039d07e49f0248c974877c3c3fa68))
|
|
15
|
+
* **review:** 新增 ChangedFileCollection 类,封装变更文件集合并提供常用访问器,统一文件操作接口 ([22020f4](https://github.com/Lydanne/spaceflow/commit/22020f4c1c21ddd3adc422990e9ac3bc846ba593))
|
|
16
|
+
* **review:** 新增 git blame 支持,在分支比较模式下按实际 commit hash 过滤问题,并在 commits 为空时退化为变更行模式 ([ef5ba45](https://github.com/Lydanne/spaceflow/commit/ef5ba45c741ee94aa20ca18adb2836eba6692abe))
|
|
17
|
+
* **review:** 移除行号自动更新机制,改为在验证提示中提供原始代码片段辅助定位,并将去重逻辑从 ReviewService 上移至 ReviewResultModel.nextRound ([174b924](https://github.com/Lydanne/spaceflow/commit/174b924931c0f09e3714462a466f8844097a2af6))
|
|
18
|
+
* **review:** 简化规则过滤逻辑,移除冗余的 applicableSpecs 变量,统一使用 specs 表示已过滤的适用规则 ([571ad26](https://github.com/Lydanne/spaceflow/commit/571ad2656e743a091017384f31533ac67b3499d3))
|
|
19
|
+
|
|
20
|
+
### 文档更新
|
|
21
|
+
|
|
22
|
+
* **review:** 移除 buildLineCommitMap 方法及相关文档和注释 ([92e78d2](https://github.com/Lydanne/spaceflow/commit/92e78d2905f206bbb04e6a4873cd6a25c79b3882))
|
|
23
|
+
|
|
24
|
+
### 测试用例
|
|
25
|
+
|
|
26
|
+
* **review:** 新增 ReviewContextBuilder 和 ReviewIssueFilter 单元测试,覆盖上下文构建、问题过滤和文件内容获取等核心功能 ([432cc60](https://github.com/Lydanne/spaceflow/commit/432cc60c95a44bc6060a09be3a47f2c23aa8cd9d))
|
|
27
|
+
|
|
28
|
+
### 其他修改
|
|
29
|
+
|
|
30
|
+
* **core:** released version 0.31.0 [no ci] ([aed2199](https://github.com/Lydanne/spaceflow/commit/aed2199c5df44a0dca6f2e992c39b040571aaf49))
|
|
31
|
+
* **publish:** released version 0.56.0 [no ci] ([91a3da8](https://github.com/Lydanne/spaceflow/commit/91a3da86f91e1085c1b2d9affd72ace03ebd8e93))
|
|
32
|
+
* **review-summary:** released version 0.50.0 [no ci] ([1e1fc71](https://github.com/Lydanne/spaceflow/commit/1e1fc71842b06732e5132c26ec91e2f4fde32542))
|
|
33
|
+
* **scripts:** released version 0.33.0 [no ci] ([515099f](https://github.com/Lydanne/spaceflow/commit/515099f1dd6eda61cea9494750e5a73db4f6696a))
|
|
34
|
+
* **shell:** released version 0.33.0 [no ci] ([c9f6615](https://github.com/Lydanne/spaceflow/commit/c9f66152b33ab14343c9060b6d8bb30552262a61))
|
|
35
|
+
|
|
3
36
|
## [0.81.0](https://github.com/Lydanne/spaceflow/compare/@spaceflow/review@0.80.0...@spaceflow/review@0.81.0) (2026-04-09)
|
|
4
37
|
|
|
5
38
|
### 新特性
|
package/dist/index.js
CHANGED
|
@@ -5293,7 +5293,7 @@ class ReviewLlmProcessor {
|
|
|
5293
5293
|
({ commits, changedFiles } = await this.applyPreFilters(context, commits, changedFiles, isDirectFileMode));
|
|
5294
5294
|
const headSha = prModel ? await prModel.getHeadSha() : context.headRef || "HEAD";
|
|
5295
5295
|
const collectedFiles = ChangedFileCollection.from(changedFiles);
|
|
5296
|
-
const fileContents = await this.getFileContents(context.owner, context.repo, collectedFiles.toArray(), commits, headSha, context.prNumber, isLocalMode, context.verbose);
|
|
5296
|
+
const fileContents = await this.getFileContents(context.owner, context.repo, collectedFiles.toArray(), commits, headSha, context.prNumber, isLocalMode, context.showAll, context.verbose);
|
|
5297
5297
|
return {
|
|
5298
5298
|
prModel,
|
|
5299
5299
|
commits,
|
|
@@ -5435,18 +5435,20 @@ class ReviewLlmProcessor {
|
|
|
5435
5435
|
* 2. --commits — 仅保留用户指定的 commit 及其涉及的文件
|
|
5436
5436
|
* 3. --includes — glob 模式过滤文件和 commits(支持 status| 前缀语法)
|
|
5437
5437
|
*/ async applyPreFilters(context, commits, rawChangedFiles, isDirectFileMode) {
|
|
5438
|
-
const { owner, repo, prNumber, verbose, includes, files, commits: filterCommits } = context;
|
|
5438
|
+
const { owner, repo, prNumber, verbose, includes, files, commits: filterCommits, showAll } = context;
|
|
5439
5439
|
let changedFiles = ChangedFileCollection.from(rawChangedFiles);
|
|
5440
|
-
// 0. 过滤掉 merge commit
|
|
5441
|
-
{
|
|
5440
|
+
// 0. 过滤掉 merge commit(showAll=false 时启用)
|
|
5441
|
+
if (!showAll) {
|
|
5442
5442
|
const before = commits.length;
|
|
5443
5443
|
commits = commits.filter((c)=>{
|
|
5444
5444
|
const message = c.commit?.message || "";
|
|
5445
|
-
return
|
|
5445
|
+
return !/^merge\b/i.test(message);
|
|
5446
5446
|
});
|
|
5447
5447
|
if (before !== commits.length && shouldLog(verbose, 1)) {
|
|
5448
5448
|
console.log(` 跳过 Merge Commits: ${before} -> ${commits.length} 个`);
|
|
5449
5449
|
}
|
|
5450
|
+
} else if (shouldLog(verbose, 2)) {
|
|
5451
|
+
console.log(` showAll=true,跳过 Merge Commit 过滤`);
|
|
5450
5452
|
}
|
|
5451
5453
|
// 1. 按指定的 files 过滤
|
|
5452
5454
|
if (files && files.length > 0) {
|
|
@@ -5520,9 +5522,11 @@ class ReviewLlmProcessor {
|
|
|
5520
5522
|
/**
|
|
5521
5523
|
* 获取文件内容并构建行号到 commit hash 的映射
|
|
5522
5524
|
* 返回 Map<filename, Array<[commitHash, lineCode]>>
|
|
5523
|
-
*/ async getFileContents(owner, repo, changedFiles, commits, ref, prNumber, isLocalMode, verbose) {
|
|
5525
|
+
*/ async getFileContents(owner, repo, changedFiles, commits, ref, prNumber, isLocalMode, showAll, verbose) {
|
|
5524
5526
|
const contents = new Map();
|
|
5525
5527
|
const latestCommitHash = commits[commits.length - 1]?.sha?.slice(0, 7) || "+local+";
|
|
5528
|
+
const validCommitHashes = new Set(commits.map((c)=>c.sha?.slice(0, 7)).filter(Boolean));
|
|
5529
|
+
const shouldMaskUnknownChangedLines = !showAll && validCommitHashes.size > 0;
|
|
5526
5530
|
if (shouldLog(verbose, 1)) {
|
|
5527
5531
|
console.log(`📊 正在构建行号到变更的映射...`);
|
|
5528
5532
|
}
|
|
@@ -5577,6 +5581,12 @@ class ReviewLlmProcessor {
|
|
|
5577
5581
|
];
|
|
5578
5582
|
}
|
|
5579
5583
|
const hash = blameMap?.get(lineNum) ?? latestCommitHash;
|
|
5584
|
+
if (shouldMaskUnknownChangedLines && !validCommitHashes.has(hash)) {
|
|
5585
|
+
return [
|
|
5586
|
+
"-------",
|
|
5587
|
+
line
|
|
5588
|
+
];
|
|
5589
|
+
}
|
|
5580
5590
|
return [
|
|
5581
5591
|
hash,
|
|
5582
5592
|
line
|
|
@@ -6014,7 +6024,11 @@ class ReviewService {
|
|
|
6014
6024
|
console.log(`📋 找到 ${resultModel.issues.length} 个历史问题`);
|
|
6015
6025
|
}
|
|
6016
6026
|
// 2. 获取 commits 并填充 author 信息
|
|
6017
|
-
const
|
|
6027
|
+
const allCommits = await prModel.getCommits();
|
|
6028
|
+
const commits = context.showAll ? allCommits : allCommits.filter((c)=>!/^merge\b/i.test(c.commit?.message || ""));
|
|
6029
|
+
if (allCommits.length !== commits.length && shouldLog(verbose, 1)) {
|
|
6030
|
+
console.log(` 跳过 Merge Commits: ${allCommits.length} -> ${commits.length} 个`);
|
|
6031
|
+
}
|
|
6018
6032
|
resultModel.issues = await this.contextBuilder.fillIssueAuthors(resultModel.issues, commits, owner, repo, verbose);
|
|
6019
6033
|
// 3. 同步已解决的评论状态
|
|
6020
6034
|
await resultModel.syncResolved();
|
|
@@ -6026,7 +6040,7 @@ class ReviewService {
|
|
|
6026
6040
|
const changedFiles = await prModel.getFiles();
|
|
6027
6041
|
const headSha = await prModel.getHeadSha();
|
|
6028
6042
|
const verifySpecs = await this.issueFilter.loadSpecs(context.specSources, verbose);
|
|
6029
|
-
const verifyFileContents = await this.sourceResolver.getFileContents(owner, repo, changedFiles, commits, headSha, prNumber, false, verbose);
|
|
6043
|
+
const verifyFileContents = await this.sourceResolver.getFileContents(owner, repo, changedFiles, commits, headSha, prNumber, false, context.showAll, verbose);
|
|
6030
6044
|
resultModel.issues = await this.issueFilter.verifyAndUpdateIssues(context, resultModel.issues, commits, {
|
|
6031
6045
|
specs: verifySpecs,
|
|
6032
6046
|
fileContents: verifyFileContents
|
package/package.json
CHANGED
|
@@ -86,6 +86,7 @@ describe("ReviewIssueFilter", () => {
|
|
|
86
86
|
getCommitsBetweenRefs: vi.fn().mockResolvedValue([]),
|
|
87
87
|
getDiffBetweenRefs: vi.fn().mockResolvedValue([]),
|
|
88
88
|
getFileContent: vi.fn().mockResolvedValue(""),
|
|
89
|
+
getFileBlame: vi.fn().mockResolvedValue(new Map()),
|
|
89
90
|
getFilesForCommit: vi.fn().mockResolvedValue([]),
|
|
90
91
|
getWorkingFileContent: vi.fn().mockReturnValue(""),
|
|
91
92
|
getCommitDiff: vi.fn().mockReturnValue([]),
|
|
@@ -264,6 +265,7 @@ describe("ReviewIssueFilter", () => {
|
|
|
264
265
|
"abc",
|
|
265
266
|
1,
|
|
266
267
|
false,
|
|
268
|
+
undefined,
|
|
267
269
|
3,
|
|
268
270
|
);
|
|
269
271
|
expect(result.has("test.ts")).toBe(true);
|
|
@@ -279,6 +281,56 @@ describe("ReviewIssueFilter", () => {
|
|
|
279
281
|
expect(lines![0][0]).toBe("abc1234");
|
|
280
282
|
expect(lines![1][0]).toBe("abc1234");
|
|
281
283
|
});
|
|
284
|
+
|
|
285
|
+
it("should mask merge commit line hash when showAll is false", async () => {
|
|
286
|
+
gitProvider.getFileContent.mockResolvedValue("line1\nnew line");
|
|
287
|
+
mockGitSdkService.getFileBlame.mockResolvedValue(new Map([[2, "merge12"]]));
|
|
288
|
+
const changedFiles = [
|
|
289
|
+
{ filename: "test.ts", status: "modified", patch: "@@ -1,1 +1,2 @@\n line1\n+new line" },
|
|
290
|
+
];
|
|
291
|
+
const commits = [{ sha: "abc1234567890", commit: { message: "feat: add line" } }];
|
|
292
|
+
|
|
293
|
+
const result = await resolver.getFileContents(
|
|
294
|
+
"o",
|
|
295
|
+
"r",
|
|
296
|
+
changedFiles,
|
|
297
|
+
commits,
|
|
298
|
+
"abc",
|
|
299
|
+
1,
|
|
300
|
+
false,
|
|
301
|
+
false,
|
|
302
|
+
undefined,
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
const lines = result.get("test.ts");
|
|
306
|
+
expect(lines).toBeDefined();
|
|
307
|
+
expect(lines![1][0]).toBe("-------");
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
it("should keep merge commit line hash when showAll is true", async () => {
|
|
311
|
+
gitProvider.getFileContent.mockResolvedValue("line1\nnew line");
|
|
312
|
+
mockGitSdkService.getFileBlame.mockResolvedValue(new Map([[2, "merge12"]]));
|
|
313
|
+
const changedFiles = [
|
|
314
|
+
{ filename: "test.ts", status: "modified", patch: "@@ -1,1 +1,2 @@\n line1\n+new line" },
|
|
315
|
+
];
|
|
316
|
+
const commits = [{ sha: "abc1234567890", commit: { message: "feat: add line" } }];
|
|
317
|
+
|
|
318
|
+
const result = await resolver.getFileContents(
|
|
319
|
+
"o",
|
|
320
|
+
"r",
|
|
321
|
+
changedFiles,
|
|
322
|
+
commits,
|
|
323
|
+
"abc",
|
|
324
|
+
1,
|
|
325
|
+
false,
|
|
326
|
+
true,
|
|
327
|
+
undefined,
|
|
328
|
+
);
|
|
329
|
+
|
|
330
|
+
const lines = result.get("test.ts");
|
|
331
|
+
expect(lines).toBeDefined();
|
|
332
|
+
expect(lines![1][0]).toBe("merge12");
|
|
333
|
+
});
|
|
282
334
|
});
|
|
283
335
|
|
|
284
336
|
describe("getChangedFilesBetweenRefs", () => {
|
|
@@ -150,6 +150,7 @@ export class ReviewSourceResolver {
|
|
|
150
150
|
headSha,
|
|
151
151
|
context.prNumber,
|
|
152
152
|
isLocalMode,
|
|
153
|
+
context.showAll,
|
|
153
154
|
context.verbose,
|
|
154
155
|
);
|
|
155
156
|
return {
|
|
@@ -313,19 +314,30 @@ export class ReviewSourceResolver {
|
|
|
313
314
|
rawChangedFiles: ChangedFile[],
|
|
314
315
|
isDirectFileMode: boolean,
|
|
315
316
|
): Promise<CommitsAndFiles> {
|
|
316
|
-
const {
|
|
317
|
+
const {
|
|
318
|
+
owner,
|
|
319
|
+
repo,
|
|
320
|
+
prNumber,
|
|
321
|
+
verbose,
|
|
322
|
+
includes,
|
|
323
|
+
files,
|
|
324
|
+
commits: filterCommits,
|
|
325
|
+
showAll,
|
|
326
|
+
} = context;
|
|
317
327
|
let changedFiles = ChangedFileCollection.from(rawChangedFiles);
|
|
318
328
|
|
|
319
|
-
// 0. 过滤掉 merge commit
|
|
320
|
-
{
|
|
329
|
+
// 0. 过滤掉 merge commit(showAll=false 时启用)
|
|
330
|
+
if (!showAll) {
|
|
321
331
|
const before = commits.length;
|
|
322
332
|
commits = commits.filter((c) => {
|
|
323
333
|
const message = c.commit?.message || "";
|
|
324
|
-
return
|
|
334
|
+
return !/^merge\b/i.test(message);
|
|
325
335
|
});
|
|
326
336
|
if (before !== commits.length && shouldLog(verbose, 1)) {
|
|
327
337
|
console.log(` 跳过 Merge Commits: ${before} -> ${commits.length} 个`);
|
|
328
338
|
}
|
|
339
|
+
} else if (shouldLog(verbose, 2)) {
|
|
340
|
+
console.log(` showAll=true,跳过 Merge Commit 过滤`);
|
|
329
341
|
}
|
|
330
342
|
|
|
331
343
|
// 1. 按指定的 files 过滤
|
|
@@ -426,10 +438,13 @@ export class ReviewSourceResolver {
|
|
|
426
438
|
ref: string,
|
|
427
439
|
prNumber?: number,
|
|
428
440
|
isLocalMode?: boolean,
|
|
441
|
+
showAll?: boolean,
|
|
429
442
|
verbose?: VerboseLevel,
|
|
430
443
|
): Promise<FileContentsMap> {
|
|
431
444
|
const contents: FileContentsMap = new Map();
|
|
432
445
|
const latestCommitHash = commits[commits.length - 1]?.sha?.slice(0, 7) || "+local+";
|
|
446
|
+
const validCommitHashes = new Set(commits.map((c) => c.sha?.slice(0, 7)).filter(Boolean));
|
|
447
|
+
const shouldMaskUnknownChangedLines = !showAll && validCommitHashes.size > 0;
|
|
433
448
|
|
|
434
449
|
if (shouldLog(verbose, 1)) {
|
|
435
450
|
console.log(`📊 正在构建行号到变更的映射...`);
|
|
@@ -503,6 +518,9 @@ export class ReviewSourceResolver {
|
|
|
503
518
|
return ["-------", line];
|
|
504
519
|
}
|
|
505
520
|
const hash = blameMap?.get(lineNum) ?? latestCommitHash;
|
|
521
|
+
if (shouldMaskUnknownChangedLines && !validCommitHashes.has(hash)) {
|
|
522
|
+
return ["-------", line];
|
|
523
|
+
}
|
|
506
524
|
return [hash, line];
|
|
507
525
|
});
|
|
508
526
|
contents.set(file.filename, contentLines);
|
|
@@ -650,6 +650,50 @@ describe("ReviewService", () => {
|
|
|
650
650
|
expect(result.issues).toHaveLength(1);
|
|
651
651
|
expect(result.stats).toBeDefined();
|
|
652
652
|
});
|
|
653
|
+
|
|
654
|
+
it("should filter merge commits before getFileContents when verifyFixes enabled", async () => {
|
|
655
|
+
const existingResult = { issues: [{ file: "a.ts", line: "1", ruleId: "R1" }], summary: [] };
|
|
656
|
+
service._reviewReportService.formatStatsTerminal = vi.fn().mockReturnValue("stats") as any;
|
|
657
|
+
gitProvider.listPullReviews.mockResolvedValue([] as any);
|
|
658
|
+
gitProvider.listPullReviewComments.mockResolvedValue([] as any);
|
|
659
|
+
gitProvider.getPullRequest.mockResolvedValue({ head: { sha: "head1234" } } as any);
|
|
660
|
+
gitProvider.getPullRequestFiles.mockResolvedValue([
|
|
661
|
+
{ filename: "a.ts", status: "modified" },
|
|
662
|
+
] as any);
|
|
663
|
+
gitProvider.getPullRequestCommits.mockResolvedValue([
|
|
664
|
+
{ sha: "merge1111", commit: { message: "Merge branch 'main' into feature" } },
|
|
665
|
+
{ sha: "feat22222", commit: { message: "feat: add logic" } },
|
|
666
|
+
] as any);
|
|
667
|
+
|
|
668
|
+
vi.spyOn(ReviewResultModel, "loadFromPr").mockResolvedValue(
|
|
669
|
+
ReviewResultModel.create(
|
|
670
|
+
new PullRequestModel(gitProvider as any, "o", "r", 1),
|
|
671
|
+
existingResult as any,
|
|
672
|
+
service._resultModelDeps,
|
|
673
|
+
),
|
|
674
|
+
);
|
|
675
|
+
const getFileContentsSpy = vi
|
|
676
|
+
.spyOn(service._sourceResolver, "getFileContents")
|
|
677
|
+
.mockResolvedValue(new Map() as any);
|
|
678
|
+
|
|
679
|
+
const context = {
|
|
680
|
+
owner: "o",
|
|
681
|
+
repo: "r",
|
|
682
|
+
prNumber: 1,
|
|
683
|
+
ci: false,
|
|
684
|
+
dryRun: false,
|
|
685
|
+
verifyFixes: true,
|
|
686
|
+
specSources: ["/spec/dir"],
|
|
687
|
+
showAll: false,
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
await service.executeCollectOnly(context);
|
|
691
|
+
|
|
692
|
+
expect(getFileContentsSpy).toHaveBeenCalled();
|
|
693
|
+
const passedCommits = getFileContentsSpy.mock.calls[0][3] as any[];
|
|
694
|
+
expect(passedCommits).toHaveLength(1);
|
|
695
|
+
expect(passedCommits[0].sha).toBe("feat22222");
|
|
696
|
+
});
|
|
653
697
|
});
|
|
654
698
|
|
|
655
699
|
describe("ReviewService.execute - flush mode", () => {
|
package/src/review.service.ts
CHANGED
|
@@ -496,7 +496,13 @@ export class ReviewService {
|
|
|
496
496
|
}
|
|
497
497
|
|
|
498
498
|
// 2. 获取 commits 并填充 author 信息
|
|
499
|
-
const
|
|
499
|
+
const allCommits = await prModel.getCommits();
|
|
500
|
+
const commits = context.showAll
|
|
501
|
+
? allCommits
|
|
502
|
+
: allCommits.filter((c) => !/^merge\b/i.test(c.commit?.message || ""));
|
|
503
|
+
if (allCommits.length !== commits.length && shouldLog(verbose, 1)) {
|
|
504
|
+
console.log(` 跳过 Merge Commits: ${allCommits.length} -> ${commits.length} 个`);
|
|
505
|
+
}
|
|
500
506
|
resultModel.issues = await this.contextBuilder.fillIssueAuthors(
|
|
501
507
|
resultModel.issues,
|
|
502
508
|
commits,
|
|
@@ -525,6 +531,7 @@ export class ReviewService {
|
|
|
525
531
|
headSha,
|
|
526
532
|
prNumber,
|
|
527
533
|
false,
|
|
534
|
+
context.showAll,
|
|
528
535
|
verbose,
|
|
529
536
|
);
|
|
530
537
|
resultModel.issues = await this.issueFilter.verifyAndUpdateIssues(
|