Files
gitea-mirror/src/lib/utils/mirror-strategies.ts
2025-08-28 08:34:41 +05:30

93 lines
3.0 KiB
TypeScript

/**
* Mirror strategy configuration for handling various repository scenarios
*/
export type NonMirrorStrategy = "skip" | "delete" | "rename";
export interface MirrorStrategyConfig {
/**
* How to handle repositories that exist in Gitea but are not mirrors
* - "skip": Leave the repository as-is and mark as failed
* - "delete": Delete the repository and recreate as mirror
* - "rename": Rename the existing repository (not implemented yet)
* Note: "convert" strategy was removed as it's not supported by most Gitea versions
*/
nonMirrorStrategy: NonMirrorStrategy;
/**
* Maximum retries for organization creation
*/
orgCreationRetries: number;
/**
* Base delay in milliseconds for exponential backoff
*/
orgCreationRetryDelay: number;
/**
* Whether to create organizations sequentially to avoid race conditions
*/
sequentialOrgCreation: boolean;
/**
* Batch size for parallel repository processing
*/
repoBatchSize: number;
/**
* Timeout for sync operations in milliseconds
*/
syncTimeout: number;
}
export const DEFAULT_MIRROR_STRATEGY: MirrorStrategyConfig = {
nonMirrorStrategy: "delete", // Safe default: delete and recreate
orgCreationRetries: 3,
orgCreationRetryDelay: 100,
sequentialOrgCreation: true,
repoBatchSize: 3,
syncTimeout: 30000, // 30 seconds
};
/**
* Get mirror strategy configuration from environment or defaults
*/
export function getMirrorStrategyConfig(): MirrorStrategyConfig {
return {
nonMirrorStrategy: (process.env.NON_MIRROR_STRATEGY as NonMirrorStrategy) || DEFAULT_MIRROR_STRATEGY.nonMirrorStrategy,
orgCreationRetries: parseInt(process.env.ORG_CREATION_RETRIES || "") || DEFAULT_MIRROR_STRATEGY.orgCreationRetries,
orgCreationRetryDelay: parseInt(process.env.ORG_CREATION_RETRY_DELAY || "") || DEFAULT_MIRROR_STRATEGY.orgCreationRetryDelay,
sequentialOrgCreation: process.env.SEQUENTIAL_ORG_CREATION !== "false",
repoBatchSize: parseInt(process.env.REPO_BATCH_SIZE || "") || DEFAULT_MIRROR_STRATEGY.repoBatchSize,
syncTimeout: parseInt(process.env.SYNC_TIMEOUT || "") || DEFAULT_MIRROR_STRATEGY.syncTimeout,
};
}
/**
* Validate strategy configuration
*/
export function validateStrategyConfig(config: MirrorStrategyConfig): string[] {
const errors: string[] = [];
if (!["skip", "delete", "rename"].includes(config.nonMirrorStrategy)) {
errors.push(`Invalid nonMirrorStrategy: ${config.nonMirrorStrategy}`);
}
if (config.orgCreationRetries < 1 || config.orgCreationRetries > 10) {
errors.push("orgCreationRetries must be between 1 and 10");
}
if (config.orgCreationRetryDelay < 10 || config.orgCreationRetryDelay > 5000) {
errors.push("orgCreationRetryDelay must be between 10ms and 5000ms");
}
if (config.repoBatchSize < 1 || config.repoBatchSize > 50) {
errors.push("repoBatchSize must be between 1 and 50");
}
if (config.syncTimeout < 5000 || config.syncTimeout > 300000) {
errors.push("syncTimeout must be between 5s and 5min");
}
return errors;
}