gitlab-auto-reviewers 2.0.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/LICENSE +21 -0
- package/README.md +1878 -0
- package/dist/api/gitlab-api.d.ts +136 -0
- package/dist/api/gitlab-api.d.ts.map +1 -0
- package/dist/api/gitlab-api.js +334 -0
- package/dist/api/gitlab-api.js.map +1 -0
- package/dist/bin/cli.d.ts +10 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +186 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/bin/deprecated-mcp.d.ts +12 -0
- package/dist/bin/deprecated-mcp.d.ts.map +1 -0
- package/dist/bin/deprecated-mcp.js +73 -0
- package/dist/bin/deprecated-mcp.js.map +1 -0
- package/dist/bin/index.d.ts +18 -0
- package/dist/bin/index.d.ts.map +1 -0
- package/dist/bin/index.js +78 -0
- package/dist/bin/index.js.map +1 -0
- package/dist/bin/mcp.d.ts +11 -0
- package/dist/bin/mcp.d.ts.map +1 -0
- package/dist/bin/mcp.js +43 -0
- package/dist/bin/mcp.js.map +1 -0
- package/dist/cache/cache.service.d.ts +113 -0
- package/dist/cache/cache.service.d.ts.map +1 -0
- package/dist/cache/cache.service.js +213 -0
- package/dist/cache/cache.service.js.map +1 -0
- package/dist/cli/commands.d.ts +40 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +142 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/output.d.ts +24 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +143 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/config/config.service.d.ts +89 -0
- package/dist/config/config.service.d.ts.map +1 -0
- package/dist/config/config.service.js +169 -0
- package/dist/config/config.service.js.map +1 -0
- package/dist/datasources/git-data-source.interface.d.ts +140 -0
- package/dist/datasources/git-data-source.interface.d.ts.map +1 -0
- package/dist/datasources/git-data-source.interface.js +2 -0
- package/dist/datasources/git-data-source.interface.js.map +1 -0
- package/dist/datasources/gitlab-api-data-source.d.ts +127 -0
- package/dist/datasources/gitlab-api-data-source.d.ts.map +1 -0
- package/dist/datasources/gitlab-api-data-source.js +248 -0
- package/dist/datasources/gitlab-api-data-source.js.map +1 -0
- package/dist/datasources/local-git-data-source.d.ts +124 -0
- package/dist/datasources/local-git-data-source.d.ts.map +1 -0
- package/dist/datasources/local-git-data-source.js +580 -0
- package/dist/datasources/local-git-data-source.js.map +1 -0
- package/dist/errors/error-handler.d.ts +113 -0
- package/dist/errors/error-handler.d.ts.map +1 -0
- package/dist/errors/error-handler.js +230 -0
- package/dist/errors/error-handler.js.map +1 -0
- package/dist/index.d.ts +139 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +139 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/example.d.ts +15 -0
- package/dist/logging/example.d.ts.map +1 -0
- package/dist/logging/example.js +79 -0
- package/dist/logging/example.js.map +1 -0
- package/dist/logging/index.d.ts +7 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +7 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.service.d.ts +98 -0
- package/dist/logging/logger.service.d.ts.map +1 -0
- package/dist/logging/logger.service.js +160 -0
- package/dist/logging/logger.service.js.map +1 -0
- package/dist/mcp/server.d.ts +67 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +213 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +22 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +176 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/services/blacklist.service.d.ts +32 -0
- package/dist/services/blacklist.service.d.ts.map +1 -0
- package/dist/services/blacklist.service.js +59 -0
- package/dist/services/blacklist.service.js.map +1 -0
- package/dist/services/codeowners.service.d.ts +45 -0
- package/dist/services/codeowners.service.d.ts.map +1 -0
- package/dist/services/codeowners.service.js +200 -0
- package/dist/services/codeowners.service.js.map +1 -0
- package/dist/services/comment-builder.service.d.ts +48 -0
- package/dist/services/comment-builder.service.d.ts.map +1 -0
- package/dist/services/comment-builder.service.js +61 -0
- package/dist/services/comment-builder.service.js.map +1 -0
- package/dist/services/contributors.service.d.ts +52 -0
- package/dist/services/contributors.service.d.ts.map +1 -0
- package/dist/services/contributors.service.js +144 -0
- package/dist/services/contributors.service.js.map +1 -0
- package/dist/services/reviewer-service.d.ts +125 -0
- package/dist/services/reviewer-service.d.ts.map +1 -0
- package/dist/services/reviewer-service.js +554 -0
- package/dist/services/reviewer-service.js.map +1 -0
- package/dist/services/team-members.service.d.ts +29 -0
- package/dist/services/team-members.service.d.ts.map +1 -0
- package/dist/services/team-members.service.js +45 -0
- package/dist/services/team-members.service.js.map +1 -0
- package/dist/services/whitelist.service.d.ts +31 -0
- package/dist/services/whitelist.service.d.ts.map +1 -0
- package/dist/services/whitelist.service.js +51 -0
- package/dist/services/whitelist.service.js.map +1 -0
- package/dist/tools.d.ts +22 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +176 -0
- package/dist/tools.js.map +1 -0
- package/dist/types/index.d.ts +502 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +91 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types.d.ts +219 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service for building formatted reviewer assignment comments for GitLab merge requests.
|
|
3
|
+
*
|
|
4
|
+
* Generates markdown-formatted comments that include reviewer suggestions with
|
|
5
|
+
* file links, load balancing information, and GitLab quick actions for assigning reviewers.
|
|
6
|
+
*/
|
|
7
|
+
export class CommentBuilderService {
|
|
8
|
+
gitlabUrl;
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new CommentBuilderService instance.
|
|
11
|
+
*
|
|
12
|
+
* @param gitlabUrl - The base URL of the GitLab instance (e.g., 'https://gitlab.com')
|
|
13
|
+
*/
|
|
14
|
+
constructor(gitlabUrl) {
|
|
15
|
+
this.gitlabUrl = gitlabUrl;
|
|
16
|
+
}
|
|
17
|
+
buildReviewerAssignmentComment({ projectId, base, contributors, teamMembers, codeOwners, }) {
|
|
18
|
+
const sections = [
|
|
19
|
+
...contributors
|
|
20
|
+
.filter(({ username }) => username)
|
|
21
|
+
.map(({ username, changes }) => `Hi @${username},\n\nAs a previous contributor, could you review the following files since your last change.\n${changes
|
|
22
|
+
.map(({ path, fragments }) => `- [ ] ${path}#${fragments
|
|
23
|
+
?.map((fragment) => `[${fragment}](${this.gitlabUrl}/${projectId}/-/blame/${base}/${path}#${fragment})`)
|
|
24
|
+
.join(", ") || ""}`)
|
|
25
|
+
.join("\n")}\n\n/assign_reviewer @${username}\n\n`),
|
|
26
|
+
...teamMembers.map(({ team, members, loadBalanced, memberScores }) => {
|
|
27
|
+
const membersWithScores = loadBalanced && memberScores
|
|
28
|
+
? memberScores
|
|
29
|
+
.map((m) => {
|
|
30
|
+
const score = Math.round(m.ratio);
|
|
31
|
+
const suffix = m.fte === 1 ? "" : `(${m.score}:${m.fte})`;
|
|
32
|
+
return `@${m.username}<sup>${score}${suffix}</sup>`;
|
|
33
|
+
})
|
|
34
|
+
.join(", ")
|
|
35
|
+
: members.map((member) => `@${member}`).join(", ");
|
|
36
|
+
const assignedMember = loadBalanced && memberScores
|
|
37
|
+
? memberScores[0].username
|
|
38
|
+
: members[0];
|
|
39
|
+
return `Hi ${membersWithScores},\n\nAs a member of ~"Team::${team}", could you review and approve?\n\n/assign_reviewer @${assignedMember}\n\n`;
|
|
40
|
+
}),
|
|
41
|
+
...codeOwners
|
|
42
|
+
.filter(({ owners }) => owners && owners.length > 0)
|
|
43
|
+
.map(({ sectionName, files, owners, loadBalanced, allOwners, ownerScores, }) => {
|
|
44
|
+
const allOwnersWithScores = loadBalanced && ownerScores && allOwners
|
|
45
|
+
? ownerScores
|
|
46
|
+
.map((o) => {
|
|
47
|
+
const score = Math.round(o.ratio);
|
|
48
|
+
const suffix = o.fte === 1 ? "" : `(${o.assignedMRs}:${o.fte})`;
|
|
49
|
+
return `@${o.username}<sup>${score}${suffix}</sup>`;
|
|
50
|
+
})
|
|
51
|
+
.join(", ")
|
|
52
|
+
: (allOwners || owners)
|
|
53
|
+
.map((owner) => `@${owner}`)
|
|
54
|
+
.join(", ");
|
|
55
|
+
return `Hi ${allOwnersWithScores},\n\n${sectionName === "Global" ? "As code owner(s)" : `As [${sectionName}] code owner(s)`}, please review and approve. The following file(s) may require more of your attention.\n${files.map((file) => `- [ ] [${file}](${this.gitlabUrl}/${projectId}/-/blame/${base}/${file})`).join("\n")}\n\n/assign_reviewer ${owners.map((owner) => `@${owner}`).join(", ")}\n\n`;
|
|
56
|
+
}),
|
|
57
|
+
];
|
|
58
|
+
return sections.join("---\n");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=comment-builder.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-builder.service.js","sourceRoot":"","sources":["../../src/services/comment-builder.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { GitDataSource } from "../datasources/git-data-source.interface.js";
|
|
2
|
+
import { Contributor } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Represents a change to a specific file by a contributor.
|
|
5
|
+
*
|
|
6
|
+
* @property path - The file path that was modified
|
|
7
|
+
* @property fragments - Array of line ranges (e.g., 'L10-L20') that were changed
|
|
8
|
+
*/
|
|
9
|
+
export interface ContributorChange {
|
|
10
|
+
path: string;
|
|
11
|
+
fragments: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Extends Contributor with information about their specific changes in a merge request.
|
|
15
|
+
*
|
|
16
|
+
* @property changes - Array of file changes made by this contributor
|
|
17
|
+
*/
|
|
18
|
+
export interface ContributorWithChanges extends Contributor {
|
|
19
|
+
changes: ContributorChange[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Service for analyzing merge request contributors based on git blame data.
|
|
23
|
+
*
|
|
24
|
+
* Identifies previous contributors to modified code by analyzing git blame
|
|
25
|
+
* information and matching it against a whitelist of known contributors.
|
|
26
|
+
* Provides detailed information about which lines each contributor previously authored.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ContributorsService {
|
|
29
|
+
private dataSource;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new ContributorsService instance.
|
|
32
|
+
*
|
|
33
|
+
* @param dataSource - The data source for accessing GitLab and git data
|
|
34
|
+
*/
|
|
35
|
+
constructor(dataSource: GitDataSource);
|
|
36
|
+
/**
|
|
37
|
+
* Analyzes merge request diffs to identify previous contributors to modified code.
|
|
38
|
+
*
|
|
39
|
+
* Uses git blame to determine who previously authored the lines being removed
|
|
40
|
+
* in the merge request, then matches those authors against the whitelist.
|
|
41
|
+
* Returns contributors with detailed information about which files and line
|
|
42
|
+
* ranges they previously modified.
|
|
43
|
+
*
|
|
44
|
+
* @param project - The GitLab project identifier (ID or path)
|
|
45
|
+
* @param mr - The merge request IID
|
|
46
|
+
* @param base - The base commit SHA to blame against
|
|
47
|
+
* @param whitelist - Array of known contributors to match against
|
|
48
|
+
* @returns Array of contributors with their specific changes in this MR
|
|
49
|
+
*/
|
|
50
|
+
getContributors(project: string, mr: number, base: string, whitelist: Contributor[]): Promise<ContributorWithChanges[]>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=contributors.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contributors.service.d.ts","sourceRoot":"","sources":["../../src/services/contributors.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAuB,SAAQ,WAAW;IACzD,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAQD;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAMlB,OAAO,CAAC,UAAU;IAL9B;;;;OAIG;gBACiB,UAAU,EAAE,aAAa;IAE7C;;;;;;;;;;;;;OAaG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,WAAW,EAAE,GACvB,OAAO,CAAC,sBAAsB,EAAE,CAAC;CAoJrC"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service for analyzing merge request contributors based on git blame data.
|
|
3
|
+
*
|
|
4
|
+
* Identifies previous contributors to modified code by analyzing git blame
|
|
5
|
+
* information and matching it against a whitelist of known contributors.
|
|
6
|
+
* Provides detailed information about which lines each contributor previously authored.
|
|
7
|
+
*/
|
|
8
|
+
export class ContributorsService {
|
|
9
|
+
dataSource;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a new ContributorsService instance.
|
|
12
|
+
*
|
|
13
|
+
* @param dataSource - The data source for accessing GitLab and git data
|
|
14
|
+
*/
|
|
15
|
+
constructor(dataSource) {
|
|
16
|
+
this.dataSource = dataSource;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Analyzes merge request diffs to identify previous contributors to modified code.
|
|
20
|
+
*
|
|
21
|
+
* Uses git blame to determine who previously authored the lines being removed
|
|
22
|
+
* in the merge request, then matches those authors against the whitelist.
|
|
23
|
+
* Returns contributors with detailed information about which files and line
|
|
24
|
+
* ranges they previously modified.
|
|
25
|
+
*
|
|
26
|
+
* @param project - The GitLab project identifier (ID or path)
|
|
27
|
+
* @param mr - The merge request IID
|
|
28
|
+
* @param base - The base commit SHA to blame against
|
|
29
|
+
* @param whitelist - Array of known contributors to match against
|
|
30
|
+
* @returns Array of contributors with their specific changes in this MR
|
|
31
|
+
*/
|
|
32
|
+
async getContributors(project, mr, base, whitelist) {
|
|
33
|
+
const diffs = await this.dataSource.getDiffs(project, mr);
|
|
34
|
+
console.error(`[Contributors] Processing ${diffs.length} diffs`);
|
|
35
|
+
const nested = await Promise.all(diffs.map(async ({ old_path: path, diff }) => {
|
|
36
|
+
if (!diff) {
|
|
37
|
+
console.error(`[Contributors] No diff for ${path}`);
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const blame = await this.dataSource.getBlame(project, path, base);
|
|
41
|
+
if (!blame) {
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
const blameLines = blame.reduce((result, { commit: { author_email }, lines }) => {
|
|
45
|
+
const contributor = whitelist.find((c) => c.email === author_email?.toLowerCase());
|
|
46
|
+
lines.forEach(() => result.push(contributor));
|
|
47
|
+
return result;
|
|
48
|
+
}, []);
|
|
49
|
+
console.error(`[Contributors] ${path}: ${blameLines.filter((c) => c).length}/${blameLines.length} lines matched whitelist`);
|
|
50
|
+
const linesRemoved = {};
|
|
51
|
+
const diffLines = diff
|
|
52
|
+
.split("\n")
|
|
53
|
+
.filter((line) => !line.startsWith("+"));
|
|
54
|
+
let diffIndex = 0;
|
|
55
|
+
let fragmentStart = null;
|
|
56
|
+
let lastContributor = undefined;
|
|
57
|
+
do {
|
|
58
|
+
const diffLineContent = diffLines[diffIndex];
|
|
59
|
+
if (!diffLineContent ||
|
|
60
|
+
diffLineContent === "\") {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (!diffLineContent.startsWith("@@")) {
|
|
64
|
+
console.error("Unexpected line", diffLineContent);
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
const [token] = diffLineContent.split("@@").slice(1, 2);
|
|
68
|
+
const [subToken] = token.split(" ").slice(1, 2);
|
|
69
|
+
const [startText, linesText] = subToken.replace("-", "").split(",");
|
|
70
|
+
const start = parseInt(startText);
|
|
71
|
+
const lines = linesText ? parseInt(linesText) : 1;
|
|
72
|
+
for (let i = 0; i < lines; i++) {
|
|
73
|
+
diffIndex++;
|
|
74
|
+
const blameIndex = start - 1 + i;
|
|
75
|
+
const contributor = blameLines[blameIndex];
|
|
76
|
+
if (diffLines[diffIndex]?.startsWith("-")) {
|
|
77
|
+
if (contributor !== lastContributor) {
|
|
78
|
+
if (lastContributor && lastContributor.email) {
|
|
79
|
+
const fragmentEnd = blameIndex;
|
|
80
|
+
const fragments = linesRemoved[lastContributor.email]?.fragments || [];
|
|
81
|
+
fragments.push(fragmentEnd > (fragmentStart || 0)
|
|
82
|
+
? `L${fragmentStart}-${fragmentEnd}`
|
|
83
|
+
: `L${fragmentStart}`);
|
|
84
|
+
linesRemoved[lastContributor.email] = {
|
|
85
|
+
path,
|
|
86
|
+
fragments,
|
|
87
|
+
by: lastContributor,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
fragmentStart = blameIndex + 1;
|
|
91
|
+
lastContributor = contributor;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (lastContributor && lastContributor.email) {
|
|
95
|
+
const fragmentEnd = blameIndex;
|
|
96
|
+
const fragments = linesRemoved[lastContributor.email]?.fragments || [];
|
|
97
|
+
fragments.push(fragmentEnd > (fragmentStart || 0)
|
|
98
|
+
? `L${fragmentStart}-${fragmentEnd}`
|
|
99
|
+
: `L${fragmentStart}`);
|
|
100
|
+
linesRemoved[lastContributor.email] = {
|
|
101
|
+
path,
|
|
102
|
+
fragments,
|
|
103
|
+
by: lastContributor,
|
|
104
|
+
};
|
|
105
|
+
fragmentStart = null;
|
|
106
|
+
lastContributor = undefined;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
diffIndex++;
|
|
110
|
+
} while (true);
|
|
111
|
+
if (lastContributor && lastContributor.email) {
|
|
112
|
+
const fragmentEnd = diffIndex - 1;
|
|
113
|
+
const fragments = linesRemoved[lastContributor.email]?.fragments || [];
|
|
114
|
+
fragments.push(fragmentEnd > (fragmentStart || 0)
|
|
115
|
+
? `L${fragmentStart}-${fragmentEnd}`
|
|
116
|
+
: `L${fragmentStart}`);
|
|
117
|
+
linesRemoved[lastContributor.email] = {
|
|
118
|
+
path,
|
|
119
|
+
fragments,
|
|
120
|
+
by: lastContributor,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
const removed = Object.values(linesRemoved);
|
|
124
|
+
console.error(`[Contributors] ${path}: ${removed.length} contributors with removed lines`);
|
|
125
|
+
return removed;
|
|
126
|
+
}));
|
|
127
|
+
const mapping = nested
|
|
128
|
+
.flat()
|
|
129
|
+
.reduce((result, { path, fragments, by: contributor }) => {
|
|
130
|
+
if (!contributor.email)
|
|
131
|
+
return result;
|
|
132
|
+
const contribution = result[contributor.email] || {
|
|
133
|
+
...contributor,
|
|
134
|
+
changes: [],
|
|
135
|
+
};
|
|
136
|
+
contribution.changes.push({ path, fragments });
|
|
137
|
+
return { ...result, [contributor.email]: contribution };
|
|
138
|
+
}, {});
|
|
139
|
+
const result = Object.values(mapping);
|
|
140
|
+
console.error(`[Contributors] Found ${result.length} contributors`);
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=contributors.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contributors.service.js","sourceRoot":"","sources":["../../src/services/contributors.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { AutoReviewerParams, AutoReviewerResult, ContributorAnalysisParams, WorkloadAnalysisParams, PostCommentParams, InviteReviewersParams, Contributor } from "../types.js";
|
|
2
|
+
import { Logger } from "../logging/logger.service.js";
|
|
3
|
+
import { CacheService } from "../cache/cache.service.js";
|
|
4
|
+
/**
|
|
5
|
+
* Main service for suggesting and managing merge request reviewers.
|
|
6
|
+
*
|
|
7
|
+
* Orchestrates multiple analysis strategies to suggest appropriate reviewers:
|
|
8
|
+
* - Previous contributors based on git blame analysis
|
|
9
|
+
* - Team members with FTE-aware load balancing
|
|
10
|
+
* - Code owners with approval requirements and load balancing
|
|
11
|
+
*
|
|
12
|
+
* Provides transparency into reviewer selection with detailed scoring and reasoning.
|
|
13
|
+
*/
|
|
14
|
+
export declare class ReviewerService {
|
|
15
|
+
private dataSource;
|
|
16
|
+
private contributorsService;
|
|
17
|
+
private whitelistService;
|
|
18
|
+
private blacklistService;
|
|
19
|
+
private codeOwnersService;
|
|
20
|
+
private teamMembersService;
|
|
21
|
+
private commentBuilderService;
|
|
22
|
+
private logger;
|
|
23
|
+
private cache?;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new ReviewerService instance.
|
|
26
|
+
*
|
|
27
|
+
* @param gitlabUrl - The base URL of the GitLab instance (e.g., 'https://gitlab.com')
|
|
28
|
+
* @param token - GitLab personal access token or API token
|
|
29
|
+
* @param repoPath - Optional local repository path for git operations (enables local mode)
|
|
30
|
+
* @param logger - Optional logger instance for structured logging
|
|
31
|
+
* @param cache - Optional cache service for performance optimization
|
|
32
|
+
*/
|
|
33
|
+
constructor(gitlabUrl: string, token: string, repoPath?: string, logger?: Logger, cache?: CacheService);
|
|
34
|
+
/**
|
|
35
|
+
* Suggests reviewers for a merge request using multiple analysis strategies.
|
|
36
|
+
*
|
|
37
|
+
* Analyzes the merge request to suggest appropriate reviewers based on:
|
|
38
|
+
* - Previous contributors to modified code (git blame analysis)
|
|
39
|
+
* - Team membership with FTE-aware load balancing
|
|
40
|
+
* - Code ownership rules with approval requirements
|
|
41
|
+
*
|
|
42
|
+
* Returns a formatted comment for posting to GitLab and detailed reviewer
|
|
43
|
+
* suggestions with transparency information (scores, reasoning, workload).
|
|
44
|
+
*
|
|
45
|
+
* @param params - Parameters including project, MR IID, or branch information
|
|
46
|
+
* @returns Reviewer suggestions with formatted comment and detailed analysis
|
|
47
|
+
* @throws Error if project/MR cannot be resolved or required data is unavailable
|
|
48
|
+
*/
|
|
49
|
+
suggestReviewers(params: AutoReviewerParams): Promise<AutoReviewerResult>;
|
|
50
|
+
/**
|
|
51
|
+
* Analyzes contributors for a merge request without suggesting reviewers.
|
|
52
|
+
*
|
|
53
|
+
* Provides detailed contributor analysis including which files were changed
|
|
54
|
+
* and which previous contributors modified those files. Useful for
|
|
55
|
+
* understanding contribution patterns without generating reviewer suggestions.
|
|
56
|
+
*
|
|
57
|
+
* @param params - Parameters including project and merge request IID
|
|
58
|
+
* @returns Changed files and contributors with their modification details
|
|
59
|
+
* @throws Error if merge request is not found or has no diffs
|
|
60
|
+
*/
|
|
61
|
+
getContributorAnalysis(params: ContributorAnalysisParams): Promise<{
|
|
62
|
+
changedFiles: (string | null)[];
|
|
63
|
+
contributors: Contributor[];
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Analyzes current reviewer workload across all open merge requests.
|
|
67
|
+
*
|
|
68
|
+
* Calculates how many open merge requests each reviewer is currently
|
|
69
|
+
* assigned to, useful for understanding team capacity and load distribution.
|
|
70
|
+
*
|
|
71
|
+
* @param params - Parameters including project identifier
|
|
72
|
+
* @returns Array of reviewers with their current open MR counts
|
|
73
|
+
*/
|
|
74
|
+
getReviewerWorkload(params: WorkloadAnalysisParams): Promise<{
|
|
75
|
+
reviewers: Array<{
|
|
76
|
+
username: string;
|
|
77
|
+
openMRs: number;
|
|
78
|
+
}>;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* Posts a comment to a GitLab merge request.
|
|
82
|
+
*
|
|
83
|
+
* @param params - Parameters including project, MR IID or branch, and comment text
|
|
84
|
+
* @returns The created note with ID and body
|
|
85
|
+
* @throws Error if project/MR cannot be resolved
|
|
86
|
+
*/
|
|
87
|
+
postComment(params: PostCommentParams): Promise<{
|
|
88
|
+
id: number;
|
|
89
|
+
body: string;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Suggests reviewers and posts the suggestion comment to the merge request.
|
|
93
|
+
*
|
|
94
|
+
* Combines suggestReviewers() and postComment() into a single operation.
|
|
95
|
+
*
|
|
96
|
+
* @param params - Parameters including project, MR IID or branch
|
|
97
|
+
* @returns Reviewer suggestions with formatted comment (same as suggestReviewers)
|
|
98
|
+
* @throws Error if project/MR cannot be resolved or comment posting fails
|
|
99
|
+
*/
|
|
100
|
+
inviteReviewers(params: InviteReviewersParams): Promise<AutoReviewerResult>;
|
|
101
|
+
/**
|
|
102
|
+
* Helper method to fetch data with optional caching
|
|
103
|
+
* If cache is not available, directly executes the operation
|
|
104
|
+
*/
|
|
105
|
+
private fetchWithCache;
|
|
106
|
+
/**
|
|
107
|
+
* Extract result from Promise.allSettled with partial failure handling
|
|
108
|
+
* If the promise failed and a fallback is provided, returns the fallback
|
|
109
|
+
* If the promise failed and no fallback is provided, throws the error
|
|
110
|
+
*/
|
|
111
|
+
private extractResult;
|
|
112
|
+
/**
|
|
113
|
+
* Build a detailed contributor suggestion with transparency information
|
|
114
|
+
*/
|
|
115
|
+
private buildContributorSuggestion;
|
|
116
|
+
/**
|
|
117
|
+
* Build a detailed team member suggestion with transparency information
|
|
118
|
+
*/
|
|
119
|
+
private buildTeamMemberSuggestion;
|
|
120
|
+
/**
|
|
121
|
+
* Build a detailed code owner suggestion with transparency information
|
|
122
|
+
*/
|
|
123
|
+
private buildCodeOwnerSuggestion;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=reviewer-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewer-service.d.ts","sourceRoot":"","sources":["../../src/services/reviewer-service.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,WAAW,EAEZ,MAAM,aAAa,CAAC;AAQrB,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAC,CAAe;IAE7B;;;;;;;;OAQG;gBAED,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,YAAY;IAkBtB;;;;;;;;;;;;;;OAcG;IACG,gBAAgB,CACpB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,kBAAkB,CAAC;IAsM9B;;;;;;;;;;OAUG;IACG,sBAAsB,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC;QACvE,YAAY,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;QAChC,YAAY,EAAE,WAAW,EAAE,CAAC;KAC7B,CAAC;IAuDF;;;;;;;;OAQG;IACG,mBAAmB,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC;QACjE,SAAS,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KACzD,CAAC;IAqCF;;;;;;OAMG;IACG,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAkDnF;;;;;;;;OAQG;IACG,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkBjF;;;OAGG;YACW,cAAc;IAW5B;;;;OAIG;IACH,OAAO,CAAC,aAAa;IA0BrB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA4DlC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAmEjC;;OAEG;IACH,OAAO,CAAC,wBAAwB;CAmEjC"}
|