Add optional external Gitea URL for UI links

This commit is contained in:
Arunavo Ray
2026-02-24 10:33:30 +05:30
parent b1ca8c46bf
commit ef13fefb69
11 changed files with 45 additions and 8 deletions

View File

@@ -67,6 +67,7 @@ DOCKER_TAG=latest
# Basic Gitea Settings
# GITEA_URL=http://gitea:3000
# GITEA_EXTERNAL_URL=https://gitea.example.com # Optional: used only for UI links
# GITEA_TOKEN=your-local-gitea-token
# GITEA_USERNAME=your-local-gitea-username
# GITEA_ORGANIZATION=github-mirrors # Default organization for single-org strategy

View File

@@ -88,6 +88,7 @@ Settings for the destination Gitea instance.
| Variable | Description | Default | Options |
|----------|-------------|---------|---------|
| `GITEA_URL` | Gitea instance URL | - | Valid URL |
| `GITEA_EXTERNAL_URL` | Optional external/browser URL used for dashboard links. API and mirroring still use `GITEA_URL`. | - | Valid URL |
| `GITEA_TOKEN` | Gitea access token | - | - |
| `GITEA_USERNAME` | Gitea username | - | - |
| `GITEA_ORGANIZATION` | Default organization for single-org strategy | `github-mirrors` | Any string |

View File

