remove .local
This commit is contained in:
@@ -1,28 +0,0 @@
|
|||||||
# NFOGuard Environment Variables
|
|
||||||
|
|
||||||
# User and Group IDs
|
|
||||||
PUID=1000
|
|
||||||
PGID=1000
|
|
||||||
|
|
||||||
# Timezone
|
|
||||||
TZ=UTC
|
|
||||||
|
|
||||||
# Media path (for read-only access to scan NFO files)
|
|
||||||
MEDIA_PATH=/path/to/your/media
|
|
||||||
|
|
||||||
# Database settings (if using PostgreSQL)
|
|
||||||
# DB_USER=nfoguard
|
|
||||||
# DB_PASSWORD=your_secure_password
|
|
||||||
|
|
||||||
# Emby Plugin Deployment - Bind Mount Method (Recommended)
|
|
||||||
# Set this to the path where Emby plugins are installed on your host
|
|
||||||
# Common paths:
|
|
||||||
# - /var/lib/emby/plugins (native Emby install)
|
|
||||||
# - /path/to/emby/config/plugins (Docker Emby)
|
|
||||||
# - /config/plugins (linuxserver.io Emby)
|
|
||||||
EMBY_PLUGINS_PATH=/path/to/emby/plugins
|
|
||||||
|
|
||||||
# NFOGuard specific settings
|
|
||||||
DEBUG=false
|
|
||||||
PATH_DEBUG=false
|
|
||||||
SUPPRESS_TVDB_WARNINGS=true
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
# NFOGuard Environment Configuration Template
|
|
||||||
# Copy this to .env and customize for your setup
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# MEDIA PATHS (REQUIRED)
|
|
||||||
# ===========================================
|
|
||||||
# Paths where your movies and TV shows are stored inside the container
|
|
||||||
# Adjust these to match YOUR directory structure
|
|
||||||
TV_PATHS=/media/TV/tv,/media/TV/tv6
|
|
||||||
MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# DATABASE CONFIGURATION
|
|
||||||
# ===========================================
|
|
||||||
# NFOGuard SQLite database location
|
|
||||||
DB_PATH=/app/data/media_dates.db
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# RADARR DATABASE CONNECTION (REQUIRED)
|
|
||||||
# ===========================================
|
|
||||||
# Connection to Radarr's PostgreSQL database
|
|
||||||
# NOTE: Database password should be set in .env.secrets file
|
|
||||||
RADARR_DB_HOST=radarr-postgres
|
|
||||||
RADARR_DB_PORT=5432
|
|
||||||
RADARR_DB_NAME=radarr
|
|
||||||
RADARR_DB_USER=radarr
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# RADARR API (OPTIONAL - for fallback)
|
|
||||||
# ===========================================
|
|
||||||
# Only needed if you want API fallback (not recommended for performance)
|
|
||||||
# NOTE: API key should be set in .env.secrets file
|
|
||||||
RADARR_URL=http://radarr:7878
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# SONARR API (REQUIRED for Enhanced TV NFOs - v0.6.0+)
|
|
||||||
# ===========================================
|
|
||||||
# Required for TV processing and enhanced NFO generation with metadata
|
|
||||||
# NOTE: API key should be set in .env.secrets file
|
|
||||||
SONARR_URL=http://sonarr:8989
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# EXTERNAL APIs FOR DIGITAL RELEASE DATES
|
|
||||||
# ===========================================
|
|
||||||
# NOTE: All API keys should be set in .env.secrets file
|
|
||||||
# See .env.secrets.template for required keys:
|
|
||||||
# - TMDB_API_KEY (recommended for digital release dates)
|
|
||||||
# - OMDB_API_KEY (optional for DVD/digital release dates)
|
|
||||||
# - JELLYSEERR_API_KEY (optional for additional digital release data)
|
|
||||||
|
|
||||||
# Jellyseerr URL (optional)
|
|
||||||
JELLYSEERR_URL=http://jellyseerr:5055
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# NFO MANAGEMENT
|
|
||||||
# ===========================================
|
|
||||||
# Whether to create/update .nfo files
|
|
||||||
MANAGE_NFO=true
|
|
||||||
|
|
||||||
# Whether to fix file modification times to match import dates
|
|
||||||
FIX_DIR_MTIMES=true
|
|
||||||
|
|
||||||
# Whether to add <lockdata> tags to prevent metadata drift
|
|
||||||
LOCK_METADATA=true
|
|
||||||
|
|
||||||
# Brand name to add to NFO files
|
|
||||||
MANAGER_BRAND=NFOGuard
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# PROCESSING SETTINGS
|
|
||||||
# ===========================================
|
|
||||||
# Delay before processing batched webhook events (seconds)
|
|
||||||
BATCH_DELAY=5.0
|
|
||||||
|
|
||||||
# Maximum concurrent series processing
|
|
||||||
MAX_CONCURRENT_SERIES=3
|
|
||||||
|
|
||||||
# Movie date strategy: import_then_digital or digital_then_import
|
|
||||||
MOVIE_PRIORITY=import_then_digital
|
|
||||||
|
|
||||||
# Smart fallback: prefer release dates over file dates for manual imports (true/false)
|
|
||||||
PREFER_RELEASE_DATES_OVER_FILE_DATES=true
|
|
||||||
|
|
||||||
# Allow file dates as absolute last resort (true/false)
|
|
||||||
# If false, movies with no valid import AND no release dates will be skipped entirely
|
|
||||||
ALLOW_FILE_DATE_FALLBACK=false
|
|
||||||
|
|
||||||
# Fallback priority order when no valid Radarr import exists (comma-separated)
|
|
||||||
# Options: digital, physical, theatrical
|
|
||||||
# digital = VOD/streaming release, physical = DVD/Blu-ray, theatrical = cinema release
|
|
||||||
RELEASE_DATE_PRIORITY=digital,physical,theatrical
|
|
||||||
|
|
||||||
# Smart date validation: automatically prefer theatrical over unreasonably late digital/physical dates
|
|
||||||
# Example: "The Craft (1996)" theatrical vs "The Craft (2022)" physical → chooses 1996 theatrical
|
|
||||||
ENABLE_SMART_DATE_VALIDATION=true
|
|
||||||
|
|
||||||
# Maximum reasonable gap between theatrical and digital/physical release (in years)
|
|
||||||
# If digital/physical is more than this many years after theatrical, prefer theatrical instead
|
|
||||||
MAX_RELEASE_DATE_GAP_YEARS=10
|
|
||||||
|
|
||||||
# TMDB country for regional release date preferences
|
|
||||||
TMDB_COUNTRY=US
|
|
||||||
|
|
||||||
# TMDB release type priority (comma-separated numbers)
|
|
||||||
# 1=Premiere, 2=Limited Theatrical, 3=Theatrical, 4=Digital, 5=Physical, 6=TV Premiere
|
|
||||||
# Default: 4,5,3,2,6,1 (Digital → Physical → Theatrical → Limited → TV → Premiere)
|
|
||||||
TMDB_TYPE_PRIORITY=4,5,3,2,6,1
|
|
||||||
|
|
||||||
# When to query APIs: always, if_missing, never
|
|
||||||
MOVIE_POLL_MODE=always
|
|
||||||
|
|
||||||
# Update mode: backfill_only or overwrite
|
|
||||||
MOVIE_DATE_UPDATE_MODE=backfill_only
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# TV SERIES PROCESSING
|
|
||||||
# ===========================================
|
|
||||||
# Season directory naming format (supports {season} placeholder)
|
|
||||||
# Examples: "Season {season:02d}" -> "Season 01", "S{season:02d}" -> "S01"
|
|
||||||
TV_SEASON_DIR_FORMAT=Season {season:02d}
|
|
||||||
|
|
||||||
# Season directory detection pattern (lowercase, what to look for at start of dir name)
|
|
||||||
# Examples: "season " -> matches "Season 01", "s" -> matches "S01", "season" -> matches "Season01"
|
|
||||||
TV_SEASON_DIR_PATTERN=season
|
|
||||||
|
|
||||||
# TV webhook processing mode (v0.6.0+)
|
|
||||||
# targeted = Only process episodes mentioned in webhook (efficient, recommended)
|
|
||||||
# series = Process entire series directory (comprehensive, current default)
|
|
||||||
TV_WEBHOOK_PROCESSING_MODE=targeted
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# LOGGING
|
|
||||||
# ===========================================
|
|
||||||
# Enable debug logging
|
|
||||||
DEBUG=false
|
|
||||||
|
|
||||||
# ===========================================
|
|
||||||
# SERVER
|
|
||||||
# ===========================================
|
|
||||||
# Port to run the webhook server on
|
|
||||||
PORT=8080
|
|
||||||
-153
@@ -1,153 +0,0 @@
|
|||||||
# NFOGuard Setup Guide
|
|
||||||
|
|
||||||
## 🔐 Secure Configuration Setup
|
|
||||||
|
|
||||||
NFOGuard now uses a **two-file configuration system** for better security and easier troubleshooting:
|
|
||||||
|
|
||||||
- **`.env`** - Main configuration (safe to share for debugging)
|
|
||||||
- **`.env.secrets`** - Sensitive API keys and passwords (never commit to git)
|
|
||||||
|
|
||||||
### Step 1: Copy Configuration Templates
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copy main configuration
|
|
||||||
cp .env.template .env
|
|
||||||
|
|
||||||
# Copy secrets configuration
|
|
||||||
cp .env.secrets.template .env.secrets
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 2: Configure Main Settings
|
|
||||||
|
|
||||||
Edit your `.env` file with your specific paths and preferences:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Media paths (adjust to your directory structure)
|
|
||||||
TV_PATHS=/media/TV/tv,/media/TV/tv6
|
|
||||||
MOVIE_PATHS=/media/Movies/movies,/media/Movies/movies6
|
|
||||||
|
|
||||||
# Database connection details
|
|
||||||
RADARR_DB_HOST=radarr-postgres
|
|
||||||
RADARR_DB_PORT=5432
|
|
||||||
RADARR_DB_NAME=radarr
|
|
||||||
RADARR_DB_USER=radarr
|
|
||||||
|
|
||||||
# Processing preferences
|
|
||||||
PREFER_RELEASE_DATES_OVER_FILE_DATES=true
|
|
||||||
ALLOW_FILE_DATE_FALLBACK=false
|
|
||||||
RELEASE_DATE_PRIORITY=digital,physical,theatrical
|
|
||||||
|
|
||||||
# TV webhook processing mode (v0.6.0+)
|
|
||||||
TV_WEBHOOK_PROCESSING_MODE=targeted
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Configure Secrets
|
|
||||||
|
|
||||||
Edit your `.env.secrets` file with your actual API keys and passwords:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Database password
|
|
||||||
RADARR_DB_PASSWORD=your_actual_radarr_password
|
|
||||||
|
|
||||||
# TMDB API key (required for release date detection)
|
|
||||||
TMDB_API_KEY=your_actual_tmdb_api_key
|
|
||||||
|
|
||||||
# Sonarr API key (REQUIRED for v0.6.0+ Enhanced TV NFO Generation)
|
|
||||||
SONARR_API_KEY=your_actual_sonarr_api_key
|
|
||||||
|
|
||||||
# Optional API keys
|
|
||||||
RADARR_API_KEY=your_radarr_api_key
|
|
||||||
OMDB_API_KEY=your_omdb_api_key
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 4: Verify Configuration
|
|
||||||
|
|
||||||
Test your setup:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Test database connections
|
|
||||||
curl -X POST "http://localhost:8080/test/bulk-update"
|
|
||||||
|
|
||||||
# Test movie scanning
|
|
||||||
curl -X POST "http://localhost:8080/test/movie-scan"
|
|
||||||
|
|
||||||
# Check system health
|
|
||||||
curl "http://localhost:8080/health"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🔒 Security Features
|
|
||||||
|
|
||||||
### API Key Masking
|
|
||||||
All API keys and passwords are automatically masked in logs:
|
|
||||||
```
|
|
||||||
[2025-09-09T12:34:56] INFO: TMDB API call with key=***masked***
|
|
||||||
[2025-09-09T12:34:56] INFO: Database connection password=***masked***
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sensitive Data Separation
|
|
||||||
- **Main `.env`**: Paths, preferences, URLs (safe to share)
|
|
||||||
- **`.env.secrets`**: API keys, passwords (never commit to version control)
|
|
||||||
- **Automatic loading**: Both files loaded automatically at startup
|
|
||||||
|
|
||||||
### Git Protection
|
|
||||||
The `.gitignore` file prevents accidental commits:
|
|
||||||
```
|
|
||||||
.env
|
|
||||||
.env.secrets
|
|
||||||
.env.local
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🛠 Troubleshooting
|
|
||||||
|
|
||||||
### "Environment files not loaded" Warning
|
|
||||||
Install python-dotenv:
|
|
||||||
```bash
|
|
||||||
pip install python-dotenv==1.0.0
|
|
||||||
# or
|
|
||||||
docker-compose build # rebuilds with updated requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
### Sharing Configuration for Help
|
|
||||||
You can safely share your `.env` file for debugging since it contains no sensitive data. The `.env.secrets` file should never be shared.
|
|
||||||
|
|
||||||
### Migration from Old Setup
|
|
||||||
If you have an existing `.env` with API keys:
|
|
||||||
1. Move all `*_API_KEY` and `*_PASSWORD` variables to `.env.secrets`
|
|
||||||
2. Remove sensitive data from `.env`
|
|
||||||
3. Restart NFOGuard
|
|
||||||
|
|
||||||
## 🎯 Docker Compose Example
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
version: '3.8'
|
|
||||||
services:
|
|
||||||
nfoguard:
|
|
||||||
image: sbcrumb/nfoguard:latest
|
|
||||||
container_name: nfoguard
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
volumes:
|
|
||||||
- /path/to/your/media:/media:rw
|
|
||||||
- ./data:/app/data
|
|
||||||
- ./.env:/app/.env:ro # Main configuration
|
|
||||||
- ./.env.secrets:/app/.env.secrets:ro # Secrets
|
|
||||||
environment:
|
|
||||||
- PORT=8080
|
|
||||||
depends_on:
|
|
||||||
- radarr-postgres
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📋 Configuration Reference
|
|
||||||
|
|
||||||
### Main Configuration (.env)
|
|
||||||
- **Paths**: `TV_PATHS`, `MOVIE_PATHS`, `DB_PATH`
|
|
||||||
- **Processing**: `MOVIE_PRIORITY`, `RELEASE_DATE_PRIORITY`
|
|
||||||
- **Features**: `MANAGE_NFO`, `FIX_DIR_MTIMES`, `LOCK_METADATA`
|
|
||||||
- **URLs**: `RADARR_URL`, `SONARR_URL`, `JELLYSEERR_URL`
|
|
||||||
|
|
||||||
### Secrets Configuration (.env.secrets)
|
|
||||||
- **Database**: `RADARR_DB_PASSWORD`
|
|
||||||
- **APIs**: `TMDB_API_KEY`, `OMDB_API_KEY`, `RADARR_API_KEY`, `SONARR_API_KEY`
|
|
||||||
- **Optional**: `JELLYSEERR_API_KEY`
|
|
||||||
|
|
||||||
This setup makes NFOGuard more secure while keeping configuration manageable for troubleshooting and deployment.
|
|
||||||
@@ -1,259 +0,0 @@
|
|||||||
# NFOGuard Development Summary - September 24, 2025
|
|
||||||
|
|
||||||
## 🔥 CRITICAL SECURITY & PRIVACY FIXES COMPLETED
|
|
||||||
|
|
||||||
### 🛡️ Privacy Protection (COMPLETED)
|
|
||||||
- **REDACTED**: Removed personal name "jskala" from all Gitea workflows (kept on private Gitea, removed from public GitHub)
|
|
||||||
- **SECURITY**: Personal information completely scrubbed from public repository
|
|
||||||
- **SEPARATION**: Gitea (private dev) vs GitHub (public release) properly isolated
|
|
||||||
|
|
||||||
### 🤖 Claude Attribution Removal (COMPLETED)
|
|
||||||
- **ELIMINATED**: All "Co-Authored-By: Claude" lines from commit history
|
|
||||||
- **CLEAN HISTORY**: Repository recreated with professional commit history
|
|
||||||
- **CONTRIBUTOR LIST**: GitHub now shows only sbcrumb as contributor (0 Claude references)
|
|
||||||
- **FRESH START**: Repository deleted and recreated to eliminate all AI attribution
|
|
||||||
|
|
||||||
### 📋 Repository Refresh (COMPLETED)
|
|
||||||
- **PROFESSIONAL**: Added clean "Repository Refresh" notice in README explaining fresh start
|
|
||||||
- **POSITIONING**: Framed as intentional improvement for "professional and streamlined experience"
|
|
||||||
- **NO AI MENTIONS**: Zero references to Claude or AI assistance anywhere
|
|
||||||
|
|
||||||
## 🐳 Docker Hub Integration (COMPLETED)
|
|
||||||
|
|
||||||
### 🔧 Workflow Fixes
|
|
||||||
- **FIXED**: Changed from GitHub Container Registry (GHCR) to Docker Hub
|
|
||||||
- **WORKING**: Builds now push to `sbcrumb/nfoguard:1.7.1` and `:latest`
|
|
||||||
- **AUTHENTICATION**: Uses DOCKER_HUB_USERNAME and DOCKER_HUB_TOKEN secrets
|
|
||||||
- **AUTOMATION**: Triggers on pushes to main branch with proper versioning
|
|
||||||
|
|
||||||
### 📦 Release Management
|
|
||||||
- **SYNCHRONIZED**: VERSION file matches Docker tags and GitHub releases
|
|
||||||
- **AUTOMATED**: Release drafter creates releases with Docker Hub links
|
|
||||||
- **VERSIONING**: Fixed version mismatches between workflows
|
|
||||||
|
|
||||||
## ✅ MAJOR NFO RELEASE DATE BUG FIXES COMPLETED
|
|
||||||
|
|
||||||
### 🎯 Core Issue Resolved
|
|
||||||
Movies were getting minimal NFO files with "no_valid_date_source" when digital release dates were available from TMDB/OMDB but not being used properly.
|
|
||||||
|
|
||||||
**ROOT CAUSES IDENTIFIED & FIXED:**
|
|
||||||
- should_query logic wasn't querying APIs when database had empty entries
|
|
||||||
- Digital release dates weren't being used as dateadded fallback
|
|
||||||
- NFOGuard fields were scattered in NFO files instead of grouped at bottom
|
|
||||||
- Emby plugin compatibility issues with dateadded field positioning
|
|
||||||
|
|
||||||
**FIXES IMPLEMENTED:**
|
|
||||||
- Fixed should_query condition to query APIs when dateadded is None
|
|
||||||
- Use digital release dates as dateadded when import dates unavailable
|
|
||||||
- Ensure all NFOGuard fields append at bottom of NFO files
|
|
||||||
- Add NFOGuard comment marker to clearly delineate our additions
|
|
||||||
|
|
||||||
## 🚀 THREE-TIER PERFORMANCE OPTIMIZATION SYSTEM
|
|
||||||
|
|
||||||
### 🎯 Revolutionary Speed Improvements
|
|
||||||
Implemented intelligent caching system that eliminates 90%+ of processing time on warm systems:
|
|
||||||
|
|
||||||
**TIER 1 - NFO File Cache (Instant ~99% faster):**
|
|
||||||
- **MOVIES**: Detects existing NFOGuard data in NFO files (`<dateadded>` + `<lockdata>true</lockdata>`)
|
|
||||||
- **TV EPISODES**: Detects NFOGuard data in episode NFO files (`<dateadded>` + `<lockdata>true</lockdata>`)
|
|
||||||
- Uses NFO data directly, skips all database queries AND API calls
|
|
||||||
- Perfect for: Database rebuilds, migrations, disaster recovery
|
|
||||||
|
|
||||||
**TIER 2 - Database Cache (Very Fast ~90% faster):**
|
|
||||||
- **MOVIES**: Uses complete database entries when available
|
|
||||||
- **TV EPISODES**: Uses existing episode database entries with dateadded
|
|
||||||
- Skips expensive API calls to TMDB/OMDB/Radarr/Sonarr
|
|
||||||
- Creates NFO from cached data only
|
|
||||||
|
|
||||||
**TIER 3 - Full Processing (Normal Speed):**
|
|
||||||
- **MOVIES**: Only triggers when neither NFO nor database have data
|
|
||||||
- **TV EPISODES**: Falls back to Sonarr API queries and airdate extraction
|
|
||||||
- Performs full API queries, date processing, saves everything
|
|
||||||
|
|
||||||
**TIER 1.5 - TMDB Fallback Processing (Fast):**
|
|
||||||
- **MOVIES ONLY**: Special handling for TMDB-only movies without IMDb IDs
|
|
||||||
- Extracts `premiered` dates from existing NFO files created by other tools
|
|
||||||
- Uses TMDB data as fallback when standard IMDb workflow fails
|
|
||||||
|
|
||||||
### 🔧 Critical Use Cases Enabled
|
|
||||||
|
|
||||||
**DATABASE REBUILD SCENARIO:**
|
|
||||||
- User loses NFOGuard database but has processed NFO files
|
|
||||||
- **MOVIES**: System reads existing NFOGuard data from thousands of movie NFO files instantly
|
|
||||||
- **TV EPISODES**: System reads existing NFOGuard data from episode NFO files instantly
|
|
||||||
- Repopulates database without ANY API calls or rate limiting
|
|
||||||
- Complete rebuild in minutes instead of hours
|
|
||||||
|
|
||||||
**MIGRATION SCENARIO:**
|
|
||||||
- Moving to new NFOGuard installation
|
|
||||||
- Existing NFO files contain all necessary date information
|
|
||||||
- **MOVIES**: Zero API dependency for movie data recovery
|
|
||||||
- **TV EPISODES**: Zero API dependency for episode data recovery
|
|
||||||
|
|
||||||
**PERFORMANCE SCENARIO:**
|
|
||||||
- Subsequent full scans become lightning fast
|
|
||||||
- **MOVIES**: Only new movies require API processing
|
|
||||||
- **TV EPISODES**: Only new episodes require Sonarr API calls
|
|
||||||
- Existing library processes near-instantly
|
|
||||||
|
|
||||||
**EDGE CASE SCENARIO:**
|
|
||||||
- **TMDB-ONLY MOVIES**: Movies with TMDB IDs but no IMDb IDs (e.g., "For the One (2024)")
|
|
||||||
- System extracts `premiered` dates from existing NFO files created by Radarr/other tools
|
|
||||||
- Provides fallback support for movies that can't be processed via standard IMDb workflow
|
|
||||||
|
|
||||||
## 📝 SUMMARY.md PURPOSE & GUIDELINES
|
|
||||||
|
|
||||||
### 🎯 This File's Purpose
|
|
||||||
- **PRIVATE DEVELOPMENT DOCS**: This .local/SUMMARY.md stays on Gitea only
|
|
||||||
- **MEMORY AID**: Track what was actually accomplished vs what's visible publicly
|
|
||||||
- **SECURITY RECORD**: Document sensitive changes that can't be mentioned publicly
|
|
||||||
- **DEVELOPMENT CONTINUITY**: Help future sessions understand what really happened
|
|
||||||
|
|
||||||
### 🚨 CRITICAL DEVELOPMENT WORKFLOW REMINDER
|
|
||||||
|
|
||||||
**⚠️ CODE REPOSITORY ONLY - NO SYSTEM ACCESS:**
|
|
||||||
- **THIS IS A CODE REPOSITORY ONLY** - No access to running NFOGuard systems, movie directories, or file operations
|
|
||||||
- **MAKE CODE CHANGES ONLY** - Edit source files, commit to Gitea, push for local builds
|
|
||||||
- **NO BASH COMMANDS** - Cannot run python scripts, find commands, or test operations outside of git
|
|
||||||
- **GITEA LOCAL BUILDS** - All testing happens on local Gitea builds, not in development environment
|
|
||||||
- **NO FILE SYSTEM ACCESS** - Cannot access /mnt/unionfs/Media/Movies/ or any movie directories
|
|
||||||
- **CODE CHANGES → COMMIT → PUSH → BUILD** - This is the only workflow available
|
|
||||||
|
|
||||||
### 🚫 CRITICAL COMMIT MESSAGE GUIDELINES
|
|
||||||
|
|
||||||
**NEVER INCLUDE IN COMMITS:**
|
|
||||||
- ❌ "Co-Authored-By: Claude"
|
|
||||||
- ❌ "Generated with Claude Code"
|
|
||||||
- ❌ Any AI assistant mentions
|
|
||||||
- ❌ "jskala" or personal names in public commits
|
|
||||||
- ❌ References to AI tools or assistance
|
|
||||||
|
|
||||||
**ALWAYS USE:**
|
|
||||||
- ✅ Professional, technical descriptions
|
|
||||||
- ✅ Focus on "what" and "why", not "who"
|
|
||||||
- ✅ Generic developer language
|
|
||||||
- ✅ Business/technical justifications
|
|
||||||
|
|
||||||
### 🚨 CRITICAL SECURITY REMINDER
|
|
||||||
|
|
||||||
**⚠️ .local/ DIRECTORY SECURITY:**
|
|
||||||
- **NEVER COMMIT .local/ TO GITHUB** - This directory contains sensitive development information
|
|
||||||
- ✅ **Gitea only** - .local/ stays on private Gitea repository forever
|
|
||||||
- ✅ **Protected by .gitignore** - .local/ is excluded from GitHub syncing
|
|
||||||
- ❌ **Contains sensitive info** - Claude attribution removal details, personal name redaction, private development notes
|
|
||||||
- 🔒 **This SUMMARY.md** - Contains confidential information that must never be public
|
|
||||||
|
|
||||||
**IF .local/ EVER APPEARS ON GITHUB:**
|
|
||||||
1. **IMMEDIATE ACTION REQUIRED** - Delete repository and recreate
|
|
||||||
2. **SECURITY BREACH** - All sensitive development information exposed
|
|
||||||
3. **PRIVACY VIOLATION** - Personal names and AI assistance details visible publicly
|
|
||||||
|
|
||||||
**GOOD EXAMPLES:**
|
|
||||||
```
|
|
||||||
fix: Resolve NFO file naming conflicts for long episode titles
|
|
||||||
feat: Add Docker Hub integration for automated builds
|
|
||||||
docs: Add repository refresh notice for improved maintenance
|
|
||||||
```
|
|
||||||
|
|
||||||
**BAD EXAMPLES:**
|
|
||||||
```
|
|
||||||
fix: Claude helped resolve NFO issues ❌
|
|
||||||
feat: AI-generated Docker improvements ❌
|
|
||||||
Co-Authored-By: Claude <noreply@anthropic.com> ❌
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🐳 DOCKER BUILD IMPROVEMENTS COMPLETED
|
|
||||||
|
|
||||||
### 🏷️ Version-Specific Gitea Tags
|
|
||||||
- **IMPLEMENTED**: Clear Docker image tagging with version-gitea format
|
|
||||||
- **DEV BUILDS**: `sbcrumb/nfoguard:1.7.0-dev-gitea` for development testing
|
|
||||||
- **MAIN BUILDS**: `sbcrumb/nfoguard:1.7.0-gitea` for production releases
|
|
||||||
- **IDENTIFICATION**: Easy to verify you're running Gitea builds vs other sources
|
|
||||||
|
|
||||||
### 🔧 CI/CD Workflow Fixes
|
|
||||||
- **FIXED**: Repository paths changed from jskala/NFOguard to sbcrumb/nfoguard
|
|
||||||
- **WORKING**: Both dev and main branch builds functioning properly
|
|
||||||
- **AUTOMATION**: Proper Docker registry pushing and caching
|
|
||||||
|
|
||||||
## 🔄 Current Repository State
|
|
||||||
|
|
||||||
### 📍 Gitea (Private - Complete & Working Code)
|
|
||||||
- ✅ All NFO release date fixes implemented and working
|
|
||||||
- ✅ Complete development history with proper attribution handling
|
|
||||||
- ✅ .local/ directory with private development documentation
|
|
||||||
- ✅ Version 1.7.0 with comprehensive NFO improvements
|
|
||||||
- ✅ Working CI/CD with version-specific Docker tags
|
|
||||||
|
|
||||||
### 📍 GitHub (Public - Clean History, Needs Sync)
|
|
||||||
- ✅ Professional commit history (sbcrumb only)
|
|
||||||
- ✅ Working Docker Hub automation
|
|
||||||
- ✅ Zero Claude/AI references maintained
|
|
||||||
- ⚠️ **NEEDS SYNC**: GitHub main should get NFO fixes from Gitea dev
|
|
||||||
- ⚠️ **OUT OF DATE**: Missing latest 1.7.0 improvements
|
|
||||||
|
|
||||||
## 🧪 TESTING STATUS
|
|
||||||
|
|
||||||
### ✅ SUCCESSFUL TEST CASES
|
|
||||||
- **Flow (2019)**: Fixed IMDb ID issue, now gets proper digital release dates and NFO structure
|
|
||||||
- **Ambush (2023)**: Working correctly with TMDB digital release date fallback
|
|
||||||
- **Inside Out 2**: Needs reprocessing with latest code to verify NFO field positioning
|
|
||||||
|
|
||||||
### 🔧 DEBUG IMPROVEMENTS ADDED
|
|
||||||
- **Enhanced Logging**: Added should_query decision tracking and external API call debugging
|
|
||||||
- **NFO Creation Logs**: Shows exactly what parameters are passed and what fields are added
|
|
||||||
- **API Debug Endpoints**: `/debug/movie/{imdb_id}` for troubleshooting specific movies
|
|
||||||
- **IMDb ID Detection**: Comprehensive logging for directory/filename/NFO parsing
|
|
||||||
- **Three-Tier Logging**: Shows which optimization tier is used for each movie
|
|
||||||
- **Failed Movies Log**: Dedicated `logs/failed_movies.log` for movies with no_valid_date_source
|
|
||||||
|
|
||||||
### 🎯 PERFORMANCE TESTING SCENARIOS
|
|
||||||
- **Cold Database**: Test full processing with empty database (Tier 3 for all content)
|
|
||||||
- **Warm Database**: Test database optimization (Tier 2 for processed content)
|
|
||||||
- **NFO File Recovery**: Test database rebuild from existing NFO files (Tier 1 instant recovery)
|
|
||||||
- **Mixed Scenarios**: New content (Tier 3) + existing content (Tier 1/2) performance
|
|
||||||
- **TV Episode Testing**: Verify three-tier optimization works for TV shows and episodes
|
|
||||||
- **TMDB Fallback Testing**: Test movies with TMDB IDs but no IMDb IDs (Tier 1.5)
|
|
||||||
|
|
||||||
## 🎯 SUCCESS METRICS ACHIEVED
|
|
||||||
|
|
||||||
✅ **Privacy**: Zero personal info on public GitHub maintained
|
|
||||||
✅ **Attribution**: Zero Claude references anywhere public maintained
|
|
||||||
✅ **Automation**: Working Docker Hub builds and releases with version tags
|
|
||||||
✅ **Professional**: Clean repository presentation maintained
|
|
||||||
✅ **Functionality**: NFO release date logic completely fixed and working
|
|
||||||
✅ **Compatibility**: Emby plugin dateadded field positioning corrected
|
|
||||||
✅ **User Experience**: Clear Docker tags for easy identification of Gitea builds
|
|
||||||
✅ **Performance**: Revolutionary three-tier optimization system implemented for movies AND TV episodes
|
|
||||||
✅ **Reliability**: Database rebuild/disaster recovery scenarios fully supported for all content types
|
|
||||||
✅ **Scalability**: System now handles large libraries efficiently with intelligent caching
|
|
||||||
✅ **TV Episode Support**: Three-tier optimization extended to TV shows with Sonarr integration
|
|
||||||
✅ **TMDB Fallback**: Edge case support for TMDB-only movies without IMDb IDs
|
|
||||||
|
|
||||||
## 📅 FUTURE CONSIDERATIONS
|
|
||||||
|
|
||||||
### 🔄 GitHub Sync Strategy
|
|
||||||
- **WHEN TO SYNC**: After thorough testing of current NFO fixes
|
|
||||||
- **HOW TO SYNC**: Merge Gitea dev → Gitea main → GitHub main (preserving clean history)
|
|
||||||
- **PRIORITY**: Not urgent since Gitea builds are working perfectly
|
|
||||||
|
|
||||||
### 🚀 Version 1.7.0 Release Readiness
|
|
||||||
- **CURRENT STATUS**: Production-ready with game-changing performance improvements
|
|
||||||
- **TESTING NEEDED**: Verify three-tier optimization in various scenarios (movies AND TV episodes)
|
|
||||||
- **FEATURES COMPLETE**: Digital release dates, NFO structure, Emby compatibility, performance optimization, TV episode support, TMDB fallback
|
|
||||||
|
|
||||||
## 📋 IMMEDIATE ACTION ITEMS
|
|
||||||
|
|
||||||
1. **PERFORMANCE TEST**: Test three-tier optimization with various scenarios
|
|
||||||
- Empty database (cold start) for movies AND TV episodes
|
|
||||||
- Full database rebuild from existing NFO files (movies AND episodes)
|
|
||||||
- Mixed library with new + existing content (both movies and TV)
|
|
||||||
- TMDB-only movies (e.g., "For the One (2024)" with tt33293430)
|
|
||||||
2. **VALIDATE**: Confirm IMDb ID detection from filenames (Adulthood case)
|
|
||||||
3. **TV EPISODE VALIDATION**: Verify TV episode three-tier optimization in real scenarios
|
|
||||||
4. **TMDB FALLBACK TESTING**: Test movies with TMDB IDs but no IMDb IDs
|
|
||||||
5. **MONITOR**: Database size should remain appropriate with new optimizations
|
|
||||||
6. **BENCHMARK**: Compare scan times before/after optimization (should see 90%+ improvement)
|
|
||||||
7. **DEBUG LOG**: Check `logs/failed_movies.log` for movies that couldn't get valid dates
|
|
||||||
|
|
||||||
---
|
|
||||||
**CONFIDENTIAL**: This file contains sensitive development information and remains on private Gitea only.
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# =� NFOGuard v1.6.9 - Enhanced NFO Migration & Workflow Automation
|
|
||||||
|
|
||||||
## <� Major Features
|
|
||||||
|
|
||||||
### Complete NFO Migration System
|
|
||||||
- **Smart Content Preservation**: Automatically migrates rich metadata (title, plot, runtime) from long-named Sonarr NFO files to standardized `S##E##.nfo` format
|
|
||||||
- **Intelligent File Detection**: Enhanced `find_existing_episode_nfo()` detects matching season/episode in any NFO file naming convention
|
|
||||||
- **Automatic Cleanup**: Long-named NFO files automatically deleted after successful migration
|
|
||||||
- **Priority Logic Fix**: Migration now correctly prioritizes long-named files over existing short files for content extraction
|
|
||||||
|
|
||||||
### Workflow Automation Overhaul
|
|
||||||
- **Local-Only Builds**: Removed all Docker Hub dependencies, builds now local-only for faster, more secure CI/CD
|
|
||||||
- **GitHub Integration**: Automated local � GitHub workflow for public testing and releases
|
|
||||||
- **Post-Merge Automation**: Git hooks automatically sync local main to GitHub dev branch with PR creation
|
|
||||||
- **Version Management**: Integrated semantic versioning with automatic increment options (patch/minor/major)
|
|
||||||
|
|
||||||
### Build Identification System
|
|
||||||
- **Branch Detection**: Automatic git branch detection during Docker builds
|
|
||||||
- **Environment Tagging**: Clear version identification (`1.6.9-dev-gitea` vs `1.6.9`)
|
|
||||||
- **Build Source Tracking**: Distinguishes local Gitea builds from public GitHub releases
|
|
||||||
|
|
||||||
## =' Technical Improvements
|
|
||||||
|
|
||||||
### Docker Enhancements
|
|
||||||
- **Graceful Shutdown**: Added proper SIGTERM/SIGINT signal handling for clean container stops
|
|
||||||
- **Branch-Specific Builds**: Workflow now correctly clones target branch instead of default
|
|
||||||
- **Build Arguments**: Proper `GIT_BRANCH` and `BUILD_SOURCE` parameter passing
|
|
||||||
|
|
||||||
### Debug System
|
|
||||||
- **Conditional Logging**: All debug statements now respect `DEBUG=true/false` environment variable
|
|
||||||
- **Migration Tracking**: Detailed logging for NFO content preservation process (when enabled)
|
|
||||||
- **Clean Production Logs**: Debug noise eliminated when `DEBUG=false`
|
|
||||||
|
|
||||||
## <� NFO Migration Details
|
|
||||||
|
|
||||||
**Before**: Long-named Sonarr NFO files existed alongside minimal short NFO files, content was lost
|
|
||||||
**After**: Rich metadata automatically preserved in standardized format, old files cleaned up
|
|
||||||
|
|
||||||
**Example Migration**:
|
|
||||||
```
|
|
||||||
Source: "Invasion (2021)-S03E04-The Mission[WEBDL-1080p][AAC2.0][h264].nfo"
|
|
||||||
Target: "S03E04.nfo"
|
|
||||||
Content: title, plot, runtime, premiered � All preserved
|
|
||||||
Cleanup: Original long file � Automatically deleted
|
|
||||||
```
|
|
||||||
|
|
||||||
## =� New Release Workflow
|
|
||||||
|
|
||||||
1. **Local Development** � dev branch with local Gitea CI
|
|
||||||
2. **Local Release** � Merge dev to main triggers GitHub sync
|
|
||||||
3. **Public Testing** � GitHub dev branch for community testing
|
|
||||||
4. **Production Release** � Manual PR approval to GitHub main
|
|
||||||
|
|
||||||
## =� Developer Experience
|
|
||||||
|
|
||||||
- **Version Bumping**: Never forget with integrated `sync-to-github.sh` script
|
|
||||||
- **Build Clarity**: Always know which environment you're running
|
|
||||||
- **Fast Iteration**: Local-only builds eliminate external dependencies
|
|
||||||
- **Debug Control**: Toggle verbose logging with single environment variable
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Breaking Changes**: None - fully backward compatible
|
|
||||||
**Migration**: Automatic - existing NFO files will be migrated on next scan
|
|
||||||
**Requirements**: No additional dependencies
|
|
||||||
|
|
||||||
@@ -1,602 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# NFOGuard Dual-Repo Development Sync Script
|
|
||||||
# Manages Gitea (private) + GitHub (public) workflow with AI attribution prevention
|
|
||||||
# CONFIDENTIAL: Stays in .local/ directory only
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
GITEA_REMOTE="origin" # gitea@192.168.253.221:sbcrumb/nfoguard.git
|
|
||||||
GITHUB_REMOTE="github" # git@github.com:sbcrumb/nfoguard.git
|
|
||||||
VERSION_FILE="VERSION"
|
|
||||||
|
|
||||||
# Helper functions
|
|
||||||
log_info() { echo -e "${BLUE}ℹ️ $1${NC}"; }
|
|
||||||
log_success() { echo -e "${GREEN}✅ $1${NC}"; }
|
|
||||||
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
|
|
||||||
log_error() { echo -e "${RED}❌ $1${NC}"; }
|
|
||||||
|
|
||||||
# Help with common mistakes and suggestions
|
|
||||||
suggest_command() {
|
|
||||||
local input="$1"
|
|
||||||
local suggestions=()
|
|
||||||
|
|
||||||
# Common typos and alternatives
|
|
||||||
case "$input" in
|
|
||||||
"create"|"new"|"begin"|"init")
|
|
||||||
suggestions+=("start")
|
|
||||||
;;
|
|
||||||
"merge"|"pr"|"pullrequest"|"pull-request")
|
|
||||||
suggestions+=("github-pr")
|
|
||||||
;;
|
|
||||||
"clean"|"cleanup"|"remove"|"delete")
|
|
||||||
suggestions+=("cleanup-github-pr")
|
|
||||||
;;
|
|
||||||
"check"|"info"|"show")
|
|
||||||
suggestions+=("status")
|
|
||||||
;;
|
|
||||||
"push"|"deploy"|"publish")
|
|
||||||
suggestions+=("release")
|
|
||||||
;;
|
|
||||||
"dev"|"develop"|"development")
|
|
||||||
suggestions+=("test")
|
|
||||||
;;
|
|
||||||
"help"|"--help"|"-h")
|
|
||||||
suggestions+=("(see help below)")
|
|
||||||
;;
|
|
||||||
"ver"|"version")
|
|
||||||
suggestions+=("version")
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Fuzzy matching for close commands
|
|
||||||
local commands=("start" "test" "release" "github-pr" "cleanup-github-pr" "sync" "version" "status")
|
|
||||||
for cmd in "${commands[@]}"; do
|
|
||||||
# Simple character similarity check
|
|
||||||
if [[ ${#input} -gt 2 && "$cmd" == *"$input"* ]]; then
|
|
||||||
suggestions+=("$cmd")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
if [[ ${#suggestions[@]} -gt 0 ]]; then
|
|
||||||
log_warning "Unknown command: '$input'"
|
|
||||||
echo ""
|
|
||||||
echo "Did you mean:"
|
|
||||||
for suggestion in "${suggestions[@]}"; do
|
|
||||||
echo " $0 $suggestion"
|
|
||||||
done
|
|
||||||
echo ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if feature branch exists and suggest next steps
|
|
||||||
check_feature_status() {
|
|
||||||
local feature_name="$1"
|
|
||||||
local branch_name="feature/$feature_name"
|
|
||||||
|
|
||||||
# Check if feature branch exists locally
|
|
||||||
if git branch | grep -q " $branch_name$"; then
|
|
||||||
log_info "Feature branch '$branch_name' exists locally"
|
|
||||||
|
|
||||||
# Check if it's been tested (merged to dev)
|
|
||||||
if git branch -r | grep -q "$GITEA_REMOTE/dev"; then
|
|
||||||
git fetch "$GITEA_REMOTE" dev >/dev/null 2>&1
|
|
||||||
if git merge-base --is-ancestor "$branch_name" "$GITEA_REMOTE/dev" 2>/dev/null; then
|
|
||||||
log_success "Feature has been tested on dev branch"
|
|
||||||
log_info "Next step: $0 release $feature_name [patch|minor|major]"
|
|
||||||
else
|
|
||||||
log_warning "Feature not yet tested on dev branch"
|
|
||||||
log_info "Next step: $0 test $feature_name"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if it's been released (merged to main)
|
|
||||||
if git branch -r | grep -q "$GITEA_REMOTE/main"; then
|
|
||||||
git fetch "$GITEA_REMOTE" main >/dev/null 2>&1
|
|
||||||
if git merge-base --is-ancestor "$branch_name" "$GITEA_REMOTE/main" 2>/dev/null; then
|
|
||||||
log_success "Feature has been released to Gitea main"
|
|
||||||
log_info "Next step: $0 github-pr $feature_name"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log_warning "Feature branch '$branch_name' does not exist"
|
|
||||||
log_info "Start with: $0 start $feature_name"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show current workflow state and suggest next action
|
|
||||||
show_workflow_guidance() {
|
|
||||||
log_info "🔄 Current Workflow State Analysis"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check for existing feature branches
|
|
||||||
local feature_branches=($(git branch | grep "feature/" | sed 's/^[* ]*//' | sed 's/feature\///'))
|
|
||||||
|
|
||||||
if [[ ${#feature_branches[@]} -eq 0 ]]; then
|
|
||||||
log_info "No active feature branches found"
|
|
||||||
log_info "Start a new feature: $0 start <feature-name>"
|
|
||||||
echo ""
|
|
||||||
echo "Example: $0 start user-dashboard"
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
log_info "Active feature branches:"
|
|
||||||
for feature in "${feature_branches[@]}"; do
|
|
||||||
echo " 📝 $feature"
|
|
||||||
check_feature_status "$feature"
|
|
||||||
echo ""
|
|
||||||
done
|
|
||||||
|
|
||||||
log_info "Quick reference:"
|
|
||||||
echo " $0 test <name> # Test feature on Gitea dev"
|
|
||||||
echo " $0 release <name> # Release to Gitea main"
|
|
||||||
echo " $0 github-pr <name> # Create GitHub PR workflow"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get current version
|
|
||||||
get_version() {
|
|
||||||
if [[ -f "$VERSION_FILE" ]]; then
|
|
||||||
cat "$VERSION_FILE" | tr -d '\n'
|
|
||||||
else
|
|
||||||
echo "1.0.0"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Bump version
|
|
||||||
bump_version() {
|
|
||||||
local current_version=$(get_version)
|
|
||||||
local version_type=$1
|
|
||||||
|
|
||||||
IFS='.' read -ra VERSION_PARTS <<< "$current_version"
|
|
||||||
local major=${VERSION_PARTS[0]}
|
|
||||||
local minor=${VERSION_PARTS[1]}
|
|
||||||
local patch=${VERSION_PARTS[2]}
|
|
||||||
|
|
||||||
case $version_type in
|
|
||||||
"patch"|"p")
|
|
||||||
patch=$((patch + 1))
|
|
||||||
;;
|
|
||||||
"minor"|"m")
|
|
||||||
minor=$((minor + 1))
|
|
||||||
patch=0
|
|
||||||
;;
|
|
||||||
"major"|"M")
|
|
||||||
major=$((major + 1))
|
|
||||||
minor=0
|
|
||||||
patch=0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
log_error "Invalid version type. Use: patch|p, minor|m, major|M"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
local new_version="$major.$minor.$patch"
|
|
||||||
echo "$new_version" > "$VERSION_FILE"
|
|
||||||
log_success "Version bumped: $current_version → $new_version"
|
|
||||||
echo "$new_version"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if working directory is clean
|
|
||||||
check_clean() {
|
|
||||||
if [[ -n $(git status --porcelain) ]]; then
|
|
||||||
log_error "Working directory not clean. Commit or stash changes first."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ensure we're on the right branch
|
|
||||||
ensure_branch() {
|
|
||||||
local target_branch=$1
|
|
||||||
local current_branch=$(git branch --show-current)
|
|
||||||
|
|
||||||
if [[ "$current_branch" != "$target_branch" ]]; then
|
|
||||||
log_info "Switching to $target_branch"
|
|
||||||
git checkout "$target_branch"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sync all branches to match a source
|
|
||||||
sync_all_branches() {
|
|
||||||
local source_remote=$1
|
|
||||||
local source_branch=$2
|
|
||||||
|
|
||||||
log_info "Syncing all branches to match $source_remote/$source_branch"
|
|
||||||
|
|
||||||
# Fetch all remotes
|
|
||||||
git fetch "$GITEA_REMOTE"
|
|
||||||
git fetch "$GITHUB_REMOTE"
|
|
||||||
|
|
||||||
# Reset local main to source
|
|
||||||
ensure_branch main
|
|
||||||
git reset --hard "$source_remote/$source_branch"
|
|
||||||
|
|
||||||
# Push to Gitea (includes .local and .gitea)
|
|
||||||
log_info "Pushing to Gitea main and dev..."
|
|
||||||
git push "$GITEA_REMOTE" main --force-with-lease
|
|
||||||
git push "$GITEA_REMOTE" main:dev --force-with-lease
|
|
||||||
|
|
||||||
# For GitHub: create clean branch without .local and .gitea AND without AI attribution
|
|
||||||
log_info "Creating GitHub-safe branch (excluding .local, .gitea, and AI attribution)..."
|
|
||||||
local temp_branch="github-sync-temp"
|
|
||||||
git checkout -b "$temp_branch"
|
|
||||||
|
|
||||||
# Remove private directories if they exist
|
|
||||||
if [[ -d ".local" ]]; then
|
|
||||||
git rm -rf .local --cached 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
if [[ -d ".gitea" ]]; then
|
|
||||||
git rm -rf .gitea --cached 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Commit the clean version for GitHub
|
|
||||||
if [[ -n $(git status --porcelain) ]]; then
|
|
||||||
git add .
|
|
||||||
git commit -m "sync: Clean version for GitHub (excludes private dev files)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Strip AI attribution AND fix author names from the entire branch history
|
|
||||||
log_info "Removing AI attribution and fixing author names..."
|
|
||||||
git filter-branch -f --env-filter '
|
|
||||||
# Fix author name/email for any commits by jskala or Claude
|
|
||||||
if [ "$GIT_AUTHOR_NAME" = "jskala" ] || [ "$GIT_AUTHOR_EMAIL" = "jskala@gmail.com" ] ||
|
|
||||||
[ "$GIT_AUTHOR_NAME" = "Claude" ] || [ "$GIT_AUTHOR_EMAIL" = "noreply@anthropic.com" ]; then
|
|
||||||
export GIT_AUTHOR_NAME="SBCrumb"
|
|
||||||
export GIT_AUTHOR_EMAIL="sbcrumb@kickthetree.com"
|
|
||||||
fi
|
|
||||||
# Fix committer name/email for any commits by jskala or Claude
|
|
||||||
if [ "$GIT_COMMITTER_NAME" = "jskala" ] || [ "$GIT_COMMITTER_EMAIL" = "jskala@gmail.com" ] ||
|
|
||||||
[ "$GIT_COMMITTER_NAME" = "Claude" ] || [ "$GIT_COMMITTER_EMAIL" = "noreply@anthropic.com" ]; then
|
|
||||||
export GIT_COMMITTER_NAME="SBCrumb"
|
|
||||||
export GIT_COMMITTER_EMAIL="sbcrumb@kickthetree.com"
|
|
||||||
fi
|
|
||||||
' --msg-filter '
|
|
||||||
# Remove Claude co-authorship lines from commit messages
|
|
||||||
sed "/Co-Authored-By: Claude/d" |
|
|
||||||
sed "/Generated with.*Claude/d" |
|
|
||||||
sed "/🤖 Generated with.*Claude/d" |
|
|
||||||
# Remove any other AI references
|
|
||||||
sed "/noreply@anthropic.com/d"
|
|
||||||
' -- "$temp_branch" 2>/dev/null || log_warning "Filter-branch may not be needed"
|
|
||||||
|
|
||||||
log_info "Pushing to GitHub main and dev..."
|
|
||||||
git push "$GITHUB_REMOTE" "$temp_branch:main" --force-with-lease
|
|
||||||
git push "$GITHUB_REMOTE" "$temp_branch:dev" --force-with-lease
|
|
||||||
|
|
||||||
# Clean up temp branch and return to main
|
|
||||||
git checkout main
|
|
||||||
git branch -D "$temp_branch"
|
|
||||||
|
|
||||||
log_success "All branches synchronized with privacy respected!"
|
|
||||||
log_warning "Note: .local and .gitea stay on Gitea only (as intended)"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Start feature development
|
|
||||||
start_feature() {
|
|
||||||
local feature_name=$1
|
|
||||||
|
|
||||||
if [[ -z "$feature_name" ]]; then
|
|
||||||
log_error "Feature name required"
|
|
||||||
echo ""
|
|
||||||
echo "Usage: $0 start <feature-name>"
|
|
||||||
echo ""
|
|
||||||
echo "Examples:"
|
|
||||||
echo " $0 start user-dashboard # Creates feature/user-dashboard"
|
|
||||||
echo " $0 start api-improvements # Creates feature/api-improvements"
|
|
||||||
echo " $0 start bug-fix-login # Creates feature/bug-fix-login"
|
|
||||||
echo ""
|
|
||||||
log_info "💡 Use descriptive names with hyphens (no spaces)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_clean
|
|
||||||
ensure_branch main
|
|
||||||
|
|
||||||
# Create feature branch
|
|
||||||
local branch_name="feature/$feature_name"
|
|
||||||
log_info "Creating feature branch: $branch_name"
|
|
||||||
git checkout -b "$branch_name"
|
|
||||||
|
|
||||||
log_success "Feature branch '$branch_name' created. Start coding!"
|
|
||||||
echo ""
|
|
||||||
log_info "🔄 Next steps in workflow:"
|
|
||||||
echo " 1. Make your changes and commit them"
|
|
||||||
echo " 2. When ready for testing: $0 test $feature_name"
|
|
||||||
echo " 3. After testing: $0 release $feature_name [patch|minor|major]"
|
|
||||||
echo " 4. For GitHub PR: $0 github-pr $feature_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Test feature (merge to dev)
|
|
||||||
test_feature() {
|
|
||||||
local feature_name=$1
|
|
||||||
|
|
||||||
if [[ -z "$feature_name" ]]; then
|
|
||||||
log_error "Feature name required"
|
|
||||||
echo "Usage: $0 test <feature-name>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_clean
|
|
||||||
local branch_name="feature/$feature_name"
|
|
||||||
|
|
||||||
# Merge to Gitea dev for testing
|
|
||||||
ensure_branch dev
|
|
||||||
git fetch "$GITEA_REMOTE"
|
|
||||||
git reset --hard "$GITEA_REMOTE/dev"
|
|
||||||
|
|
||||||
log_info "Merging $branch_name to dev for testing"
|
|
||||||
git merge "$branch_name" --no-ff -m "test: Merge $feature_name for local testing"
|
|
||||||
|
|
||||||
git push "$GITEA_REMOTE" dev
|
|
||||||
|
|
||||||
log_success "Feature merged to Gitea dev for testing"
|
|
||||||
echo ""
|
|
||||||
log_info "🧪 Testing Phase:"
|
|
||||||
echo " • Test your changes thoroughly on the dev environment"
|
|
||||||
echo " • Check logs, functionality, and integration"
|
|
||||||
echo " • When satisfied: $0 release $feature_name [patch|minor|major]"
|
|
||||||
echo ""
|
|
||||||
log_warning "💡 Remember: Once released to main, it goes to GitHub PR workflow"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Release feature (merge to Gitea main, then create GitHub PR workflow)
|
|
||||||
release_feature() {
|
|
||||||
local feature_name=$1
|
|
||||||
local version_type=${2:-"patch"}
|
|
||||||
|
|
||||||
if [[ -z "$feature_name" ]]; then
|
|
||||||
log_error "Feature name required"
|
|
||||||
echo "Usage: $0 release <feature-name> [patch|minor|major]"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_clean
|
|
||||||
|
|
||||||
# Bump version
|
|
||||||
local new_version=$(bump_version "$version_type")
|
|
||||||
|
|
||||||
# Merge to Gitea main
|
|
||||||
ensure_branch main
|
|
||||||
git fetch "$GITEA_REMOTE"
|
|
||||||
git reset --hard "$GITEA_REMOTE/main"
|
|
||||||
|
|
||||||
local branch_name="feature/$feature_name"
|
|
||||||
log_info "Merging $branch_name to Gitea main"
|
|
||||||
git merge "$branch_name" --no-ff -m "feat: $feature_name (v$new_version)"
|
|
||||||
|
|
||||||
# Push to Gitea main
|
|
||||||
git push "$GITEA_REMOTE" main
|
|
||||||
|
|
||||||
log_success "Feature '$feature_name' merged to Gitea main as v$new_version"
|
|
||||||
echo ""
|
|
||||||
log_info "🚀 Ready for GitHub PR Workflow!"
|
|
||||||
echo " Phase 1 (Gitea) Complete ✅"
|
|
||||||
echo ""
|
|
||||||
log_info "📋 Next steps:"
|
|
||||||
echo " 1. $0 github-pr $feature_name"
|
|
||||||
echo " 2. Go to GitHub → Create PR: github-feature/$feature_name → dev"
|
|
||||||
echo " 3. Test on GitHub dev environment"
|
|
||||||
echo " 4. Create PR: dev → main"
|
|
||||||
echo " 5. $0 cleanup-github-pr $feature_name"
|
|
||||||
echo ""
|
|
||||||
log_warning "💡 The github-pr command will automatically exclude .local/.gitea files"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create GitHub PR workflow branch
|
|
||||||
github_pr() {
|
|
||||||
local feature_name=$1
|
|
||||||
|
|
||||||
if [[ -z "$feature_name" ]]; then
|
|
||||||
log_error "Feature name required"
|
|
||||||
echo "Usage: $0 github-pr <feature-name>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
check_clean
|
|
||||||
|
|
||||||
# Create clean GitHub feature branch from current Gitea main
|
|
||||||
log_info "Creating GitHub PR workflow for feature: $feature_name"
|
|
||||||
|
|
||||||
ensure_branch main
|
|
||||||
git fetch "$GITEA_REMOTE"
|
|
||||||
git reset --hard "$GITEA_REMOTE/main"
|
|
||||||
|
|
||||||
# Create GitHub-safe feature branch
|
|
||||||
local github_branch="github-feature/$feature_name"
|
|
||||||
git checkout -b "$github_branch"
|
|
||||||
|
|
||||||
# Remove private directories for GitHub
|
|
||||||
if [[ -d ".local" ]]; then
|
|
||||||
git rm -rf .local --cached 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
if [[ -d ".gitea" ]]; then
|
|
||||||
git rm -rf .gitea --cached 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Commit clean version if changes exist
|
|
||||||
if [[ -n $(git status --porcelain) ]]; then
|
|
||||||
git add .
|
|
||||||
git commit -m "github: Clean feature branch for $feature_name PR workflow"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Apply privacy filters
|
|
||||||
log_info "Applying privacy filters..."
|
|
||||||
git filter-branch -f --env-filter '
|
|
||||||
if [ "$GIT_AUTHOR_NAME" = "jskala" ] || [ "$GIT_AUTHOR_EMAIL" = "jskala@gmail.com" ] ||
|
|
||||||
[ "$GIT_AUTHOR_NAME" = "Claude" ] || [ "$GIT_AUTHOR_EMAIL" = "noreply@anthropic.com" ]; then
|
|
||||||
export GIT_AUTHOR_NAME="SBCrumb"
|
|
||||||
export GIT_AUTHOR_EMAIL="sbcrumb@kickthetree.com"
|
|
||||||
fi
|
|
||||||
if [ "$GIT_COMMITTER_NAME" = "jskala" ] || [ "$GIT_COMMITTER_EMAIL" = "jskala@gmail.com" ] ||
|
|
||||||
[ "$GIT_COMMITTER_NAME" = "Claude" ] || [ "$GIT_COMMITTER_EMAIL" = "noreply@anthropic.com" ]; then
|
|
||||||
export GIT_COMMITTER_NAME="SBCrumb"
|
|
||||||
export GIT_COMMITTER_EMAIL="sbcrumb@kickthetree.com"
|
|
||||||
fi
|
|
||||||
' --msg-filter '
|
|
||||||
sed "/Co-Authored-By: Claude/d" |
|
|
||||||
sed "/Generated with.*Claude/d" |
|
|
||||||
sed "/🤖 Generated with.*Claude/d" |
|
|
||||||
sed "/noreply@anthropic.com/d"
|
|
||||||
' -- "$github_branch" 2>/dev/null || log_warning "Filter-branch may not be needed"
|
|
||||||
|
|
||||||
# Push feature branch to GitHub
|
|
||||||
git push "$GITHUB_REMOTE" "$github_branch" --force-with-lease
|
|
||||||
|
|
||||||
# Also update GitHub dev branch
|
|
||||||
git push "$GITHUB_REMOTE" "$github_branch:dev" --force-with-lease
|
|
||||||
|
|
||||||
log_success "GitHub feature branch created: $github_branch"
|
|
||||||
log_info "Next steps:"
|
|
||||||
log_info " 1. Go to GitHub and create PR: $github_branch → dev"
|
|
||||||
log_info " 2. Test the changes on github-dev"
|
|
||||||
log_info " 3. Create PR: dev → main"
|
|
||||||
log_info " 4. Run: $0 cleanup-github-pr $feature_name"
|
|
||||||
|
|
||||||
# Return to main and cleanup
|
|
||||||
git checkout main
|
|
||||||
git branch -D "$github_branch"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cleanup after GitHub PR workflow
|
|
||||||
cleanup_github_pr() {
|
|
||||||
local feature_name=$1
|
|
||||||
|
|
||||||
if [[ -z "$feature_name" ]]; then
|
|
||||||
log_error "Feature name required"
|
|
||||||
echo "Usage: $0 cleanup-github-pr <feature-name>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Cleanup local feature branch
|
|
||||||
local branch_name="feature/$feature_name"
|
|
||||||
git branch -d "$branch_name" 2>/dev/null || true
|
|
||||||
|
|
||||||
# Cleanup remote branches
|
|
||||||
git push "$GITEA_REMOTE" --delete "$branch_name" 2>/dev/null || true
|
|
||||||
git push "$GITHUB_REMOTE" --delete "github-feature/$feature_name" 2>/dev/null || true
|
|
||||||
|
|
||||||
log_success "Cleaned up feature branches for: $feature_name"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show status
|
|
||||||
show_status() {
|
|
||||||
log_info "Current Repository Status"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Current branch and version
|
|
||||||
local current_branch=$(git branch --show-current)
|
|
||||||
local current_version=$(get_version)
|
|
||||||
echo "📍 Current Branch: $current_branch"
|
|
||||||
echo "🔢 Current Version: $current_version"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Remote status
|
|
||||||
git fetch "$GITEA_REMOTE" >/dev/null 2>&1
|
|
||||||
git fetch "$GITHUB_REMOTE" >/dev/null 2>&1
|
|
||||||
|
|
||||||
echo "🔄 Branch Status:"
|
|
||||||
echo " Local main: $(git rev-parse --short main)"
|
|
||||||
echo " Gitea main: $(git rev-parse --short $GITEA_REMOTE/main)"
|
|
||||||
echo " Gitea dev: $(git rev-parse --short $GITEA_REMOTE/dev)"
|
|
||||||
echo " GitHub main: $(git rev-parse --short $GITHUB_REMOTE/main)"
|
|
||||||
echo " GitHub dev: $(git rev-parse --short $GITHUB_REMOTE/dev)"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Check if synchronized
|
|
||||||
local gitea_main=$(git rev-parse $GITEA_REMOTE/main)
|
|
||||||
local gitea_dev=$(git rev-parse $GITEA_REMOTE/dev)
|
|
||||||
local github_main=$(git rev-parse $GITHUB_REMOTE/main)
|
|
||||||
local github_dev=$(git rev-parse $GITHUB_REMOTE/dev)
|
|
||||||
|
|
||||||
if [[ "$gitea_main" == "$gitea_dev" && "$gitea_main" == "$github_main" && "$gitea_main" == "$github_dev" ]]; then
|
|
||||||
log_success "All branches are synchronized! ✨"
|
|
||||||
else
|
|
||||||
log_warning "Branches are not synchronized"
|
|
||||||
echo " Run: $0 sync to synchronize all branches"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
show_workflow_guidance
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main script logic
|
|
||||||
case "${1:-status}" in
|
|
||||||
"start")
|
|
||||||
start_feature "$2"
|
|
||||||
;;
|
|
||||||
"test")
|
|
||||||
test_feature "$2"
|
|
||||||
;;
|
|
||||||
"release")
|
|
||||||
release_feature "$2" "$3"
|
|
||||||
;;
|
|
||||||
"github-pr")
|
|
||||||
github_pr "$2"
|
|
||||||
;;
|
|
||||||
"cleanup-github-pr")
|
|
||||||
cleanup_github_pr "$2"
|
|
||||||
;;
|
|
||||||
"sync")
|
|
||||||
sync_all_branches "$GITEA_REMOTE" main
|
|
||||||
;;
|
|
||||||
"version")
|
|
||||||
if [[ -n "$2" ]]; then
|
|
||||||
bump_version "$2"
|
|
||||||
else
|
|
||||||
echo "Current version: $(get_version)"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
"status"|"")
|
|
||||||
show_status
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# Check if it's a typo or unknown command and suggest alternatives
|
|
||||||
suggest_command "$1"
|
|
||||||
|
|
||||||
echo "NFOGuard Development Sync Script"
|
|
||||||
echo ""
|
|
||||||
echo "Usage: $0 <command> [options]"
|
|
||||||
echo ""
|
|
||||||
log_info "Available Commands:"
|
|
||||||
echo " start <name> Create new feature branch"
|
|
||||||
echo " test <name> Merge feature to dev for testing"
|
|
||||||
echo " release <name> [type] Merge to Gitea main (patch|minor|major)"
|
|
||||||
echo " github-pr <name> Create GitHub PR workflow branch"
|
|
||||||
echo " cleanup-github-pr <name> Cleanup after GitHub PR workflow"
|
|
||||||
echo " sync Sync all branches to Gitea main"
|
|
||||||
echo " version [type] Show or bump version"
|
|
||||||
echo " status Show repository status (default)"
|
|
||||||
echo ""
|
|
||||||
log_info "Professional Git Workflow:"
|
|
||||||
echo " # 🔧 Gitea Development (Private)"
|
|
||||||
echo " $0 start user-auth # Create feature branch"
|
|
||||||
echo " # ... develop feature ..."
|
|
||||||
echo " $0 test user-auth # Test on Gitea dev"
|
|
||||||
echo " $0 release user-auth minor # Merge to Gitea main"
|
|
||||||
echo ""
|
|
||||||
echo " # 🚀 GitHub PR Workflow (Public)"
|
|
||||||
echo " $0 github-pr user-auth # Create clean GitHub branch"
|
|
||||||
echo " # Create PR: github-feature/user-auth → github-dev"
|
|
||||||
echo " # Test, then create PR: github-dev → github-main"
|
|
||||||
echo " $0 cleanup-github-pr user-auth # Cleanup branches"
|
|
||||||
echo ""
|
|
||||||
log_info "Common Aliases:"
|
|
||||||
echo " create, new, init → start"
|
|
||||||
echo " merge, pr, pull-request → github-pr"
|
|
||||||
echo " clean, cleanup, remove → cleanup-github-pr"
|
|
||||||
echo " check, info, show → status"
|
|
||||||
echo " push, deploy, publish → release"
|
|
||||||
echo " dev, develop → test"
|
|
||||||
echo ""
|
|
||||||
log_warning "💡 Tip: Run '$0 status' to see your current workflow state and next steps"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
# NFOGuard Development Workflow
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
NFOGuard uses a dual-repository system:
|
|
||||||
- **Gitea (Private)**: `origin` - Development, testing, messy commits
|
|
||||||
- **GitHub (Public)**: `github` - Clean releases, public testing
|
|
||||||
|
|
||||||
## Repository Setup
|
|
||||||
```bash
|
|
||||||
# Remotes should be configured as:
|
|
||||||
origin gitea@192.168.253.221:jskala/NFOguard.git (fetch/push)
|
|
||||||
github git@github.com:sbcrumb/nfoguard.git (fetch/push)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Daily Development Workflow
|
|
||||||
|
|
||||||
### 1. Local Development
|
|
||||||
```bash
|
|
||||||
# Work on dev branch (make as many commits as you want)
|
|
||||||
git checkout dev
|
|
||||||
# ... make changes, commit frequently ...
|
|
||||||
git add .
|
|
||||||
git commit -m "fix: whatever you're working on"
|
|
||||||
|
|
||||||
# Push to Gitea regularly for backup
|
|
||||||
git push origin dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Feature Complete - Merge to Main
|
|
||||||
```bash
|
|
||||||
# When feature/fix is complete, merge to main
|
|
||||||
git checkout main
|
|
||||||
git merge dev
|
|
||||||
|
|
||||||
# Push to Gitea main
|
|
||||||
git push origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Prepare for GitHub Release
|
|
||||||
|
|
||||||
**Use the sync script for clean releases:**
|
|
||||||
```bash
|
|
||||||
# From main branch, run the sync script
|
|
||||||
./sync-to-github.sh
|
|
||||||
|
|
||||||
# Choose Option 3: "Create clean release branch for GitHub PR (RECOMMENDED)"
|
|
||||||
# This will:
|
|
||||||
# 1. Increment version (patch/minor/major)
|
|
||||||
# 2. Create clean release-vX.X.X branch from GitHub main
|
|
||||||
# 3. Copy your changes with single clean commit
|
|
||||||
# 4. Push to GitHub automatically
|
|
||||||
```
|
|
||||||
|
|
||||||
**The script will output:**
|
|
||||||
```
|
|
||||||
🔗 Create PR at: https://github.com/sbcrumb/nfoguard/pull/new/release-v1.7.0
|
|
||||||
📝 PR will be: release-v1.7.0 → main (clean, single commit)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. GitHub Testing and Release
|
|
||||||
```bash
|
|
||||||
# 1. Create PR: release-vX.X.X → main on GitHub
|
|
||||||
# 2. Test the release branch thoroughly
|
|
||||||
# 3. Merge when satisfied (squash merge will be available)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Manual Process (If Script Unavailable)
|
|
||||||
|
|
||||||
### Emergency Manual Release
|
|
||||||
If the sync script isn't available, here's the manual process:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. Fetch latest GitHub main
|
|
||||||
git fetch github
|
|
||||||
|
|
||||||
# 2. Create clean release branch
|
|
||||||
git checkout -b release-v1.7.0 github/main
|
|
||||||
|
|
||||||
# 3. Copy key files from your local main
|
|
||||||
git checkout main -- VERSION Dockerfile core/nfo_manager.py nfoguard.py .env.template .env.secrets.template .gitea/
|
|
||||||
|
|
||||||
# 4. Increment version manually
|
|
||||||
echo "1.7.0" > VERSION
|
|
||||||
|
|
||||||
# 5. Commit and push
|
|
||||||
git add .
|
|
||||||
git commit -m "feat: Release v1.7.0 - [describe key changes]"
|
|
||||||
git push github release-v1.7.0
|
|
||||||
|
|
||||||
# 6. Create PR on GitHub: release-v1.7.0 → main
|
|
||||||
```
|
|
||||||
|
|
||||||
## Important Files and Their Purpose
|
|
||||||
|
|
||||||
### Local-Only Files (Never Commit to Gitea/GitHub)
|
|
||||||
- `sync-to-github.sh` - GitHub sync automation
|
|
||||||
- `.local/` directory - Local documentation and notes
|
|
||||||
- `.env.secrets` - API keys and passwords
|
|
||||||
|
|
||||||
### Repository-Specific Files
|
|
||||||
- `.gitea/workflows/` - Gitea CI/CD (ignored by GitHub)
|
|
||||||
- `.github/workflows/` - GitHub CI/CD (ignored by Gitea)
|
|
||||||
|
|
||||||
### Shared Files
|
|
||||||
- Core application code
|
|
||||||
- Dockerfile
|
|
||||||
- Configuration templates
|
|
||||||
- VERSION file
|
|
||||||
|
|
||||||
## Version Management
|
|
||||||
|
|
||||||
### Semantic Versioning
|
|
||||||
- **Patch (X.Y.Z+1)**: Bug fixes, small updates
|
|
||||||
- **Minor (X.Y+1.0)**: New features, enhancements
|
|
||||||
- **Major (X+1.0.0)**: Breaking changes, major releases
|
|
||||||
|
|
||||||
### Version Identification
|
|
||||||
- **Local Gitea builds**: `1.7.0-dev-gitea`
|
|
||||||
- **GitHub releases**: `1.7.0`
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### "Messy Commit History" in GitHub PRs
|
|
||||||
**Problem**: Local dev has 20+ commits that make GitHub PRs hard to review
|
|
||||||
**Solution**: Always use sync script Option 3 to create clean release branches
|
|
||||||
|
|
||||||
### "No Common History" Error
|
|
||||||
**Problem**: GitHub and local repos have different histories
|
|
||||||
**Solution**: Use the clean release branch workflow (creates branches from GitHub main)
|
|
||||||
|
|
||||||
### "Sync Script Not Working"
|
|
||||||
**Fallback**: Use the manual process outlined above
|
|
||||||
|
|
||||||
### Local Branch "Ahead by X Commits"
|
|
||||||
**Normal**: Your local dev is ahead of Gitea dev - just push when ready
|
|
||||||
```bash
|
|
||||||
git push origin dev # Sync to Gitea
|
|
||||||
```
|
|
||||||
|
|
||||||
## Branch Strategy
|
|
||||||
|
|
||||||
### Local Branches
|
|
||||||
- `dev` - Active development (tracks origin/dev)
|
|
||||||
- `main` - Stable local code (tracks origin/main)
|
|
||||||
|
|
||||||
### GitHub Branches
|
|
||||||
- `release-vX.X.X` - Clean release branches (created by sync script)
|
|
||||||
- `main` - Public stable releases
|
|
||||||
- `dev` - Optional testing branch
|
|
||||||
|
|
||||||
### Gitea Branches
|
|
||||||
- `dev` - Development history (all commits)
|
|
||||||
- `main` - Feature-complete code (merged from dev)
|
|
||||||
|
|
||||||
## CI/CD Behavior
|
|
||||||
|
|
||||||
### Gitea Workflows
|
|
||||||
- Build locally only (no Docker Hub)
|
|
||||||
- Version shows as "X.X.X-dev-gitea"
|
|
||||||
- Triggered on dev/main pushes
|
|
||||||
|
|
||||||
### GitHub Workflows
|
|
||||||
- Build to GitHub Container Registry
|
|
||||||
- Version shows as "X.X.X" (clean)
|
|
||||||
- Triggered on main pushes
|
|
||||||
|
|
||||||
## Emergency Procedures
|
|
||||||
|
|
||||||
### If Sync Script is Lost
|
|
||||||
1. Recreate from this workflow document
|
|
||||||
2. Use manual process for immediate needs
|
|
||||||
3. Script should be in `.local/` directory and ignored by git
|
|
||||||
|
|
||||||
### If GitHub Repo Gets Corrupted
|
|
||||||
1. Force push clean main from Gitea
|
|
||||||
2. Recreate release branches as needed
|
|
||||||
3. Your code is safe in Gitea
|
|
||||||
|
|
||||||
### If Gitea Goes Down
|
|
||||||
1. Continue development locally
|
|
||||||
2. Push to GitHub dev branch for backup
|
|
||||||
3. Sync back to Gitea when restored
|
|
||||||
|
|
||||||
## Success Indicators
|
|
||||||
|
|
||||||
### Good Workflow Signs
|
|
||||||
- ✅ GitHub PRs have 1-3 clean commits
|
|
||||||
- ✅ Local history is detailed and preserved
|
|
||||||
- ✅ Version numbers increment properly
|
|
||||||
- ✅ CI/CD builds succeed on both platforms
|
|
||||||
|
|
||||||
### Warning Signs
|
|
||||||
- ❌ GitHub PRs have 20+ messy commits
|
|
||||||
- ❌ "No common history" errors
|
|
||||||
- ❌ Version numbers out of sync
|
|
||||||
- ❌ Sync script getting committed to repos
|
|
||||||
|
|
||||||
## Quick Reference Commands
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Daily development
|
|
||||||
git checkout dev && git pull origin dev
|
|
||||||
# ... work ...
|
|
||||||
git add . && git commit -m "fix: description"
|
|
||||||
git push origin dev
|
|
||||||
|
|
||||||
# Complete feature
|
|
||||||
git checkout main && git merge dev && git push origin main
|
|
||||||
|
|
||||||
# Release to GitHub
|
|
||||||
./sync-to-github.sh # Choose option 3
|
|
||||||
|
|
||||||
# Check status
|
|
||||||
git status
|
|
||||||
git log --oneline -5
|
|
||||||
git remote -v
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Remember**: The sync script Option 3 is your best friend for clean GitHub releases!
|
|
||||||
Reference in New Issue
Block a user