This commit is contained in:
2026-03-05 12:05:57 +00:00
parent cd6a97dd2d
commit 6260e90b09
8 changed files with 162 additions and 306 deletions

View File

@@ -18,130 +18,47 @@ export class GitLabProvider extends BaseProvider {
}
async getProjects(opts?: IListOptions): Promise<interfaces.data.IProject[]> {
if (this.groupFilterId) {
// Auto-paginate group-scoped project listing
if (opts?.page) {
const projects = await this.client.getGroupProjects(this.groupFilterId, opts);
return projects.map((p) => this.mapProject(p));
}
const allProjects: plugins.gitlabClient.IGitLabProject[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const projects = await this.client.getGroupProjects(this.groupFilterId, { ...opts, page, perPage });
allProjects.push(...projects);
if (projects.length < perPage) break;
page++;
}
return allProjects.map((p) => this.mapProject(p));
}
if (opts?.page) {
const projects = await this.client.getProjects(opts);
return projects.map((p) => this.mapProject(p));
}
const allProjects: plugins.gitlabClient.IGitLabProject[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const projects = await this.client.getProjects({ ...opts, page, perPage });
allProjects.push(...projects);
if (projects.length < perPage) break;
page++;
}
return allProjects.map((p) => this.mapProject(p));
const projects = this.groupFilterId
? await (await this.client.getGroup(this.groupFilterId)).getProjects(opts)
: await this.client.getProjects(opts);
return projects.map((p) => this.mapProject(p));
}
async getGroups(opts?: IListOptions): Promise<interfaces.data.IGroup[]> {
if (this.groupFilterId) {
// Auto-paginate descendant groups listing
if (opts?.page) {
const groups = await this.client.getDescendantGroups(this.groupFilterId, opts);
return groups.map((g) => this.mapGroup(g));
}
const allGroups: plugins.gitlabClient.IGitLabGroup[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const groups = await this.client.getDescendantGroups(this.groupFilterId, { ...opts, page, perPage });
allGroups.push(...groups);
if (groups.length < perPage) break;
page++;
}
return allGroups.map((g) => this.mapGroup(g));
const group = await this.client.getGroup(this.groupFilterId);
const descendants = await group.getDescendantGroups(opts);
return descendants.map((g) => this.mapGroup(g));
}
if (opts?.page) {
const groups = await this.client.getGroups(opts);
return groups.map((g) => this.mapGroup(g));
}
const allGroups: plugins.gitlabClient.IGitLabGroup[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const groups = await this.client.getGroups({ ...opts, page, perPage });
allGroups.push(...groups);
if (groups.length < perPage) break;
page++;
}
return allGroups.map((g) => this.mapGroup(g));
const groups = await this.client.getGroups(opts);
return groups.map((g) => this.mapGroup(g));
}
async getGroupProjects(groupId: string, opts?: IListOptions): Promise<interfaces.data.IProject[]> {
if (opts?.page) {
const projects = await this.client.getGroupProjects(groupId, opts);
return projects.map((p) => this.mapProject(p));
}
const allProjects: plugins.gitlabClient.IGitLabProject[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const projects = await this.client.getGroupProjects(groupId, { ...opts, page, perPage });
allProjects.push(...projects);
if (projects.length < perPage) break;
page++;
}
return allProjects.map((p) => this.mapProject(p));
const group = await this.client.getGroup(groupId);
const projects = await group.getProjects(opts);
return projects.map((p) => this.mapProject(p));
}
// --- Branches / Tags ---
async getBranches(projectFullPath: string, opts?: IListOptions): Promise<interfaces.data.IBranch[]> {
if (opts?.page) {
const branches = await this.client.getRepoBranches(projectFullPath, opts);
return branches.map((b) => ({ name: b.name, commitSha: b.commit.id }));
}
const all: interfaces.data.IBranch[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const branches = await this.client.getRepoBranches(projectFullPath, { ...opts, page, perPage });
all.push(...branches.map((b) => ({ name: b.name, commitSha: b.commit.id })));
if (branches.length < perPage) break;
page++;
}
return all;
const project = await this.client.getProject(projectFullPath);
const branches = await project.getBranches(opts);
return branches.map((b) => ({ name: b.name, commitSha: b.commitSha }));
}
async getTags(projectFullPath: string, opts?: IListOptions): Promise<interfaces.data.ITag[]> {
if (opts?.page) {
const tags = await this.client.getRepoTags(projectFullPath, opts);
return tags.map((t) => ({ name: t.name, commitSha: t.commit.id }));
}
const all: interfaces.data.ITag[] = [];
const perPage = opts?.perPage || 50;
let page = 1;
while (true) {
const tags = await this.client.getRepoTags(projectFullPath, { ...opts, page, perPage });
all.push(...tags.map((t) => ({ name: t.name, commitSha: t.commit.id })));
if (tags.length < perPage) break;
page++;
}
return all;
const project = await this.client.getProject(projectFullPath);
const tags = await project.getTags(opts);
return tags.map((t) => ({ name: t.name, commitSha: t.commitSha }));
}
// --- Project Secrets (CI/CD Variables) ---
async getProjectSecrets(projectId: string): Promise<interfaces.data.ISecret[]> {
const vars = await this.client.getProjectVariables(projectId);
const project = await this.client.getProject(projectId);
const vars = await project.getVariables();
return vars.map((v) => this.mapVariable(v, 'project', projectId));
}
@@ -150,7 +67,8 @@ export class GitLabProvider extends BaseProvider {
key: string,
value: string,
): Promise<interfaces.data.ISecret> {
const v = await this.client.createProjectVariable(projectId, key, value);
const project = await this.client.getProject(projectId);
const v = await project.createVariable(key, value);
return this.mapVariable(v, 'project', projectId);
}
@@ -159,18 +77,21 @@ export class GitLabProvider extends BaseProvider {
key: string,
value: string,
): Promise<interfaces.data.ISecret> {
const v = await this.client.updateProjectVariable(projectId, key, value);
const project = await this.client.getProject(projectId);
const v = await project.updateVariable(key, value);
return this.mapVariable(v, 'project', projectId);
}
async deleteProjectSecret(projectId: string, key: string): Promise<void> {
await this.client.deleteProjectVariable(projectId, key);
const project = await this.client.getProject(projectId);
await project.deleteVariable(key);
}
// --- Group Secrets (CI/CD Variables) ---
async getGroupSecrets(groupId: string): Promise<interfaces.data.ISecret[]> {
const vars = await this.client.getGroupVariables(groupId);
const group = await this.client.getGroup(groupId);
const vars = await group.getVariables();
return vars.map((v) => this.mapVariable(v, 'group', groupId));
}
@@ -179,7 +100,8 @@ export class GitLabProvider extends BaseProvider {
key: string,
value: string,
): Promise<interfaces.data.ISecret> {
const v = await this.client.createGroupVariable(groupId, key, value);
const group = await this.client.getGroup(groupId);
const v = await group.createVariable(key, value);
return this.mapVariable(v, 'group', groupId);
}
@@ -188,12 +110,14 @@ export class GitLabProvider extends BaseProvider {
key: string,
value: string,
): Promise<interfaces.data.ISecret> {
const v = await this.client.updateGroupVariable(groupId, key, value);
const group = await this.client.getGroup(groupId);
const v = await group.updateVariable(key, value);
return this.mapVariable(v, 'group', groupId);
}
async deleteGroupSecret(groupId: string, key: string): Promise<void> {
await this.client.deleteGroupVariable(groupId, key);
const group = await this.client.getGroup(groupId);
await group.deleteVariable(key);
}
// --- Pipelines ---
@@ -202,7 +126,8 @@ export class GitLabProvider extends BaseProvider {
projectId: string,
opts?: IPipelineListOptions,
): Promise<interfaces.data.IPipeline[]> {
const pipelines = await this.client.getPipelines(projectId, {
const project = await this.client.getProject(projectId);
const pipelines = await project.getPipelines({
page: opts?.page,
perPage: opts?.perPage,
status: opts?.status,
@@ -216,83 +141,82 @@ export class GitLabProvider extends BaseProvider {
projectId: string,
pipelineId: string,
): Promise<interfaces.data.IPipelineJob[]> {
const jobs = await this.client.getPipelineJobs(projectId, Number(pipelineId));
const jobs = await this.client.requestGetPipelineJobs(projectId, Number(pipelineId));
return jobs.map((j) => this.mapJob(j, pipelineId));
}
async getJobLog(projectId: string, jobId: string): Promise<string> {
return this.client.getJobLog(projectId, Number(jobId));
return this.client.requestGetJobLog(projectId, Number(jobId));
}
async retryPipeline(projectId: string, pipelineId: string): Promise<void> {
await this.client.retryPipeline(projectId, Number(pipelineId));
await this.client.requestRetryPipeline(projectId, Number(pipelineId));
}
async cancelPipeline(projectId: string, pipelineId: string): Promise<void> {
await this.client.cancelPipeline(projectId, Number(pipelineId));
await this.client.requestCancelPipeline(projectId, Number(pipelineId));
}
// --- Mappers ---
private mapProject(p: plugins.gitlabClient.IGitLabProject): interfaces.data.IProject {
private mapProject(p: plugins.gitlabClient.GitLabProject): interfaces.data.IProject {
return {
id: String(p.id),
name: p.name || '',
fullPath: p.path_with_namespace || '',
description: p.description || '',
defaultBranch: p.default_branch || 'main',
webUrl: p.web_url || '',
name: p.name,
fullPath: p.fullPath,
description: p.description,
defaultBranch: p.defaultBranch,
webUrl: p.webUrl,
connectionId: this.connectionId,
visibility: p.visibility || 'private',
topics: p.topics || [],
lastActivity: p.last_activity_at || '',
visibility: p.visibility,
topics: p.topics,
lastActivity: p.lastActivityAt,
};
}
private mapGroup(g: plugins.gitlabClient.IGitLabGroup): interfaces.data.IGroup {
private mapGroup(g: plugins.gitlabClient.GitLabGroup): interfaces.data.IGroup {
return {
id: String(g.id),
name: g.name || '',
fullPath: g.full_path || '',
description: g.description || '',
webUrl: g.web_url || '',
name: g.name,
fullPath: g.fullPath,
description: g.description,
webUrl: g.webUrl,
connectionId: this.connectionId,
visibility: g.visibility || 'private',
visibility: g.visibility,
projectCount: 0,
};
}
private mapVariable(
v: plugins.gitlabClient.IGitLabVariable,
v: plugins.gitlabClient.GitLabVariable,
scope: 'project' | 'group',
scopeId: string,
scopeName?: string,
): interfaces.data.ISecret {
return {
key: v.key || '',
key: v.key,
value: v.value || '***',
protected: v.protected || false,
masked: v.masked || false,
protected: v.protected,
masked: v.masked,
scope,
scopeId,
scopeName: scopeName || scopeId,
scopeName: scopeId,
connectionId: this.connectionId,
environment: v.environment_scope || '*',
environment: v.environmentScope,
};
}
private mapPipeline(p: plugins.gitlabClient.IGitLabPipeline, projectId: string, projectName?: string): interfaces.data.IPipeline {
private mapPipeline(p: plugins.gitlabClient.GitLabPipeline, projectId: string): interfaces.data.IPipeline {
return {
id: String(p.id),
projectId,
projectName: projectName || projectId,
projectName: projectId,
connectionId: this.connectionId,
status: (p.status || 'pending') as interfaces.data.TPipelineStatus,
ref: p.ref || '',
sha: p.sha || '',
webUrl: p.web_url || '',
duration: p.duration || 0,
createdAt: p.created_at || '',
ref: p.ref,
sha: p.sha,
webUrl: p.webUrl,
duration: p.duration,
createdAt: p.createdAt,
source: p.source || 'push',
};
}