From 68108b8383df02409dfef122ad29be0578d6276d Mon Sep 17 00:00:00 2001
From: Arunavo Ray
Date: Tue, 24 Jun 2025 11:02:57 +0530
Subject: [PATCH] feat: add personal repositories organization override and
update related configurations
---
README.md | 17 +++-
src/components/config/GiteaConfigForm.tsx | 6 ++
.../config/OrganizationConfiguration.tsx | 34 ++++++-
.../organizations/OrganizationsList.tsx | 12 ++-
src/lib/db/index.ts | 27 ++++++
src/lib/db/schema.ts | 4 +
src/lib/gitea.test.ts | 90 +++++++++++++++++-
src/lib/gitea.ts | 91 +++++++++++++++++--
src/lib/utils/config-mapper.ts | 2 +
src/pages/api/job/mirror-repo.ts | 6 +-
src/pages/api/job/retry-repo.ts | 6 +-
src/types/config.ts | 1 +
12 files changed, 274 insertions(+), 22 deletions(-)
diff --git a/README.md b/README.md
index d15873e..789f1dd 100644
--- a/README.md
+++ b/README.md
@@ -322,9 +322,13 @@ Key configuration options include:
Gitea Mirror offers three flexible strategies for organizing your repositories in Gitea:
#### 1. **Preserve GitHub Structure** (Default)
-- Personal repositories → Your Gitea username
-- Organization repositories → Same organization name in Gitea
-- Maintains the exact structure from GitHub
+- Personal repositories → Your Gitea username (or custom organization)
+- Organization repositories → Same organization name in Gitea (with individual overrides)
+- Maintains the exact structure from GitHub with optional customization
+
+**New Override Options:**
+- **Personal Repos Override**: Redirect your personal repositories to a custom organization instead of your username
+- **Organization Overrides**: Set custom destinations for specific GitHub organizations on their individual cards
#### 2. **Single Organization**
- All repositories → One designated organization
@@ -339,6 +343,13 @@ Gitea Mirror offers three flexible strategies for organizing your repositories i
> [!NOTE]
> **Starred Repositories**: Regardless of the chosen strategy, starred repositories are always mirrored to a separate organization (default: "starred") to keep them organized separately from your own repositories.
+> [!TIP]
+> **Example Use Case**: With the "Preserve" strategy and overrides, you can:
+> - Mirror personal repos to `username-mirror` organization
+> - Keep `company-org` repos in their own `company-org` organization
+> - Override `community-scripts` to go to `community-mirrors` organization
+> - This gives you complete control while maintaining GitHub's structure as the default
+
## 🚀 Development
### Local Development Setup
diff --git a/src/components/config/GiteaConfigForm.tsx b/src/components/config/GiteaConfigForm.tsx
index 1acc394..6f6f5f9 100644
--- a/src/components/config/GiteaConfigForm.tsx
+++ b/src/components/config/GiteaConfigForm.tsx
@@ -217,6 +217,7 @@ export function GiteaConfigForm({ config, setConfig, onAutoSave, isAutoSaving, g
strategy={mirrorStrategy}
destinationOrg={config.organization}
starredReposOrg={config.starredReposOrg}
+ personalReposOrg={config.personalReposOrg}
visibility={config.visibility}
onDestinationOrgChange={(org) => {
const newConfig = { ...config, organization: org };
@@ -228,6 +229,11 @@ export function GiteaConfigForm({ config, setConfig, onAutoSave, isAutoSaving, g
setConfig(newConfig);
if (onAutoSave) onAutoSave(newConfig);
}}
+ onPersonalReposOrgChange={(org) => {
+ const newConfig = { ...config, personalReposOrg: org };
+ setConfig(newConfig);
+ if (onAutoSave) onAutoSave(newConfig);
+ }}
onVisibilityChange={(visibility) => {
const newConfig = { ...config, visibility };
setConfig(newConfig);
diff --git a/src/components/config/OrganizationConfiguration.tsx b/src/components/config/OrganizationConfiguration.tsx
index 48711ee..b04545b 100644
--- a/src/components/config/OrganizationConfiguration.tsx
+++ b/src/components/config/OrganizationConfiguration.tsx
@@ -15,9 +15,11 @@ interface OrganizationConfigurationProps {
strategy: MirrorStrategy;
destinationOrg?: string;
starredReposOrg?: string;
+ personalReposOrg?: string;
visibility: GiteaOrgVisibility;
onDestinationOrgChange: (org: string) => void;
onStarredReposOrgChange: (org: string) => void;
+ onPersonalReposOrgChange: (org: string) => void;
onVisibilityChange: (visibility: GiteaOrgVisibility) => void;
}
@@ -31,9 +33,11 @@ export const OrganizationConfiguration: React.FC
strategy,
destinationOrg,
starredReposOrg,
+ personalReposOrg,
visibility,
onDestinationOrgChange,
onStarredReposOrgChange,
+ onPersonalReposOrgChange,
onVisibilityChange,
}) => {
return (
@@ -75,7 +79,7 @@ export const OrganizationConfiguration: React.FC
- {/* Right column - shows destination org for single-org, empty div for others */}
+ {/* Right column - shows destination org for single-org, personal repos org for preserve, empty div for others */}
{strategy === "single-org" ? (