mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-10-30 22:21:58 +01:00
feat: mirror from GitLab and Gitea/Forgejo sources (#376)
Adds a Source dropdown to the configuration card (GitHub, GitLab beta, Gitea/Forgejo) backed by a source provider interface with three adapters. Discovery, mirroring, recovery and cleanup go through the provider; repositories record their source (migration 0015); clone credentials are built per host and a repository from another host is refused at the mirror sites. Issues, pull requests, releases and star lists stay GitHub only. The destination card gets a Gitea/Forgejo dropdown, and both hosts lock once repositories exist, with an explicit confirmation to change. Closes #375. Helps #371. Claude-Session: https://claude.ai/code/session_01Tp9pmi65a8k5jLMQFLf4JX
This commit is contained in:
1 parent
a579934539
commit
d211e54877
64 files changed
+6740
-465
No files matched your search
@@ -354,6 +354,60 @@ function verify0014Migration(db: any) {
|
||||
assert(parsed.lfs === false, `Expected persisted lfs override false, got ${updated.mirror_overrides}`);
|
||||
}
|
||||
|
||||
function seedPre0015Database(db: any) {
|
||||
// Migrations 0000-0014 have run, so repositories exist but carry no source
|
||||
// columns. Seed one so the column-add can be verified against a
|
||||
// pre-existing row: everything before 0015 came from GitHub.
|
||||
db.run("INSERT INTO users (id, email, username, name) VALUES ('u-src', 'src@example.com', 'src', 'Source User')");
|
||||
db.run("INSERT INTO configs (id, user_id, name, is_active, github_config, gitea_config, schedule_config, cleanup_config) VALUES ('cfg-pre15', 'u-src', 'Default', 1, '{}', '{}', '{}', '{}')");
|
||||
db.run(
|
||||
"INSERT INTO repositories (id, user_id, config_id, name, full_name, normalized_full_name, url, clone_url, owner, default_branch) " +
|
||||
"VALUES ('repo-pre15', 'u-src', 'cfg-pre15', 'tool', 'src/tool', 'src/tool', 'https://github.com/src/tool', 'https://github.com/src/tool.git', 'src', 'main')",
|
||||
);
|
||||
}
|
||||
|
||||
function verify0015Migration(db: any) {
|
||||
const cols = db
|
||||
.query("PRAGMA table_info(repositories)")
|
||||
.all() as Array<{ name: string; type: string; notnull: number; dflt_value: string | null }>;
|
||||
|
||||
for (const [name, expectedDefault] of [
|
||||
["source_provider", "'github'"],
|
||||
["source_url", "'https://github.com'"],
|
||||
] as const) {
|
||||
const col = cols.find((c) => c.name === name);
|
||||
assert(col, `Expected repositories.${name} column to exist`);
|
||||
assert(col.notnull === 1, `Expected repositories.${name} to be NOT NULL`);
|
||||
assert(
|
||||
col.dflt_value === expectedDefault,
|
||||
`Expected repositories.${name} default ${expectedDefault}, got ${col.dflt_value}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Pre-existing rows are backfilled as GitHub, which is where they came from.
|
||||
const existing = db
|
||||
.query("SELECT source_provider, source_url FROM repositories WHERE id = 'repo-pre15'")
|
||||
.get() as { source_provider: string; source_url: string } | null;
|
||||
assert(existing, "Expected pre-existing repository row to survive migration");
|
||||
assert(
|
||||
existing.source_provider === "github" && existing.source_url === "https://github.com",
|
||||
`Expected existing repository to default to GitHub, got ${JSON.stringify(existing)}`,
|
||||
);
|
||||
|
||||
// New rows can record another host.
|
||||
db.run(
|
||||
"INSERT INTO repositories (id, user_id, config_id, name, full_name, normalized_full_name, url, clone_url, owner, default_branch, source_provider, source_url) " +
|
||||
"VALUES ('repo-gitlab', 'u-src', 'cfg-pre15', 'tool', 'group/tool', 'group/tool', 'https://gitlab.com/group/tool', 'https://gitlab.com/group/tool.git', 'group', 'main', 'gitlab', 'https://gitlab.com')",
|
||||
);
|
||||
const inserted = db
|
||||
.query("SELECT source_provider, source_url FROM repositories WHERE id = 'repo-gitlab'")
|
||||
.get() as { source_provider: string; source_url: string } | null;
|
||||
assert(
|
||||
inserted?.source_provider === "gitlab" && inserted.source_url === "https://gitlab.com",
|
||||
`Expected GitLab source to round-trip, got ${JSON.stringify(inserted)}`,
|
||||
);
|
||||
}
|
||||
|
||||
const MIGRATION_0012_TIMESTAMP = 1774062000000;
|
||||
const MIGRATION_0013_TIMESTAMP = 1780377747526;
|
||||
|
||||
@@ -473,6 +527,10 @@ const latestUpgradeFixtures: Record<string, UpgradeFixture> = {
|
||||
seed: seedPre0014Database,
|
||||
verify: verify0014Migration,
|
||||
},
|
||||
"0015_source_provider": {
|
||||
seed: seedPre0015Database,
|
||||
verify: verify0015Migration,
|
||||
},
|
||||
};
|
||||
|
||||
function lintMigrations(selectedMigrations: Migration[]) {
|
||||
|
||||
Reference in new issue
Block a user