Skip to content

Commit 6c78842

Browse files
authored
Merge pull request #1910 from Dokploy/1894-gitlab-self-hosted-cannot-find-all-repository
refactor: streamline GitLab repository fetching by introducing valida…
2 parents 94a6a95 + 3176a9d commit 6c78842

1 file changed

Lines changed: 49 additions & 39 deletions

File tree

packages/server/src/utils/providers/gitlab.ts

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -246,32 +246,16 @@ export const getGitlabRepositories = async (gitlabId?: string) => {
246246

247247
const gitlabProvider = await findGitlabById(gitlabId);
248248

249-
const response = await fetch(
250-
`${gitlabProvider.gitlabUrl}/api/v4/projects?membership=true&owned=true&page=${0}&per_page=${100}`,
251-
{
252-
headers: {
253-
Authorization: `Bearer ${gitlabProvider.accessToken}`,
254-
},
255-
},
256-
);
257-
258-
if (!response.ok) {
259-
throw new TRPCError({
260-
code: "BAD_REQUEST",
261-
message: `Failed to fetch repositories: ${response.statusText}`,
262-
});
263-
}
264-
265-
const repositories = await response.json();
249+
const allProjects = await validateGitlabProvider(gitlabProvider);
266250

267-
const filteredRepos = repositories.filter((repo: any) => {
251+
const filteredRepos = allProjects.filter((repo: any) => {
268252
const { full_path, kind } = repo.namespace;
269253
const groupName = gitlabProvider.groupName?.toLowerCase();
270254

271255
if (groupName) {
272256
const isIncluded = groupName
273257
.split(",")
274-
.some((name) => full_path.toLowerCase().includes(name));
258+
.some((name) => full_path === name);
275259

276260
return isIncluded && kind === "group";
277261
}
@@ -432,34 +416,60 @@ export const testGitlabConnection = async (
432416

433417
const gitlabProvider = await findGitlabById(gitlabId);
434418

435-
const response = await fetch(
436-
`${gitlabProvider.gitlabUrl}/api/v4/projects?membership=true&owned=true&page=${0}&per_page=${100}`,
437-
{
438-
headers: {
439-
Authorization: `Bearer ${gitlabProvider.accessToken}`,
440-
},
441-
},
442-
);
443-
444-
if (!response.ok) {
445-
throw new TRPCError({
446-
code: "BAD_REQUEST",
447-
message: `Failed to fetch repositories: ${response.statusText}`,
448-
});
449-
}
450-
451-
const repositories = await response.json();
419+
const repositories = await validateGitlabProvider(gitlabProvider);
452420

453421
const filteredRepos = repositories.filter((repo: any) => {
454422
const { full_path, kind } = repo.namespace;
455423

456424
if (groupName) {
457-
return groupName
458-
.split(",")
459-
.some((name) => full_path.toLowerCase().includes(name));
425+
return groupName.split(",").some((name) => full_path === name);
460426
}
461427
return kind === "user";
462428
});
463429

464430
return filteredRepos.length;
465431
};
432+
433+
export const validateGitlabProvider = async (gitlabProvider: Gitlab) => {
434+
try {
435+
const allProjects = [];
436+
let page = 1;
437+
const perPage = 100; // GitLab's max per page is 100
438+
439+
while (true) {
440+
const response = await fetch(
441+
`${gitlabProvider.gitlabUrl}/api/v4/projects?membership=true&owned=true&page=${page}&per_page=${perPage}`,
442+
{
443+
headers: {
444+
Authorization: `Bearer ${gitlabProvider.accessToken}`,
445+
},
446+
},
447+
);
448+
449+
if (!response.ok) {
450+
throw new TRPCError({
451+
code: "BAD_REQUEST",
452+
message: `Failed to fetch repositories: ${response.statusText}`,
453+
});
454+
}
455+
456+
const projects = await response.json();
457+
458+
if (projects.length === 0) {
459+
break;
460+
}
461+
462+
allProjects.push(...projects);
463+
page++;
464+
465+
const total = response.headers.get("x-total");
466+
if (total && allProjects.length >= Number.parseInt(total)) {
467+
break;
468+
}
469+
}
470+
471+
return allProjects;
472+
} catch (error) {
473+
throw error;
474+
}
475+
};

0 commit comments

Comments
 (0)