@@ -42,6 +42,7 @@ export function ConfigTabs() {
},
giteaConfig: {
url: '',
externalUrl: '',
username: '',
token: '',
organization: 'github-mirrors',

View File

@@ -195,6 +195,27 @@ export function GiteaConfigForm({ config, setConfig, onAutoSave, isAutoSaving, g
/>
</div>
<div>
<label
htmlFor="gitea-external-url"
className="block text-sm font-medium mb-1.5"
>
Gitea External URL (optional)
</label>
<input
id="gitea-external-url"
name="externalUrl"
type="url"
value={config.externalUrl || ""}
onChange={handleChange}
className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
placeholder="https://gitea.example.com"
/>
<p className="text-xs text-muted-foreground mt-1">
Used only for dashboard links. API sync still uses Gitea URL.
</p>
</div>
<div>
<label
htmlFor="gitea-token"

View File

@@ -15,7 +15,8 @@ export function RepositoryList({ repositories }: RepositoryListProps) {
// Helper function to construct Gitea repository URL
const getGiteaRepoUrl = (repository: Repository): string | null => {
if (!giteaConfig?.url) {
const rawBaseUrl = giteaConfig?.externalUrl || giteaConfig?.url;
if (!rawBaseUrl) {
return null;
}
@@ -38,9 +39,9 @@ export function RepositoryList({ repositories }: RepositoryListProps) {
}
// Ensure the base URL doesn't have a trailing slash
const baseUrl = giteaConfig.url.endsWith('/')
? giteaConfig.url.slice(0, -1)
: giteaConfig.url;
const baseUrl = rawBaseUrl.endsWith("/")
? rawBaseUrl.slice(0, -1)
: rawBaseUrl;
return `${baseUrl}/${repoPath}`;
};

View File

@@ -67,7 +67,8 @@ export function OrganizationList({
// Helper function to construct Gitea organization URL
const getGiteaOrgUrl = (organization: Organization): string | null => {
if (!giteaConfig?.url) {
const rawBaseUrl = giteaConfig?.externalUrl || giteaConfig?.url;
if (!rawBaseUrl) {
return null;
}
@@ -84,9 +85,9 @@ export function OrganizationList({
}
// Ensure the base URL doesn't have a trailing slash
const baseUrl = giteaConfig.url.endsWith('/')
? giteaConfig.url.slice(0, -1)
: giteaConfig.url;
const baseUrl = rawBaseUrl.endsWith("/")
? rawBaseUrl.slice(0, -1)
: rawBaseUrl;
return `${baseUrl}/${orgName}`;
};

View File

@@ -35,6 +35,7 @@ export const githubConfigSchema = z.object({
export const giteaConfigSchema = z.object({
url: z.url(),
externalUrl: z.url().optional(),
token: z.string(),
defaultOwner: z.string(),
organization: z.string().optional(),

View File

@@ -28,6 +28,7 @@ interface EnvConfig {
};
gitea: {
url?: string;
externalUrl?: string;
username?: string;
token?: string;
organization?: string;
@@ -118,6 +119,7 @@ function parseEnvConfig(): EnvConfig {
},
gitea: {
url: process.env.GITEA_URL,
externalUrl: process.env.GITEA_EXTERNAL_URL,
username: process.env.GITEA_USERNAME,
token: process.env.GITEA_TOKEN,
organization: process.env.GITEA_ORGANIZATION,
@@ -267,6 +269,7 @@ export async function initializeConfigFromEnv(): Promise<void> {
// Build Gitea config
const giteaConfig = {
url: envConfig.gitea.url || existingConfig?.[0]?.giteaConfig?.url || '',
externalUrl: envConfig.gitea.externalUrl || existingConfig?.[0]?.giteaConfig?.externalUrl || undefined,
token: envConfig.gitea.token ? encrypt(envConfig.gitea.token) : existingConfig?.[0]?.giteaConfig?.token || '',
defaultOwner: envConfig.gitea.username || existingConfig?.[0]?.giteaConfig?.defaultOwner || '',
organization: envConfig.gitea.organization || existingConfig?.[0]?.giteaConfig?.organization || undefined,

View File

@@ -9,6 +9,7 @@ export interface DefaultConfigOptions {
githubToken?: string;
githubUsername?: string;
giteaUrl?: string;
giteaExternalUrl?: string;
giteaToken?: string;
giteaUsername?: string;
scheduleEnabled?: boolean;
@@ -38,6 +39,8 @@ export async function createDefaultConfig({ userId, envOverrides = {} }: Default
const githubToken = envOverrides.githubToken || process.env.GITHUB_TOKEN || "";
const githubUsername = envOverrides.githubUsername || process.env.GITHUB_USERNAME || "";
const giteaUrl = envOverrides.giteaUrl || process.env.GITEA_URL || "";
const giteaExternalUrl =
envOverrides.giteaExternalUrl || process.env.GITEA_EXTERNAL_URL || "";
const giteaToken = envOverrides.giteaToken || process.env.GITEA_TOKEN || "";
const giteaUsername = envOverrides.giteaUsername || process.env.GITEA_USERNAME || "";
@@ -77,6 +80,7 @@ export async function createDefaultConfig({ userId, envOverrides = {} }: Default
},
giteaConfig: {
url: giteaUrl,
externalUrl: giteaExternalUrl || undefined,
token: giteaToken ? encrypt(giteaToken) : "",
defaultOwner: giteaUsername,
mirrorInterval: "8h",

View File

@@ -61,6 +61,7 @@ export function mapUiToDbConfig(
// Map Gitea config to match database schema
const dbGiteaConfig: DbGiteaConfig = {
url: giteaConfig.url,
externalUrl: giteaConfig.externalUrl?.trim() || undefined,
token: giteaConfig.token,
defaultOwner: giteaConfig.username, // Map username to defaultOwner
organization: giteaConfig.organization, // Add organization field
@@ -127,6 +128,7 @@ export function mapDbToUiConfig(dbConfig: any): {
// Map from database Gitea config to UI fields
const giteaConfig: GiteaConfig = {
url: dbConfig.giteaConfig?.url || "",
externalUrl: dbConfig.giteaConfig?.externalUrl || "",
username: dbConfig.giteaConfig?.defaultOwner || "", // Map defaultOwner to username
token: dbConfig.giteaConfig?.token || "",
organization: dbConfig.githubConfig?.defaultOrg || "github-mirrors", // Get from GitHub config

View File

@@ -6,6 +6,7 @@ export type StarredReposMode = "dedicated-org" | "preserve-owner";
export interface GiteaConfig {
url: string;
externalUrl?: string;
username: string;
token: string;
organization: string;