Merge pull request #1821 from Dokploy/1798-gitea-provider-only-returns-a-subset-of-repositories-to-choose-from

Refactor Gitea repository fetching to handle pagination
This commit is contained in:
Mauricio Siu
2025-05-04 21:07:47 -06:00
committed by GitHub
2 changed files with 85 additions and 39 deletions

View File

@@ -381,6 +381,9 @@ export const SaveGiteaProvider = ({ applicationId }: Props) => {
<CommandEmpty>No branch found.</CommandEmpty> <CommandEmpty>No branch found.</CommandEmpty>
<CommandGroup> <CommandGroup>
{branches && branches.length === 0 && (
<CommandItem>No branches found.</CommandItem>
)}
{branches?.map((branch: GiteaBranch) => ( {branches?.map((branch: GiteaBranch) => (
<CommandItem <CommandItem
value={branch.name} value={branch.name}

View File

@@ -362,27 +362,48 @@ export const testGiteaConnection = async (input: { giteaId: string }) => {
} }
const baseUrl = provider.giteaUrl.replace(/\/+$/, ""); const baseUrl = provider.giteaUrl.replace(/\/+$/, "");
const url = `${baseUrl}/api/v1/user/repos`; const limit = 30;
let allRepos = 0;
let nextUrl = `${baseUrl}/api/v1/repos/search?limit=${limit}`;
const response = await fetch(url, { while (nextUrl) {
headers: { const response = await fetch(nextUrl, {
Accept: "application/json", headers: {
Authorization: `token ${provider.accessToken}`, Accept: "application/json",
}, Authorization: `token ${provider.accessToken}`,
}); },
});
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
`Failed to connect to Gitea API: ${response.status} ${response.statusText}`, `Failed to connect to Gitea API: ${response.status} ${response.statusText}`,
); );
}
const repos = await response.json();
allRepos += repos.data.length;
const linkHeader = response.headers.get("link");
nextUrl = "";
if (linkHeader) {
const nextLink = linkHeader
.split(",")
.find((link) => link.includes('rel="next"'));
if (nextLink) {
const matches = nextLink.match(/<([^>]+)>/);
if (matches?.[1]) {
nextUrl = matches[1];
}
}
}
} }
const repos = await response.json();
await updateGitea(giteaId, { await updateGitea(giteaId, {
lastAuthenticatedAt: Math.floor(Date.now() / 1000), lastAuthenticatedAt: Math.floor(Date.now() / 1000),
}); });
return repos.length; return allRepos;
} catch (error) { } catch (error) {
throw error; throw error;
} }
@@ -394,38 +415,57 @@ export const getGiteaRepositories = async (giteaId?: string) => {
} }
await refreshGiteaToken(giteaId); await refreshGiteaToken(giteaId);
const giteaProvider = await findGiteaById(giteaId); const giteaProvider = await findGiteaById(giteaId);
const baseUrl = giteaProvider.giteaUrl.replace(/\/+$/, ""); const baseUrl = giteaProvider.giteaUrl.replace(/\/+$/, "");
const url = `${baseUrl}/api/v1/user/repos`; const limit = 30;
let allRepositories: any[] = [];
let nextUrl = `${baseUrl}/api/v1/repos/search?limit=${limit}`;
const response = await fetch(url, { while (nextUrl) {
headers: { const response = await fetch(nextUrl, {
Accept: "application/json", headers: {
Authorization: `token ${giteaProvider.accessToken}`, Accept: "application/json",
}, Authorization: `token ${giteaProvider.accessToken}`,
}); },
if (!response.ok) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Failed to fetch repositories: ${response.statusText}`,
}); });
if (!response.ok) {
throw new TRPCError({
code: "BAD_REQUEST",
message: `Failed to fetch repositories: ${response.statusText}`,
});
}
const result = await response.json();
allRepositories = [...allRepositories, ...result.data];
const linkHeader = response.headers.get("link");
nextUrl = "";
if (linkHeader) {
const nextLink = linkHeader
.split(",")
.find((link) => link.includes('rel="next"'));
if (nextLink) {
const matches = nextLink.match(/<([^>]+)>/);
if (matches?.[1]) {
nextUrl = matches[1];
}
}
}
} }
const repositories = await response.json(); return (
allRepositories?.map((repo: any) => ({
const mappedRepositories = repositories.map((repo: any) => ({ id: repo.id,
id: repo.id, name: repo.name,
name: repo.name, url: repo.full_name,
url: repo.full_name, owner: {
owner: { username: repo.owner.login,
username: repo.owner.login, },
}, })) || []
})); );
return mappedRepositories;
}; };
export const getGiteaBranches = async (input: { export const getGiteaBranches = async (input: {
@@ -457,7 +497,10 @@ export const getGiteaBranches = async (input: {
const branches = await response.json(); const branches = await response.json();
return branches.map((branch: any) => ({ if (!branches) {
return [];
}
return branches?.map((branch: any) => ({
id: branch.name, id: branch.name,
name: branch.name, name: branch.name,
commit: { commit: {