12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
Gitea Mirror is a self-hosted web application that automatically mirrors repositories from GitHub to Gitea instances. It's built with Astro (SSR mode), React, and runs on the Bun runtime with SQLite for data persistence.
Key capabilities:
- Mirrors public, private, and starred GitHub repos to Gitea
- Supports metadata mirroring (issues, PRs as issues, labels, milestones, releases, wiki)
- Git LFS support
- Multiple authentication methods (email/password, OIDC/SSO, header auth)
- Scheduled automatic syncing with configurable intervals
- Auto-discovery of new repos and cleanup of deleted repos
- Multi-user support with encrypted token storage (AES-256-GCM)
Development Commands
Setup and Installation
# Install dependencies
bun install
# Initialize database (first time setup)
bun run setup
# Clean start (reset database)
bun run dev:clean
Development
# Start development server (http://localhost:4321)
bun run dev
# Build for production
bun run build
# Preview production build
bun run preview
# Start production server
bun run start
Testing
# Run all tests
bun test
# Run tests in watch mode
bun test:watch
# Run tests with coverage
bun test:coverage
Test configuration:
- Test runner: Bun's built-in test runner (configured in
bunfig.toml) - Setup file:
src/tests/setup.bun.ts(auto-loaded via bunfig.toml) - Timeout: 5000ms default
- Tests are colocated with source files using
*.test.tspattern
Database Management
# Database operations via Drizzle
bun run db:generate # Generate migrations from schema
bun run db:migrate # Run migrations
bun run db:push # Push schema changes directly
bun run db:studio # Open Drizzle Studio (database GUI)
bun run db:check # Check schema consistency
# Database utilities via custom scripts
bun run manage-db init # Initialize database
bun run manage-db check # Check database health
bun run manage-db fix # Fix database issues
bun run manage-db reset-users # Reset all users
bun run cleanup-db # Delete database file
Utility Scripts
# Recovery and diagnostic scripts
bun run startup-recovery # Recover from crashes
bun run startup-recovery-force # Force recovery
bun run test-recovery # Test recovery mechanism
bun run test-shutdown # Test graceful shutdown
# Environment configuration
bun run startup-env-config # Load config from env vars
Architecture
Tech Stack
- Frontend: Astro v5 (SSR mode) + React v19 + Shadcn UI + Tailwind CSS v4
- Backend: Astro API routes (Node adapter, standalone mode)
- Runtime: Bun (>=1.2.9)
- Database: SQLite via Drizzle ORM
- Authentication: Better Auth (session-based)
- APIs: GitHub (Octokit with throttling plugin), Gitea REST API
Directory Structure
src/
├── components/ # React components (UI, features)
│ ├── ui/ # Shadcn UI components
│ ├── repositories/ # Repository management components
│ ├── organizations/ # Organization management components
│ └── ...
├── pages/ # Astro pages and API routes
│ ├── api/ # API endpoints (Better Auth integration)
│ │ ├── auth/ # Authentication endpoints
│ │ ├── github/ # GitHub operations
│ │ ├── gitea/ # Gitea operations
│ │ ├── sync/ # Mirror sync operations
│ │ ├── job/ # Job management
│ │ └── ...
│ └── *.astro # Page components
├── lib/ # Core business logic
│ ├── db/ # Database (Drizzle ORM)
│ │ ├── schema.ts # Database schema with Zod validation
│ │ ├── index.ts # Database instance and table exports
│ │ └── adapter.ts # Better Auth SQLite adapter
│ ├── github.ts # GitHub API client (Octokit)
│ ├── gitea.ts # Gitea API client
│ ├── gitea-enhanced.ts # Enhanced Gitea operations (metadata)
│ ├── scheduler-service.ts # Automatic mirroring scheduler
│ ├── cleanup-service.ts # Activity log cleanup
│ ├── repository-cleanup-service.ts # Orphaned repo cleanup
│ ├── auth.ts # Better Auth configuration
│ ├── config.ts # Configuration management
│ ├── helpers.ts # Mirror job creation
│ ├── utils/ # Utility functions
│ │ ├── encryption.ts # AES-256-GCM token encryption
│ │ ├── config-encryption.ts # Config token encryption
│ │ ├── duration-parser.ts # Parse intervals (e.g., "8h", "30m")
│ │ ├── concurrency.ts # Concurrency control utilities
│ │ └── mirror-strategies.ts # Mirror strategy logic
│ └── ...
├── types/ # TypeScript type definitions
├── tests/ # Test utilities and setup
└── middleware.ts # Astro middleware (auth, session)
scripts/ # Utility scripts
├── manage-db.ts # Database management CLI
├── startup-recovery.ts # Crash recovery
└── ...
Key Architectural Patterns
1. Database Schema and Validation
- Location:
src/lib/db/schema.ts - Pattern: Drizzle ORM tables + Zod schemas for validation
- Key tables:
configs- User configuration (GitHub/Gitea settings, mirror options)repositories- Tracked repositories with metadataorganizations- GitHub organizations with destination overridesmirrorJobs- Mirror job queue and historyactivities- Activity log for dashboarduser,session,account- Better Auth tables
Important: All config tokens (GitHub/Gitea) are encrypted at rest using AES-256-GCM. Use helper functions from src/lib/utils/config-encryption.ts to decrypt.
2. Mirror Job System
- Location:
src/lib/helpers.ts(createMirrorJob) - Flow:
- User triggers mirror via API endpoint
createMirrorJob()creates job record with status "pending"- Job processor (in API routes) performs GitHub → Gitea operations
- Job status updated throughout: "mirroring" → "success"/"failed"
- Events published via SSE for real-time UI updates
3. GitHub ↔ Gitea Mirroring
- GitHub Client:
src/lib/github.ts- Octokit with rate limit tracking - Gitea Client:
src/lib/gitea.ts- Basic repo operations - Enhanced Gitea:
src/lib/gitea-enhanced.ts- Metadata mirroring (issues, PRs, releases)
Mirror strategies (configured per user):
preserve- Maintain GitHub org structure in Giteasingle-org- All repos into one Gitea orgflat-user- All repos under user accountmixed- Personal repos in one org, org repos preserve structure
Metadata mirroring:
- Issues transferred with comments, labels, assignees
- PRs converted to issues (Gitea API limitation - cannot create PRs)
- Tagged with "pull-request" label
- Title prefixed with
[PR #number] [STATUS] - Body includes commit history, file changes, merge status
- Releases mirrored with assets
- Labels and milestones preserved
- Wiki content cloned if enabled
- Sequential processing: Issues/PRs mirrored one at a time to prevent out-of-order creation (see
src/lib/gitea-enhanced.ts)
4. Scheduler Service
- Location:
src/lib/scheduler-service.ts - Features:
- Cron-based or interval-based scheduling (uses
duration-parser.ts) - Auto-start on boot when
SCHEDULE_ENABLED=trueorGITEA_MIRROR_INTERVALis set - Auto-import new GitHub repos
- Auto-cleanup orphaned repos (archive or delete)
- Respects per-repo mirror intervals (not Gitea's default 24h)
- Cron-based or interval-based scheduling (uses
- Concurrency control: Uses
src/lib/utils/concurrency.tsfor batch processing
5. Authentication System
- Location:
src/lib/auth.ts,src/lib/auth-client.ts - Better Auth integration:
- Email/password (always enabled)
- OIDC/SSO providers (configurable via UI)
- Header authentication for reverse proxies (Authentik, Authelia)
- Session management: Cookie-based, validated in Astro middleware
- User helpers:
src/lib/utils/auth-helpers.ts
6. Environment Configuration
- Startup:
src/lib/env-config-loader.ts+scripts/startup-env-config.ts - Pattern: Environment variables can pre-configure settings, but users can override via web UI
- Encryption:
ENCRYPTION_SECRETfor tokens,BETTER_AUTH_SECRETfor sessions
7. Real-time Updates
- Events:
src/lib/events.ts+src/lib/events/realtime.ts - Pattern: Server-Sent Events (SSE) for live dashboard updates
- Endpoints:
/api/sse- client subscribes to job/repo events
Testing Patterns
Unit tests:
- Colocated with source:
filename.test.tsalongsidefilename.ts - Use Bun's built-in assertions and mocking
- Mock external APIs (GitHub, Gitea) using
src/tests/mock-fetch.ts
Integration tests:
- Located in
src/tests/ - Test database operations with in-memory SQLite
- Example:
src/lib/db/index.test.ts
Test utilities:
src/tests/setup.bun.ts- Global test setup (loaded via bunfig.toml)src/tests/mock-fetch.ts- Fetch mocking utilities
Important Development Notes
-
Path Aliases: Use
@/for imports (configured intsconfig.json)import { db } from '@/lib/db'; -
Token Encryption: Always use encryption helpers when dealing with tokens:
import { getDecryptedGitHubToken, getDecryptedGiteaToken } from '@/lib/utils/config-encryption'; -
API Route Pattern: Astro API routes in
src/pages/api/should:- Check authentication via Better Auth
- Validate input with Zod schemas
- Handle errors gracefully
- Return JSON responses
-
Database Migrations:
- Schema changes: Update
src/lib/db/schema.ts - Generate migration:
bun run db:generate - Review generated SQL in
drizzle/directory - Apply:
bun run db:migrate(ordb:pushfor dev)
- Schema changes: Update
-
Concurrency Control:
- Use utilities from
src/lib/utils/concurrency.tsfor batch operations - Respect rate limits (GitHub: 5000 req/hr authenticated, Gitea: varies)
- Issue/PR mirroring is sequential to maintain chronological order
- Use utilities from
-
Duration Parsing:
- Use
parseInterval()fromsrc/lib/utils/duration-parser.ts - Supports: "30m", "8h", "24h", "7d", cron expressions, or milliseconds
- Use
-
Graceful Shutdown:
- Services implement cleanup handlers (see
src/lib/shutdown-manager.ts) - Recovery system in
src/lib/recovery.tshandles interrupted jobs
- Services implement cleanup handlers (see
Common Development Workflows
Adding a new mirror option
- Update Zod schema in
src/lib/db/schema.ts(e.g.,giteaConfigSchema) - Update TypeScript types in
src/types/config.ts - Add UI control in settings page component
- Update API handler in
src/pages/api/config/ - Implement logic in
src/lib/gitea.tsorsrc/lib/gitea-enhanced.ts
Debugging mirror failures
- Check mirror jobs:
bun run db:studio→mirrorJobstable - Review activity logs: Dashboard → Activity tab
- Check console logs for API errors (GitHub/Gitea rate limits, auth issues)
- Use diagnostic scripts:
bun run test-recovery
Adding authentication provider
- Update Better Auth config in
src/lib/auth.ts - Add provider configuration UI in settings
- Test with
src/tests/test-gitea-auth.tspatterns - Update documentation in
docs/SSO-OIDC-SETUP.md
Docker Deployment
- Dockerfile: Multi-stage build (bun base → build → production)
- Entrypoint:
docker-entrypoint.sh- handles CA certs, user permissions, database init - Compose files:
docker-compose.alt.yml- Quick start (pre-built image, minimal config)docker-compose.yml- Full setup (build from source, all env vars)docker-compose.dev.yml- Development with hot reload
Additional Resources
- Environment Variables: See
docs/ENVIRONMENT_VARIABLES.mdfor complete list - Development Workflow: See
docs/DEVELOPMENT_WORKFLOW.md - SSO Setup: See
docs/SSO-OIDC-SETUP.md - Contributing: See
CONTRIBUTING.mdfor code guidelines and scope - Graceful Shutdown: See
docs/GRACEFUL_SHUTDOWN.mdfor crash recovery details