mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-10-03 22:11:54 +02:00
A user can connect several sources (GitHub, GitHub Enterprise, GitLab, Gitea/Forgejo) and every repository remembers which source it came from. New sources table (migration 0019) with repositories.source_id backfilled by provider and host, per-user unique indexes widened to include the source, a Sources card on the Configuration page with per-source lock confirmations, and credentials resolved from each repository's own source in discovery, import, scheduling, organization mirror, retry, recovery, push targets, cleanup and reconcile. The legacy githubConfig connection fields mirror the primary source so scripts and env setups keep working.
83 lines
3.7 KiB
SQL
83 lines
3.7 KiB
SQL
CREATE TABLE `sources` (
|
|
`id` text PRIMARY KEY NOT NULL,
|
|
`user_id` text NOT NULL,
|
|
`name` text NOT NULL,
|
|
`provider` text NOT NULL,
|
|
`url` text NOT NULL,
|
|
`username` text DEFAULT '' NOT NULL,
|
|
`token` text,
|
|
`enabled` integer DEFAULT true NOT NULL,
|
|
`created_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
`updated_at` integer DEFAULT (unixepoch()) NOT NULL,
|
|
FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
|
|
);
|
|
--> statement-breakpoint
|
|
CREATE INDEX `idx_sources_user_id` ON `sources` (`user_id`);--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_sources_user_provider_url_username` ON `sources` (`user_id`,`provider`,`url`,`username`);--> statement-breakpoint
|
|
-- Seed one source row per ACTIVE config that carries connection fields. The
|
|
-- token is copied as-is: it is already encrypted at rest in the config.
|
|
-- INSERT OR IGNORE guards the unique index for accounts that somehow kept
|
|
-- multiple config rows with identical connection values (configs has no
|
|
-- per-user unique constraint). Active configs only: the app reads the
|
|
-- active config, so seeding from a stale inactive row would elect a primary
|
|
-- source the user no longer uses.
|
|
INSERT OR IGNORE INTO `sources` (`id`, `user_id`, `name`, `provider`, `url`, `username`, `token`, `enabled`, `created_at`, `updated_at`)
|
|
WITH `connection` AS (
|
|
SELECT
|
|
`configs`.`user_id` AS `user_id`,
|
|
CASE json_extract(`configs`.`github_config`, '$.provider')
|
|
WHEN 'gitlab' THEN 'gitlab'
|
|
WHEN 'gitea' THEN 'gitea'
|
|
WHEN 'forgejo' THEN 'gitea'
|
|
WHEN 'codeberg' THEN 'gitea'
|
|
WHEN 'github' THEN 'github'
|
|
ELSE 'github'
|
|
END AS `provider`,
|
|
rtrim(COALESCE(json_extract(`configs`.`github_config`, '$.url'), ''), '/') AS `url`,
|
|
COALESCE(json_extract(`configs`.`github_config`, '$.owner'), '') AS `username`,
|
|
COALESCE(json_extract(`configs`.`github_config`, '$.token'), '') AS `token`
|
|
FROM `configs`
|
|
WHERE `configs`.`is_active` = 1
|
|
AND (
|
|
COALESCE(json_extract(`configs`.`github_config`, '$.token'), '') <> ''
|
|
OR COALESCE(json_extract(`configs`.`github_config`, '$.owner'), '') <> ''
|
|
)
|
|
)
|
|
SELECT
|
|
lower(hex(randomblob(4))) || '-' || lower(hex(randomblob(2))) || '-' || lower(hex(randomblob(2))) || '-' || lower(hex(randomblob(2))) || '-' || lower(hex(randomblob(6))),
|
|
`user_id`,
|
|
CASE `provider`
|
|
WHEN 'github' THEN 'GitHub'
|
|
WHEN 'gitlab' THEN 'GitLab'
|
|
ELSE 'Gitea / Forgejo'
|
|
END || (CASE WHEN `username` = '' THEN '' ELSE ' (' || `username` || ')' END),
|
|
`provider`,
|
|
CASE
|
|
WHEN `url` <> '' THEN `url`
|
|
WHEN `provider` = 'github' THEN 'https://github.com'
|
|
WHEN `provider` = 'gitlab' THEN 'https://gitlab.com'
|
|
ELSE 'https://codeberg.org'
|
|
END,
|
|
`username`,
|
|
NULLIF(`token`, ''),
|
|
1,
|
|
unixepoch(),
|
|
unixepoch()
|
|
FROM `connection`;--> statement-breakpoint
|
|
ALTER TABLE `repositories` ADD `source_id` text;--> statement-breakpoint
|
|
-- Link each repository to its user's source row with the same provider and
|
|
-- host. MIN() keeps the subquery scalar; rows without a match keep NULL
|
|
-- ("switched source" legacy rows that deliberately match no source).
|
|
UPDATE `repositories` SET `source_id` = (
|
|
SELECT MIN(`sources`.`id`)
|
|
FROM `sources`
|
|
WHERE `sources`.`user_id` = `repositories`.`user_id`
|
|
AND `sources`.`provider` = `repositories`.`source_provider`
|
|
AND rtrim(`sources`.`url`, '/') = rtrim(`repositories`.`source_url`, '/')
|
|
)
|
|
WHERE `source_id` IS NULL;--> statement-breakpoint
|
|
DROP INDEX `uniq_repositories_user_full_name`;--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_repositories_user_full_name` ON `repositories` (`user_id`,`source_id`,`full_name`);--> statement-breakpoint
|
|
DROP INDEX `uniq_repositories_user_normalized_full_name`;--> statement-breakpoint
|
|
CREATE UNIQUE INDEX `uniq_repositories_user_normalized_full_name` ON `repositories` (`user_id`,`source_id`,`normalized_full_name`);
|