mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-10 13:36:45 +03:00
fix: mirror releases during sync
This commit is contained in:
@@ -7,6 +7,9 @@ mock.module("@/lib/helpers", () => ({
|
|||||||
createMirrorJob: mockCreateMirrorJob
|
createMirrorJob: mockCreateMirrorJob
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const mockMirrorGitHubReleasesToGitea = mock(() => Promise.resolve());
|
||||||
|
const mockGetGiteaRepoOwnerAsync = mock(() => Promise.resolve("starred"));
|
||||||
|
|
||||||
// Mock the database module
|
// Mock the database module
|
||||||
const mockDb = {
|
const mockDb = {
|
||||||
insert: mock((table: any) => ({
|
insert: mock((table: any) => ({
|
||||||
@@ -220,6 +223,9 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
mockCreateMirrorJob.mockClear();
|
mockCreateMirrorJob.mockClear();
|
||||||
mockDb.insert.mockClear();
|
mockDb.insert.mockClear();
|
||||||
mockDb.update.mockClear();
|
mockDb.update.mockClear();
|
||||||
|
mockMirrorGitHubReleasesToGitea.mockClear();
|
||||||
|
mockGetGiteaRepoOwnerAsync.mockClear();
|
||||||
|
mockGetGiteaRepoOwnerAsync.mockImplementation(() => Promise.resolve("starred"));
|
||||||
// Reset tracking variables
|
// Reset tracking variables
|
||||||
orgCheckCount = 0;
|
orgCheckCount = 0;
|
||||||
orgTestContext = "";
|
orgTestContext = "";
|
||||||
@@ -250,6 +256,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -280,6 +287,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -306,6 +314,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -362,6 +371,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -391,6 +401,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -409,18 +420,17 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock getGiteaRepoOwnerAsync
|
|
||||||
const mockGetOwner = mock(() => Promise.resolve("starred"));
|
|
||||||
global.import = mock(async (path: string) => {
|
|
||||||
if (path === "./gitea") {
|
|
||||||
return { getGiteaRepoOwnerAsync: mockGetOwner };
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}) as any;
|
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
syncGiteaRepoEnhanced({ config, repository })
|
syncGiteaRepoEnhanced(
|
||||||
|
{ config, repository },
|
||||||
|
{
|
||||||
|
getGiteaRepoOwnerAsync: mockGetGiteaRepoOwnerAsync,
|
||||||
|
mirrorGitHubReleasesToGitea: mockMirrorGitHubReleasesToGitea,
|
||||||
|
}
|
||||||
|
)
|
||||||
).rejects.toThrow("Repository non-mirror-repo is not a mirror. Cannot sync.");
|
).rejects.toThrow("Repository non-mirror-repo is not a mirror. Cannot sync.");
|
||||||
|
|
||||||
|
expect(mockMirrorGitHubReleasesToGitea).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should successfully sync a mirror repository", async () => {
|
test("should successfully sync a mirror repository", async () => {
|
||||||
@@ -436,6 +446,7 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
url: "https://gitea.example.com",
|
url: "https://gitea.example.com",
|
||||||
token: "encrypted-token",
|
token: "encrypted-token",
|
||||||
defaultOwner: "testuser",
|
defaultOwner: "testuser",
|
||||||
|
mirrorReleases: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -454,18 +465,22 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock getGiteaRepoOwnerAsync
|
const result = await syncGiteaRepoEnhanced(
|
||||||
const mockGetOwner = mock(() => Promise.resolve("starred"));
|
{ config, repository },
|
||||||
global.import = mock(async (path: string) => {
|
{
|
||||||
if (path === "./gitea") {
|
getGiteaRepoOwnerAsync: mockGetGiteaRepoOwnerAsync,
|
||||||
return { getGiteaRepoOwnerAsync: mockGetOwner };
|
mirrorGitHubReleasesToGitea: mockMirrorGitHubReleasesToGitea,
|
||||||
}
|
}
|
||||||
return {};
|
);
|
||||||
}) as any;
|
|
||||||
|
|
||||||
const result = await syncGiteaRepoEnhanced({ config, repository });
|
|
||||||
|
|
||||||
expect(result).toEqual({ success: true });
|
expect(result).toEqual({ success: true });
|
||||||
|
expect(mockGetGiteaRepoOwnerAsync).toHaveBeenCalled();
|
||||||
|
expect(mockMirrorGitHubReleasesToGitea).toHaveBeenCalledTimes(1);
|
||||||
|
const releaseCall = mockMirrorGitHubReleasesToGitea.mock.calls[0][0];
|
||||||
|
expect(releaseCall.giteaOwner).toBe("starred");
|
||||||
|
expect(releaseCall.giteaRepoName).toBe("mirror-repo");
|
||||||
|
expect(releaseCall.config.githubConfig?.token).toBe("github-token");
|
||||||
|
expect(releaseCall.octokit).toBeDefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -567,4 +582,4 @@ describe("Enhanced Gitea Operations", () => {
|
|||||||
expect(deleteCalled).toBe(true);
|
expect(deleteCalled).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
import type { Config } from "@/types/config";
|
import type { Config } from "@/types/config";
|
||||||
import type { Repository } from "./db/schema";
|
import type { Repository } from "./db/schema";
|
||||||
|
import { Octokit } from "@octokit/rest";
|
||||||
import { createMirrorJob } from "./helpers";
|
import { createMirrorJob } from "./helpers";
|
||||||
import { decryptConfigTokens } from "./utils/config-encryption";
|
import { decryptConfigTokens } from "./utils/config-encryption";
|
||||||
import { httpPost, httpGet, httpPatch, HttpError } from "./http-client";
|
import { httpPost, httpGet, httpPatch, HttpError } from "./http-client";
|
||||||
@@ -15,6 +16,11 @@ import { db, repositories } from "./db";
|
|||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { repoStatusEnum } from "@/types/Repository";
|
import { repoStatusEnum } from "@/types/Repository";
|
||||||
|
|
||||||
|
type SyncDependencies = {
|
||||||
|
getGiteaRepoOwnerAsync: typeof import("./gitea")["getGiteaRepoOwnerAsync"];
|
||||||
|
mirrorGitHubReleasesToGitea: typeof import("./gitea")["mirrorGitHubReleasesToGitea"];
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enhanced repository information including mirror status
|
* Enhanced repository information including mirror status
|
||||||
*/
|
*/
|
||||||
@@ -239,7 +245,7 @@ export async function syncGiteaRepoEnhanced({
|
|||||||
}: {
|
}: {
|
||||||
config: Partial<Config>;
|
config: Partial<Config>;
|
||||||
repository: Repository;
|
repository: Repository;
|
||||||
}): Promise<any> {
|
}, deps?: SyncDependencies): Promise<any> {
|
||||||
try {
|
try {
|
||||||
if (!config.userId || !config.giteaConfig?.url || !config.giteaConfig?.token) {
|
if (!config.userId || !config.giteaConfig?.url || !config.giteaConfig?.token) {
|
||||||
throw new Error("Gitea config is required.");
|
throw new Error("Gitea config is required.");
|
||||||
@@ -259,8 +265,8 @@ export async function syncGiteaRepoEnhanced({
|
|||||||
.where(eq(repositories.id, repository.id!));
|
.where(eq(repositories.id, repository.id!));
|
||||||
|
|
||||||
// Get the expected owner
|
// Get the expected owner
|
||||||
const { getGiteaRepoOwnerAsync } = await import("./gitea");
|
const dependencies = deps ?? (await import("./gitea"));
|
||||||
const repoOwner = await getGiteaRepoOwnerAsync({ config, repository });
|
const repoOwner = await dependencies.getGiteaRepoOwnerAsync({ config, repository });
|
||||||
|
|
||||||
// Check if repo exists and get its info
|
// Check if repo exists and get its info
|
||||||
const repoInfo = await getGiteaRepoInfo({
|
const repoInfo = await getGiteaRepoInfo({
|
||||||
@@ -324,6 +330,36 @@ export async function syncGiteaRepoEnhanced({
|
|||||||
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
Authorization: `token ${decryptedConfig.giteaConfig.token}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shouldMirrorReleases =
|
||||||
|
decryptedConfig.giteaConfig?.mirrorReleases &&
|
||||||
|
!(repository.isStarred && decryptedConfig.githubConfig?.starredCodeOnly);
|
||||||
|
|
||||||
|
if (shouldMirrorReleases) {
|
||||||
|
if (!decryptedConfig.githubConfig?.token) {
|
||||||
|
console.warn(
|
||||||
|
`[Sync] Skipping release mirroring for ${repository.name}: Missing GitHub token`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
const octokit = new Octokit({ auth: decryptedConfig.githubConfig.token });
|
||||||
|
await dependencies.mirrorGitHubReleasesToGitea({
|
||||||
|
config: decryptedConfig,
|
||||||
|
octokit,
|
||||||
|
repository,
|
||||||
|
giteaOwner: repoOwner,
|
||||||
|
giteaRepoName: repository.name,
|
||||||
|
});
|
||||||
|
console.log(`[Sync] Mirrored releases for ${repository.name} after sync`);
|
||||||
|
} catch (releaseError) {
|
||||||
|
console.error(
|
||||||
|
`[Sync] Failed to mirror releases for ${repository.name}: ${
|
||||||
|
releaseError instanceof Error ? releaseError.message : String(releaseError)
|
||||||
|
}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Mark repo as "synced" in DB
|
// Mark repo as "synced" in DB
|
||||||
await db
|
await db
|
||||||
.update(repositories)
|
.update(repositories)
|
||||||
@@ -535,4 +571,4 @@ export async function handleExistingNonMirrorRepo({
|
|||||||
// TODO: Implement rename strategy if needed
|
// TODO: Implement rename strategy if needed
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user