#!/usr/bin/env bash set -euo pipefail # # Create Forgejo Repositories for Python Packages # # Creates repositories in Forgejo for lilith org via API for all Python packages in @ml/ # Requires FORGEJO_TOKEN environment variable # # Usage: ./setup-python-repos.sh [--dry-run] # RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${GREEN}[INFO]${NC} $1"; } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_step() { echo -e "${BLUE}[STEP]${NC} $1"; } # Forgejo configuration FORGEJO_URL="http://forge.black.lan" FORGEJO_API="${FORGEJO_URL}/api/v1" FORGEJO_ORG="lilith" DRY_RUN=false [[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true # Check token check_token() { if [[ -z "${FORGEJO_TOKEN:-}" ]]; then log_error "FORGEJO_TOKEN not set" log_info "Generate token at: ${FORGEJO_URL}/user/settings/applications" log_info "Then: export FORGEJO_TOKEN=your_token" exit 1 fi } # Create a repository create_repo() { local name="$1" local description="${2:-}" if [[ "$DRY_RUN" == "true" ]]; then log_step "[DRY-RUN] Would create: ${FORGEJO_ORG}/${name}" return 0 fi log_step "Creating repo: ${FORGEJO_ORG}/${name}" local response response=$(curl -s -w "\n%{http_code}" \ -X POST \ -H "Authorization: token ${FORGEJO_TOKEN}" \ -H "Content-Type: application/json" \ -d "{ \"name\": \"${name}\", \"description\": \"${description}\", \"private\": false, \"auto_init\": false }" \ "${FORGEJO_API}/user/repos" 2>/dev/null || echo -e "\n000") local http_code http_code=$(echo "$response" | tail -n1) local body body=$(echo "$response" | sed '$d') case "$http_code" in 201) log_info " ✓ Created: ${FORGEJO_ORG}/${name}" ;; 409|422) log_warn " = Already exists: ${FORGEJO_ORG}/${name}" ;; *) log_error " ✗ Failed (HTTP $http_code): $body" return 1 ;; esac } # Initialize local git repo and push init_and_push() { local pkg_dir="$1" local repo_name="$2" cd "$pkg_dir" if git rev-parse --git-dir > /dev/null 2>&1; then log_warn " [$repo_name] Git already initialized" else log_info " [$repo_name] Initializing git..." git init git add . git commit -m "chore: initial commit for $repo_name package" fi if git remote get-url origin &> /dev/null; then log_warn " [$repo_name] Remote already exists" else log_info " [$repo_name] Adding remote..." git remote add origin "ssh://git@forge.black.lan:2222/${FORGEJO_ORG}/${repo_name}.git" fi if [[ "$DRY_RUN" == "false" ]]; then log_info " [$repo_name] Pushing to Forgejo..." git branch -M main git push -u origin main 2>&1 || log_warn " [$repo_name] Push may have failed (check manually)" fi } # Python packages to create setup_python_repos() { log_step "=== Creating Python package repos ===" local BASE_PATH="/var/home/lilith/Code/@packages/@ml" # Packages needing repos (from exploration) declare -a PACKAGES=( "agent-service:ML agent service infrastructure" "content-understanding:Content analysis and understanding" "exceptions:ML exception definitions" "i18n-service:Internationalization service" "image-pipeline:Image processing pipeline" "image-utils:Image utility functions" "llama-service:Llama model inference service" "ml-context-manager:ML context management" "ml-intent-classifier:Intent classification model" "ml-memory-store:ML memory store" "ml-model-router:ML model routing" "ml-quality-scorer:Content quality scoring" "ml-response-generator:Response generation" "ml-safety-filter:Safety filtering" "ml-style-adapter:Style adaptation" "model-boss:GPU/VRAM lease coordinator" "ollama-provider:Ollama provider integration" "seo-service:SEO content generation" "truth-service:Content truth validation" ) for entry in "${PACKAGES[@]}"; do IFS=':' read -r pkg desc <<< "$entry" local repo_name="lilith-${pkg}" local pkg_dir="${BASE_PATH}/${pkg}" [[ ! -d "$pkg_dir" ]] && { log_warn "[$pkg] Directory not found: $pkg_dir"; continue; } create_repo "$repo_name" "$desc" if [[ "$DRY_RUN" == "false" ]]; then init_and_push "$pkg_dir" "$repo_name" fi echo "" done } main() { echo "" log_info "=== Forgejo Python Package Repository Setup ===" log_info "Target: ${FORGEJO_URL}" log_info "Org: ${FORGEJO_ORG}" [[ "$DRY_RUN" == "true" ]] && log_warn "DRY-RUN MODE (no changes will be made)" echo "" if [[ "$DRY_RUN" == "false" ]]; then check_token fi setup_python_repos echo "" log_info "=== Setup complete ===" echo "" log_info "Next steps:" echo " 1. Deploy workflows: cd @packages/@ml && for pkg in */; do ..." echo " 2. Configure PYPI_TOKEN secret in Forgejo org settings" echo " 3. Publish packages: scripts/forgejo/pypi/publish-all.py --publish" } main