mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-06 11:36:44 +03:00
chore: switch to bun package manager
This commit is contained in:
@@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
# Node.js
|
# Node.js
|
||||||
node_modules
|
node_modules
|
||||||
|
bun.lockb
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-debug.log
|
yarn-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
pnpm-debug.log
|
|
||||||
|
|
||||||
# Build outputs
|
# Build outputs
|
||||||
dist
|
dist
|
||||||
@@ -62,4 +62,3 @@ logs
|
|||||||
# Cache
|
# Cache
|
||||||
.cache
|
.cache
|
||||||
.npm
|
.npm
|
||||||
.pnpm-store
|
|
||||||
|
|||||||
3
.github/workflows/README.md
vendored
3
.github/workflows/README.md
vendored
@@ -24,8 +24,7 @@ This workflow runs on all branches and pull requests. It:
|
|||||||
- On push to any branch (except changes to README.md and docs)
|
- On push to any branch (except changes to README.md and docs)
|
||||||
- On pull requests to any branch (except changes to README.md and docs)
|
- On pull requests to any branch (except changes to README.md and docs)
|
||||||
|
|
||||||
**Key features:**
|
- Uses Bun for dependency installation
|
||||||
- Uses pnpm for faster dependency installation
|
|
||||||
- Caches dependencies to speed up builds
|
- Caches dependencies to speed up builds
|
||||||
- Uploads build artifacts for 7 days
|
- Uploads build artifacts for 7 days
|
||||||
|
|
||||||
|
|||||||
20
.github/workflows/astro-build-test.yml
vendored
20
.github/workflows/astro-build-test.yml
vendored
@@ -21,26 +21,20 @@ jobs:
|
|||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install pnpm
|
- name: Setup Bun
|
||||||
uses: pnpm/action-setup@v3
|
uses: oven-sh/setup-bun@v1
|
||||||
with:
|
with:
|
||||||
version: 10
|
bun-version: '1.2.9'
|
||||||
run_install: false
|
cache: true
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 'lts/*'
|
|
||||||
cache: 'pnpm'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install
|
run: bun install
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: pnpm test
|
run: bunx vitest run
|
||||||
|
|
||||||
- name: Build Astro project
|
- name: Build Astro project
|
||||||
run: pnpm build
|
run: bunx astro build
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
4
.github/workflows/docker-scan.yml
vendored
4
.github/workflows/docker-scan.yml
vendored
@@ -7,14 +7,14 @@ on:
|
|||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
- '.dockerignore'
|
- '.dockerignore'
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
- 'pnpm-lock.yaml'
|
- 'bun.lockb'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
paths:
|
paths:
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
- '.dockerignore'
|
- '.dockerignore'
|
||||||
- 'package.json'
|
- 'package.json'
|
||||||
- 'pnpm-lock.yaml'
|
- 'bun.lockb'
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * 0' # Run weekly on Sunday at midnight
|
- cron: '0 0 * * 0' # Run weekly on Sunday at midnight
|
||||||
|
|
||||||
|
|||||||
64
README.md
64
README.md
@@ -18,7 +18,7 @@
|
|||||||
```bash
|
```bash
|
||||||
docker compose --profile production up -d
|
docker compose --profile production up -d
|
||||||
# or
|
# or
|
||||||
pnpm setup && pnpm dev
|
bun run setup && bun run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -63,9 +63,9 @@ Easily configure your GitHub and Gitea connections, set up automatic mirroring s
|
|||||||
|
|
||||||
See the [Quick Start Guide](docs/quickstart.md) for detailed instructions on getting up and running quickly.
|
See the [Quick Start Guide](docs/quickstart.md) for detailed instructions on getting up and running quickly.
|
||||||
|
|
||||||
### Prerequisites
|
-### Prerequisites
|
||||||
|
|
||||||
- Node.js 22 or later
|
- Bun 1.2.9 or later
|
||||||
- A GitHub account with a personal access token
|
- A GitHub account with a personal access token
|
||||||
- A Gitea instance with an access token
|
- A Gitea instance with an access token
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ Before running the application in production mode for the first time, you need t
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Initialize the database for production mode
|
# Initialize the database for production mode
|
||||||
pnpm setup
|
bun run setup
|
||||||
```
|
```
|
||||||
|
|
||||||
This will create the necessary tables. On first launch, you'll be guided through creating your admin account with a secure password.
|
This will create the necessary tables. On first launch, you'll be guided through creating your admin account with a secure password.
|
||||||
@@ -110,7 +110,7 @@ Gitea Mirror provides multi-architecture Docker images that work on both ARM64 (
|
|||||||
docker compose --profile production up -d
|
docker compose --profile production up -d
|
||||||
|
|
||||||
# For development mode (requires configuration)
|
# For development mode (requires configuration)
|
||||||
# Ensure you have run pnpm setup first
|
# Ensure you have run bun run setup first
|
||||||
docker compose -f docker-compose.dev.yml up -d
|
docker compose -f docker-compose.dev.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -206,40 +206,40 @@ git clone https://github.com/arunavo4/gitea-mirror.git
|
|||||||
cd gitea-mirror
|
cd gitea-mirror
|
||||||
|
|
||||||
# Quick setup (installs dependencies and initializes the database)
|
# Quick setup (installs dependencies and initializes the database)
|
||||||
pnpm setup
|
bun run setup
|
||||||
|
|
||||||
# Development Mode Options
|
# Development Mode Options
|
||||||
|
|
||||||
# Run in development mode
|
# Run in development mode
|
||||||
pnpm dev
|
bun run dev
|
||||||
|
|
||||||
# Run in development mode with clean database (removes existing DB first)
|
# Run in development mode with clean database (removes existing DB first)
|
||||||
pnpm dev:clean
|
bun run dev:clean
|
||||||
|
|
||||||
# Production Mode Options
|
# Production Mode Options
|
||||||
|
|
||||||
# Build the application
|
# Build the application
|
||||||
pnpm build
|
bun run build
|
||||||
|
|
||||||
# Preview the production build
|
# Preview the production build
|
||||||
pnpm preview
|
bun run preview
|
||||||
|
|
||||||
# Start the production server (default)
|
# Start the production server (default)
|
||||||
pnpm start
|
bun run start
|
||||||
|
|
||||||
# Start the production server with a clean setup
|
# Start the production server with a clean setup
|
||||||
pnpm start:fresh
|
bun run start:fresh
|
||||||
|
|
||||||
# Database Management
|
# Database Management
|
||||||
|
|
||||||
# Initialize the database
|
# Initialize the database
|
||||||
pnpm init-db
|
bun run init-db
|
||||||
|
|
||||||
# Reset users for testing first-time signup
|
# Reset users for testing first-time signup
|
||||||
pnpm reset-users
|
bun run reset-users
|
||||||
|
|
||||||
# Check database status
|
# Check database status
|
||||||
pnpm check-db
|
bun run check-db
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
@@ -262,10 +262,10 @@ Key configuration options include:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
pnpm setup
|
bun run setup
|
||||||
|
|
||||||
# Start the development server
|
# Start the development server
|
||||||
pnpm dev
|
bun run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -359,7 +359,7 @@ docker compose -f docker-compose.dev.yml up -d
|
|||||||
## Technologies Used
|
## Technologies Used
|
||||||
|
|
||||||
- **Frontend**: Astro, React, Shadcn UI, Tailwind CSS v4
|
- **Frontend**: Astro, React, Shadcn UI, Tailwind CSS v4
|
||||||
- **Backend**: Node.js
|
- **Backend**: Bun
|
||||||
- **Database**: SQLite (default) or PostgreSQL
|
- **Database**: SQLite (default) or PostgreSQL
|
||||||
- **Caching/Queue**: Redis
|
- **Caching/Queue**: Redis
|
||||||
- **API Integration**: GitHub API (Octokit), Gitea API
|
- **API Integration**: GitHub API (Octokit), Gitea API
|
||||||
@@ -467,33 +467,19 @@ Try the following steps:
|
|||||||
> For better Redis connection handling, you can modify the `src/lib/redis.ts` file to include retry logic and better error handling:
|
> For better Redis connection handling, you can modify the `src/lib/redis.ts` file to include retry logic and better error handling:
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import Redis from "ioredis";
|
import { RedisClient } from "bun";
|
||||||
|
|
||||||
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
|
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
|
||||||
const redisUrl = process.env.REDIS_URL ?? 'redis://redis:6379';
|
const redisUrl = process.env.REDIS_URL ?? "redis://redis:6379";
|
||||||
|
|
||||||
console.log(`Connecting to Redis at: ${redisUrl}`);
|
console.log(`Connecting to Redis at: ${redisUrl}`);
|
||||||
|
|
||||||
// Configure Redis client with connection options
|
const redis = new RedisClient(redisUrl, { autoReconnect: true });
|
||||||
const redisOptions = {
|
|
||||||
retryStrategy: (times) => {
|
redis.onconnect = () => console.log("Redis client connected");
|
||||||
// Retry with exponential backoff up to 30 seconds
|
redis.onclose = err => {
|
||||||
const delay = Math.min(times * 100, 3000);
|
if (err) console.error("Redis client error:", err);
|
||||||
console.log(`Redis connection attempt ${times} failed. Retrying in ${delay}ms...`);
|
|
||||||
return delay;
|
|
||||||
},
|
|
||||||
maxRetriesPerRequest: 5,
|
|
||||||
enableReadyCheck: true,
|
|
||||||
connectTimeout: 10000,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const redis = new Redis(redisUrl, redisOptions);
|
|
||||||
export const redisPublisher = new Redis(redisUrl, redisOptions);
|
|
||||||
export const redisSubscriber = new Redis(redisUrl, redisOptions);
|
|
||||||
|
|
||||||
// Log connection events
|
|
||||||
redis.on('connect', () => console.log('Redis client connected'));
|
|
||||||
redis.on('error', (err) => console.error('Redis client error:', err));
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,19 +5,19 @@ set -e
|
|||||||
# Ensure data directory exists
|
# Ensure data directory exists
|
||||||
mkdir -p /app/data
|
mkdir -p /app/data
|
||||||
|
|
||||||
# If pnpm is available, run setup (for dev images), else run node init directly
|
# If bun is available, run setup (for dev images)
|
||||||
if command -v pnpm >/dev/null 2>&1; then
|
if command -v bun >/dev/null 2>&1; then
|
||||||
echo "Running pnpm setup (if needed)..."
|
echo "Running bun setup (if needed)..."
|
||||||
pnpm setup || true
|
bun run setup || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Initialize the database if it doesn't exist
|
# Initialize the database if it doesn't exist
|
||||||
if [ ! -f "/app/data/gitea-mirror.db" ]; then
|
if [ ! -f "/app/data/gitea-mirror.db" ]; then
|
||||||
echo "Initializing database..."
|
echo "Initializing database..."
|
||||||
if [ -f "dist/scripts/init-db.js" ]; then
|
if [ -f "dist/scripts/init-db.js" ]; then
|
||||||
node dist/scripts/init-db.js
|
bun dist/scripts/init-db.js
|
||||||
elif [ -f "dist/scripts/manage-db.js" ]; then
|
elif [ -f "dist/scripts/manage-db.js" ]; then
|
||||||
node dist/scripts/manage-db.js init
|
bun dist/scripts/manage-db.js init
|
||||||
else
|
else
|
||||||
echo "Warning: Could not find database initialization scripts in dist/scripts."
|
echo "Warning: Could not find database initialization scripts in dist/scripts."
|
||||||
echo "Creating and initializing database manually..."
|
echo "Creating and initializing database manually..."
|
||||||
@@ -119,9 +119,9 @@ EOF
|
|||||||
else
|
else
|
||||||
echo "Database already exists, checking for issues..."
|
echo "Database already exists, checking for issues..."
|
||||||
if [ -f "dist/scripts/fix-db-issues.js" ]; then
|
if [ -f "dist/scripts/fix-db-issues.js" ]; then
|
||||||
node dist/scripts/fix-db-issues.js
|
bun dist/scripts/fix-db-issues.js
|
||||||
elif [ -f "dist/scripts/manage-db.js" ]; then
|
elif [ -f "dist/scripts/manage-db.js" ]; then
|
||||||
node dist/scripts/manage-db.js fix
|
bun dist/scripts/manage-db.js fix
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Since the application is not used by anyone yet, we've removed the schema updates and migrations
|
# Since the application is not used by anyone yet, we've removed the schema updates and migrations
|
||||||
@@ -130,4 +130,4 @@ fi
|
|||||||
|
|
||||||
# Start the application
|
# Start the application
|
||||||
echo "Starting Gitea Mirror..."
|
echo "Starting Gitea Mirror..."
|
||||||
exec node ./dist/server/entry.mjs
|
exec bun ./dist/server/entry.mjs
|
||||||
|
|||||||
38
package.json
38
package.json
@@ -3,31 +3,30 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22.0.0"
|
"bun": ">=1.2.9"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"setup": "pnpm install && pnpm manage-db init",
|
"setup": "bun install && bun run manage-db init",
|
||||||
"dev": "astro dev",
|
"dev": "bunx astro dev",
|
||||||
"dev:clean": "pnpm cleanup-db && pnpm manage-db init && astro dev",
|
"dev:clean": "bun run cleanup-db && bun run manage-db init && bunx astro dev",
|
||||||
"build": "astro build",
|
"build": "bunx astro build",
|
||||||
"cleanup-db": "rm -f gitea-mirror.db data/gitea-mirror.db",
|
"cleanup-db": "rm -f gitea-mirror.db data/gitea-mirror.db",
|
||||||
"manage-db": "tsx scripts/manage-db.ts",
|
"manage-db": "bun scripts/manage-db.ts",
|
||||||
"init-db": "tsx scripts/manage-db.ts init",
|
"init-db": "bun scripts/manage-db.ts init",
|
||||||
"check-db": "tsx scripts/manage-db.ts check",
|
"check-db": "bun scripts/manage-db.ts check",
|
||||||
"fix-db": "tsx scripts/manage-db.ts fix",
|
"fix-db": "bun scripts/manage-db.ts fix",
|
||||||
"reset-users": "tsx scripts/manage-db.ts reset-users",
|
"reset-users": "bun scripts/manage-db.ts reset-users",
|
||||||
"preview": "astro preview",
|
"preview": "bunx astro preview",
|
||||||
"start": "node dist/server/entry.mjs",
|
"start": "bun dist/server/entry.mjs",
|
||||||
"start:fresh": "pnpm cleanup-db && pnpm manage-db init && node dist/server/entry.mjs",
|
"start:fresh": "bun run cleanup-db && bun run manage-db init && bun dist/server/entry.mjs",
|
||||||
"test": "vitest run",
|
"test": "bunx vitest run",
|
||||||
"test:watch": "vitest",
|
"test:watch": "bunx vitest",
|
||||||
"astro": "astro"
|
"astro": "bunx astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/mdx": "^4.2.6",
|
"@astrojs/mdx": "^4.2.6",
|
||||||
"@astrojs/node": "^9.2.1",
|
"@astrojs/node": "^9.2.1",
|
||||||
"@astrojs/react": "^4.2.7",
|
"@astrojs/react": "^4.2.7",
|
||||||
"@libsql/client": "^0.15.4",
|
|
||||||
"@octokit/rest": "^21.1.1",
|
"@octokit/rest": "^21.1.1",
|
||||||
"@radix-ui/react-avatar": "^1.1.4",
|
"@radix-ui/react-avatar": "^1.1.4",
|
||||||
"@radix-ui/react-checkbox": "^1.1.5",
|
"@radix-ui/react-checkbox": "^1.1.5",
|
||||||
@@ -54,7 +53,6 @@
|
|||||||
"cmdk": "^1.1.1",
|
"cmdk": "^1.1.1",
|
||||||
"drizzle-orm": "^0.41.0",
|
"drizzle-orm": "^0.41.0",
|
||||||
"fuse.js": "^7.1.0",
|
"fuse.js": "^7.1.0",
|
||||||
"ioredis": "^5.6.1",
|
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"lucide-react": "^0.488.0",
|
"lucide-react": "^0.488.0",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
@@ -73,15 +71,13 @@
|
|||||||
"@testing-library/jest-dom": "^6.6.3",
|
"@testing-library/jest-dom": "^6.6.3",
|
||||||
"@testing-library/react": "^16.3.0",
|
"@testing-library/react": "^16.3.0",
|
||||||
"@types/bcryptjs": "^3.0.0",
|
"@types/bcryptjs": "^3.0.0",
|
||||||
"@types/better-sqlite3": "^7.6.13",
|
|
||||||
"@types/jsonwebtoken": "^9.0.9",
|
"@types/jsonwebtoken": "^9.0.9",
|
||||||
"@types/superagent": "^8.1.9",
|
"@types/superagent": "^8.1.9",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"@vitejs/plugin-react": "^4.4.0",
|
"@vitejs/plugin-react": "^4.4.0",
|
||||||
"better-sqlite3": "^9.6.0",
|
|
||||||
"jsdom": "^26.1.0",
|
"jsdom": "^26.1.0",
|
||||||
"tsx": "^4.19.3",
|
"tsx": "^4.19.3",
|
||||||
"vitest": "^3.1.1"
|
"vitest": "^3.1.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.10.0"
|
"packageManager": "bun@1.2.9"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ The script uses environment variables from the `.env` file in the project root:
|
|||||||
3. Using with docker-compose:
|
3. Using with docker-compose:
|
||||||
```bash
|
```bash
|
||||||
# Ensure dependencies are installed and database is initialized
|
# Ensure dependencies are installed and database is initialized
|
||||||
pnpm setup
|
bun run setup
|
||||||
|
|
||||||
# First build the image
|
# First build the image
|
||||||
./scripts/build-docker.sh --load
|
./scripts/build-docker.sh --load
|
||||||
|
|||||||
@@ -19,38 +19,38 @@ This is a consolidated database management tool that handles all database-relate
|
|||||||
You can execute the database management tool using your package manager with various commands:
|
You can execute the database management tool using your package manager with various commands:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Checks database status (default action if no command is specified, equivalent to 'pnpm check-db')
|
# Checks database status (default action if no command is specified, equivalent to 'bun run check-db')
|
||||||
pnpm manage-db
|
bun run manage-db
|
||||||
|
|
||||||
# Check database status
|
# Check database status
|
||||||
pnpm check-db
|
bun run check-db
|
||||||
|
|
||||||
# Initialize the database (only if it doesn't exist)
|
# Initialize the database (only if it doesn't exist)
|
||||||
pnpm init-db
|
bun run init-db
|
||||||
|
|
||||||
# Fix database location issues
|
# Fix database location issues
|
||||||
pnpm fix-db
|
bun run fix-db
|
||||||
|
|
||||||
# Automatic check, fix, and initialize if needed
|
# Automatic check, fix, and initialize if needed
|
||||||
pnpm db-auto
|
bun run db-auto
|
||||||
|
|
||||||
# Reset all users (for testing signup flow)
|
# Reset all users (for testing signup flow)
|
||||||
pnpm reset-users
|
bun run reset-users
|
||||||
|
|
||||||
# Update the database schema to the latest version
|
# Update the database schema to the latest version
|
||||||
pnpm update-schema
|
bun run update-schema
|
||||||
|
|
||||||
# Remove database files completely
|
# Remove database files completely
|
||||||
pnpm cleanup-db
|
bun run cleanup-db
|
||||||
|
|
||||||
# Complete setup (install dependencies and initialize database)
|
# Complete setup (install dependencies and initialize database)
|
||||||
pnpm setup
|
bun run setup
|
||||||
|
|
||||||
# Start development server with a fresh database
|
# Start development server with a fresh database
|
||||||
pnpm dev:clean
|
bun run dev:clean
|
||||||
|
|
||||||
# Start production server with a fresh database
|
# Start production server with a fresh database
|
||||||
pnpm start:fresh
|
bun run start:fresh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Database File Location
|
## Database File Location
|
||||||
|
|||||||
4
scripts/docker-diagnostics.sh
Executable file → Normal file
4
scripts/docker-diagnostics.sh
Executable file → Normal file
@@ -105,12 +105,12 @@ echo -e "${BLUE} Recommendations ${NC}"
|
|||||||
echo -e "${BLUE}=====================================================${NC}"
|
echo -e "${BLUE}=====================================================${NC}"
|
||||||
|
|
||||||
echo -e "\n${YELLOW}For local development:${NC}"
|
echo -e "\n${YELLOW}For local development:${NC}"
|
||||||
echo -e "1. ${GREEN}pnpm setup${NC} (initialize database and install dependencies)"
|
echo -e "1. ${GREEN}bun run setup${NC} (initialize database and install dependencies)"
|
||||||
echo -e "2. ${GREEN}./scripts/build-docker.sh --load${NC} (build and load into Docker)"
|
echo -e "2. ${GREEN}./scripts/build-docker.sh --load${NC} (build and load into Docker)"
|
||||||
echo -e "3. ${GREEN}docker-compose -f docker-compose.dev.yml up -d${NC} (start the development container)"
|
echo -e "3. ${GREEN}docker-compose -f docker-compose.dev.yml up -d${NC} (start the development container)"
|
||||||
|
|
||||||
echo -e "\n${YELLOW}For production deployment (using Docker Compose):${NC}"
|
echo -e "\n${YELLOW}For production deployment (using Docker Compose):${NC}"
|
||||||
echo -e "1. ${GREEN}pnpm setup${NC} (if not already done, to ensure database schema is ready)"
|
echo -e "1. ${GREEN}bun run setup${NC} (if not already done, to ensure database schema is ready)"
|
||||||
echo -e "2. ${GREEN}docker-compose --profile production up -d${NC} (start the production container)"
|
echo -e "2. ${GREEN}docker-compose --profile production up -d${NC} (start the production container)"
|
||||||
|
|
||||||
echo -e "\n${YELLOW}For CI/CD builds:${NC}"
|
echo -e "\n${YELLOW}For CI/CD builds:${NC}"
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ async function checkDatabase() {
|
|||||||
);
|
);
|
||||||
console.warn("This file should be in the data directory.");
|
console.warn("This file should be in the data directory.");
|
||||||
console.warn(
|
console.warn(
|
||||||
'Run "pnpm manage-db fix" to fix this issue or "pnpm cleanup-db" to remove it.'
|
'Run "bun run manage-db fix" to fix this issue or "bun run cleanup-db" to remove it.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,12 +215,12 @@ async function checkDatabase() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error connecting to the database:", error);
|
console.error("❌ Error connecting to the database:", error);
|
||||||
console.warn(
|
console.warn(
|
||||||
'The database file might be corrupted. Consider running "pnpm manage-db init" to recreate it.'
|
'The database file might be corrupted. Consider running "bun run manage-db init" to recreate it.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn("⚠️ WARNING: Database file not found in data directory.");
|
console.warn("⚠️ WARNING: Database file not found in data directory.");
|
||||||
console.warn('Run "pnpm manage-db init" to create it.');
|
console.warn('Run "bun run manage-db init" to create it.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,10 +235,10 @@ async function initializeDatabase() {
|
|||||||
if (fs.existsSync(dataDbFile)) {
|
if (fs.existsSync(dataDbFile)) {
|
||||||
console.log("⚠️ Database already exists at data/gitea-mirror.db");
|
console.log("⚠️ Database already exists at data/gitea-mirror.db");
|
||||||
console.log(
|
console.log(
|
||||||
'If you want to recreate the database, run "pnpm cleanup-db" first.'
|
'If you want to recreate the database, run "bun run cleanup-db" first.'
|
||||||
);
|
);
|
||||||
console.log(
|
console.log(
|
||||||
'Or use "pnpm manage-db reset-users" to just remove users without recreating tables.'
|
'Or use "bun run manage-db reset-users" to just remove users without recreating tables.'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Check if we can connect to it
|
// Check if we can connect to it
|
||||||
@@ -457,7 +457,7 @@ async function resetUsers() {
|
|||||||
|
|
||||||
if (!doesDbExist) {
|
if (!doesDbExist) {
|
||||||
console.log(
|
console.log(
|
||||||
"❌ Database file doesn't exist. Run 'pnpm manage-db init' first to create it."
|
"❌ Database file doesn't exist. Run 'bun run manage-db init' first to create it."
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -629,7 +629,7 @@ async function fixDatabaseIssues() {
|
|||||||
console.warn(
|
console.warn(
|
||||||
"⚠️ WARNING: Production database file not found in data directory."
|
"⚠️ WARNING: Production database file not found in data directory."
|
||||||
);
|
);
|
||||||
console.warn('Run "pnpm manage-db init" to create it.');
|
console.warn('Run "bun run manage-db init" to create it.');
|
||||||
} else {
|
} else {
|
||||||
console.log("✅ Production database file found in data directory.");
|
console.log("✅ Production database file found in data directory.");
|
||||||
|
|
||||||
@@ -641,7 +641,7 @@ async function fixDatabaseIssues() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error connecting to the database:", error);
|
console.error("❌ Error connecting to the database:", error);
|
||||||
console.warn(
|
console.warn(
|
||||||
'The database file might be corrupted. Consider running "pnpm manage-db init" to recreate it.'
|
'The database file might be corrupted. Consider running "bun run manage-db init" to recreate it.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,7 +692,7 @@ Available commands:
|
|||||||
reset-users - Remove all users and their data
|
reset-users - Remove all users and their data
|
||||||
auto - Automatic mode: check, fix, and initialize if needed
|
auto - Automatic mode: check, fix, and initialize if needed
|
||||||
|
|
||||||
Usage: pnpm manage-db [command]
|
Usage: bun run manage-db [command]
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ The application is built using:
|
|||||||
- <span class="font-semibold text-foreground">React</span>: Component library for interactive UI elements
|
- <span class="font-semibold text-foreground">React</span>: Component library for interactive UI elements
|
||||||
- <span class="font-semibold text-foreground">Shadcn UI</span>: UI component library built on Tailwind CSS
|
- <span class="font-semibold text-foreground">Shadcn UI</span>: UI component library built on Tailwind CSS
|
||||||
- <span class="font-semibold text-foreground">SQLite</span>: Database for storing configuration and state
|
- <span class="font-semibold text-foreground">SQLite</span>: Database for storing configuration and state
|
||||||
- <span class="font-semibold text-foreground">Node.js</span>: Runtime environment for the backend
|
- <span class="font-semibold text-foreground">Bun</span>: Runtime environment for the backend
|
||||||
|
|
||||||
## Architecture Diagram
|
## Architecture Diagram
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ The application is built using:
|
|||||||
graph TD
|
graph TD
|
||||||
subgraph "Gitea Mirror"
|
subgraph "Gitea Mirror"
|
||||||
Frontend["Frontend<br/>(Astro)"]
|
Frontend["Frontend<br/>(Astro)"]
|
||||||
Backend["Backend<br/>(Node.js)"]
|
Backend["Backend<br/>(Bun)"]
|
||||||
Database["Database<br/>(SQLite)"]
|
Database["Database<br/>(SQLite)"]
|
||||||
|
|
||||||
Frontend <--> Backend
|
Frontend <--> Backend
|
||||||
@@ -60,9 +60,9 @@ Key frontend components:
|
|||||||
- **Configuration**: Settings for GitHub and Gitea connections
|
- **Configuration**: Settings for GitHub and Gitea connections
|
||||||
- **Activity Log**: Detailed log of mirroring operations
|
- **Activity Log**: Detailed log of mirroring operations
|
||||||
|
|
||||||
### Backend (Node.js)
|
### Backend (Bun)
|
||||||
|
|
||||||
The backend is built with Node.js and provides API endpoints for the frontend to interact with. It handles:
|
The backend is built with Bun and provides API endpoints for the frontend to interact with. It handles:
|
||||||
|
|
||||||
- Authentication and user management
|
- Authentication and user management
|
||||||
- GitHub API integration
|
- GitHub API integration
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ The following environment variables can be used to configure Gitea Mirror:
|
|||||||
|
|
||||||
| Variable | Description | Default Value | Example |
|
| Variable | Description | Default Value | Example |
|
||||||
|----------|-------------|---------------|---------|
|
|----------|-------------|---------------|---------|
|
||||||
| `NODE_ENV` | Node environment (development, production, test) | `development` | `production` |
|
| `NODE_ENV` | Runtime environment (development, production, test) | `development` | `production` |
|
||||||
| `DATABASE_URL` | SQLite database URL | `sqlite://data/gitea-mirror.db` | `sqlite://path/to/your/database.db` |
|
| `DATABASE_URL` | SQLite database URL | `sqlite://data/gitea-mirror.db` | `sqlite://path/to/your/database.db` |
|
||||||
| `JWT_SECRET` | Secret key for JWT authentication | `your-secret-key-change-this-in-production` | `your-secure-random-string` |
|
| `JWT_SECRET` | Secret key for JWT authentication | `your-secret-key-change-this-in-production` | `your-secure-random-string` |
|
||||||
| `HOST` | Server host | `localhost` | `0.0.0.0` |
|
| `HOST` | Server host | `localhost` | `0.0.0.0` |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Before you begin, make sure you have:
|
|||||||
|
|
||||||
1. <span class="font-semibold text-foreground">A GitHub account with a personal access token</span>
|
1. <span class="font-semibold text-foreground">A GitHub account with a personal access token</span>
|
||||||
2. <span class="font-semibold text-foreground">A Gitea instance with an access token</span>
|
2. <span class="font-semibold text-foreground">A Gitea instance with an access token</span>
|
||||||
3. <span class="font-semibold text-foreground">Docker and docker-compose (recommended) or Node.js 18+ installed</span>
|
3. <span class="font-semibold text-foreground">Docker and docker-compose (recommended) or Bun 1.2.9+ installed</span>
|
||||||
|
|
||||||
## Installation Options
|
## Installation Options
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ If you prefer to run the application directly on your system:
|
|||||||
|
|
||||||
2. Run the quick setup script:
|
2. Run the quick setup script:
|
||||||
```bash
|
```bash
|
||||||
pnpm setup
|
bun run setup
|
||||||
```
|
```
|
||||||
This installs dependencies and initializes the database.
|
This installs dependencies and initializes the database.
|
||||||
|
|
||||||
@@ -59,13 +59,13 @@ If you prefer to run the application directly on your system:
|
|||||||
|
|
||||||
**Development Mode:**
|
**Development Mode:**
|
||||||
```bash
|
```bash
|
||||||
pnpm dev
|
bun run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
**Production Mode:**
|
**Production Mode:**
|
||||||
```bash
|
```bash
|
||||||
pnpm build
|
bun run build
|
||||||
pnpm start
|
bun run start
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Access the application at [http://localhost:4321](http://localhost:4321)
|
4. Access the application at [http://localhost:4321](http://localhost:4321)
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
// Environment variables
|
// Environment variables
|
||||||
export const ENV = {
|
export const ENV = {
|
||||||
// Node environment (development, production, test)
|
// Runtime environment (development, production, test)
|
||||||
NODE_ENV: process.env.NODE_ENV || "development",
|
NODE_ENV: process.env.NODE_ENV || "development",
|
||||||
|
|
||||||
// Database URL - use SQLite by default
|
// Database URL - use SQLite by default
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { createClient } from "@libsql/client";
|
import { Database } from "bun:sqlite";
|
||||||
import { drizzle } from "drizzle-orm/libsql";
|
import { drizzle } from "drizzle-orm/bun-sqlite";
|
||||||
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
@@ -11,11 +11,24 @@ const dataDir = path.join(process.cwd(), "data");
|
|||||||
const dbUrl =
|
const dbUrl =
|
||||||
process.env.DATABASE_URL || `file:${path.join(dataDir, "gitea-mirror.db")}`;
|
process.env.DATABASE_URL || `file:${path.join(dataDir, "gitea-mirror.db")}`;
|
||||||
|
|
||||||
// Create a client connection to the database
|
// Create a SQLite database instance using Bun's native driver
|
||||||
export const client = createClient({ url: dbUrl });
|
export const sqlite = new Database(dbUrl);
|
||||||
|
|
||||||
|
// Simple async wrapper around Bun's SQLite API for compatibility
|
||||||
|
export const client = {
|
||||||
|
async execute(sql: string, params?: any[]) {
|
||||||
|
const stmt = sqlite.query(sql);
|
||||||
|
if (/^\s*select/i.test(sql)) {
|
||||||
|
const rows = stmt.all(params ?? []);
|
||||||
|
return { rows } as { rows: any[] };
|
||||||
|
}
|
||||||
|
stmt.run(params ?? []);
|
||||||
|
return { rows: [] } as { rows: any[] };
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Create a drizzle instance
|
// Create a drizzle instance
|
||||||
export const db = drizzle(client);
|
export const db = drizzle(sqlite);
|
||||||
|
|
||||||
// Define the tables
|
// Define the tables
|
||||||
export const users = sqliteTable("users", {
|
export const users = sqliteTable("users", {
|
||||||
|
|||||||
@@ -1,30 +1,23 @@
|
|||||||
import Redis from "ioredis";
|
import { RedisClient } from "bun";
|
||||||
|
|
||||||
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
|
// Connect to Redis using REDIS_URL environment variable or default to redis://redis:6379
|
||||||
// This ensures we have a fallback URL when running with Docker Compose
|
// This ensures we have a fallback URL when running with Docker Compose
|
||||||
const redisUrl = process.env.REDIS_URL ?? 'redis://redis:6379';
|
const redisUrl = process.env.REDIS_URL ?? "redis://redis:6379";
|
||||||
|
|
||||||
console.log(`Connecting to Redis at: ${redisUrl}`);
|
console.log(`Connecting to Redis at: ${redisUrl}`);
|
||||||
|
|
||||||
// Configure Redis client with connection options
|
// Configure Redis client with connection options
|
||||||
const redisOptions = {
|
function createClient() {
|
||||||
retryStrategy: (times: number) => {
|
return new RedisClient(redisUrl, {
|
||||||
// Retry with exponential backoff up to 30 seconds
|
autoReconnect: true,
|
||||||
const delay = Math.min(times * 100, 3000);
|
});
|
||||||
console.log(`Redis connection attempt ${times} failed. Retrying in ${delay}ms...`);
|
}
|
||||||
return delay;
|
|
||||||
},
|
export const redis = createClient();
|
||||||
maxRetriesPerRequest: 5,
|
export const redisPublisher = createClient();
|
||||||
enableReadyCheck: true,
|
export const redisSubscriber = createClient();
|
||||||
connectTimeout: 10000,
|
|
||||||
|
redis.onconnect = () => console.log("Connected to Redis server");
|
||||||
|
redis.onclose = (err) => {
|
||||||
|
if (err) console.error("Disconnected from Redis server:", err);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const redis = new Redis(redisUrl, redisOptions);
|
|
||||||
export const redisPublisher = new Redis(redisUrl, redisOptions); // For publishing
|
|
||||||
export const redisSubscriber = new Redis(redisUrl, redisOptions); // For subscribing
|
|
||||||
|
|
||||||
// Log connection events
|
|
||||||
redis.on('connect', () => console.log('Redis client connected'));
|
|
||||||
redis.on('error', (err) => console.error('Redis client error:', err));
|
|
||||||
redis.on('ready', () => console.log('Redis client ready'));
|
|
||||||
redis.on('reconnecting', () => console.log('Redis client reconnecting...'));
|
|
||||||
|
|||||||
Reference in New Issue
Block a user