mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-09 21:16:48 +03:00
fix: Complete Issue #72 - Fix automatic mirroring and repository cleanup
Major fixes for Docker environment variable issues and cleanup functionality: 🔧 **Duration Parser & Scheduler Fixes** - Add comprehensive duration parser supporting "8h", "30m", "24h" formats - Fix GITEA_MIRROR_INTERVAL environment variable mapping to scheduler - Auto-enable scheduler when GITEA_MIRROR_INTERVAL is set - Improve scheduler logging to clarify timing behavior (from last run, not startup) 🧹 **Repository Cleanup Service** - Complete repository cleanup service for orphaned repos (unstarred, deleted) - Fix cleanup configuration logic - now works with CLEANUP_DELETE_IF_NOT_IN_GITHUB=true - Auto-enable cleanup when deleteIfNotInGitHub is enabled - Add manual cleanup trigger API endpoint (/api/cleanup/trigger) - Support archive/delete actions with dry-run mode and protected repos 🐛 **Environment Variable Integration** - Fix scheduler not recognizing GITEA_MIRROR_INTERVAL=8h - Fix cleanup requiring both CLEANUP_DELETE_FROM_GITEA and CLEANUP_DELETE_IF_NOT_IN_GITHUB - Auto-enable services when relevant environment variables are set - Better error logging and debugging information 📚 **Documentation Updates** - Update .env.example with auto-enabling behavior notes - Update ENVIRONMENT_VARIABLES.md with clarified functionality - Add comprehensive tests for duration parsing This resolves the core issues where: 1. GITEA_MIRROR_INTERVAL=8h was not working for automatic mirroring 2. Repository cleanup was not working despite CLEANUP_DELETE_IF_NOT_IN_GITHUB=true 3. Users had no visibility into why scheduling/cleanup wasn't working 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import { membershipRoleEnum } from "@/types/organizations";
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import type { Config } from "@/types/config";
|
||||
import type { Organization, Repository } from "./db/schema";
|
||||
import { httpPost, httpGet } from "./http-client";
|
||||
import { httpPost, httpGet, httpDelete, httpPut } from "./http-client";
|
||||
import { createMirrorJob } from "./helpers";
|
||||
import { db, organizations, repositories } from "./db";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
@@ -1739,4 +1739,69 @@ export async function mirrorGitRepoMilestonesToGitea({
|
||||
}
|
||||
|
||||
console.log(`✅ Mirrored ${mirroredCount} new milestones to Gitea`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a simple Gitea client object with base URL and token
|
||||
*/
|
||||
export function createGiteaClient(url: string, token: string) {
|
||||
return { url, token };
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a repository from Gitea
|
||||
*/
|
||||
export async function deleteGiteaRepo(
|
||||
client: { url: string; token: string },
|
||||
owner: string,
|
||||
repo: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
const response = await httpDelete(
|
||||
`${client.url}/api/v1/repos/${owner}/${repo}`,
|
||||
{
|
||||
Authorization: `token ${client.token}`,
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.success) {
|
||||
throw new Error(`Failed to delete repository ${owner}/${repo}: ${response.statusCode}`);
|
||||
}
|
||||
|
||||
console.log(`Successfully deleted repository ${owner}/${repo} from Gitea`);
|
||||
} catch (error) {
|
||||
console.error(`Error deleting repository ${owner}/${repo}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Archive a repository in Gitea
|
||||
*/
|
||||
export async function archiveGiteaRepo(
|
||||
client: { url: string; token: string },
|
||||
owner: string,
|
||||
repo: string
|
||||
): Promise<void> {
|
||||
try {
|
||||
const response = await httpPut(
|
||||
`${client.url}/api/v1/repos/${owner}/${repo}`,
|
||||
{
|
||||
archived: true,
|
||||
},
|
||||
{
|
||||
Authorization: `token ${client.token}`,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.success) {
|
||||
throw new Error(`Failed to archive repository ${owner}/${repo}: ${response.statusCode}`);
|
||||
}
|
||||
|
||||
console.log(`Successfully archived repository ${owner}/${repo} in Gitea`);
|
||||
} catch (error) {
|
||||
console.error(`Error archiving repository ${owner}/${repo}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user