#!/usr/bin/env bash set -euo pipefail # pipelines/gitea/setup.sh — Automate Gitea initial setup via REST API # # Steps: # 1. Create admin user (idempotent — skip if already exists) # 2. Create OAuth2 application for Woodpecker CI (idempotent — reuse if exists) # 3. Create stonks-oracle repository (idempotent — skip if already exists) # # Outputs OAuth2 client_id and client_secret to stdout and to # gitea-oauth2.env (sourceable by runmefirst.sh). # # Requirements: 1.1, 1.2, 1.5, 2.3 # ------------------------------------------------------- # Configuration (override via environment variables) # ------------------------------------------------------- GITEA_URL="${GITEA_URL:-http://10.1.1.12:30300}" GITEA_ADMIN_USER="${GITEA_ADMIN_USER:-admin}" GITEA_ADMIN_PASSWORD="${GITEA_ADMIN_PASSWORD:-St0nks0racl3!}" GITEA_ADMIN_EMAIL="${GITEA_ADMIN_EMAIL:-admin@celestium.life}" OAUTH2_APP_NAME="woodpecker-ci" OAUTH2_REDIRECT_URI="https://stonks-ci.celestium.life/authorize" REPO_NAME="stonks-oracle" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" OAUTH2_ENV_FILE="${SCRIPT_DIR}/gitea-oauth2.env" API="${GITEA_URL}/api/v1" AUTH_HEADER="Authorization: Basic $(echo -n "${GITEA_ADMIN_USER}:${GITEA_ADMIN_PASSWORD}" | base64)" echo "=== Gitea Setup ===" echo " URL: ${GITEA_URL}" echo " Admin user: ${GITEA_ADMIN_USER}" echo "" # ------------------------------------------------------- # Helper: wait for Gitea to be reachable # (Gitea returns 404 on /api/v1/version when on install page, so check root) # ------------------------------------------------------- echo "--- Waiting for Gitea to be reachable ---" for i in $(seq 1 30); do HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "${GITEA_URL}/" 2>/dev/null || echo "000") if [ "$HTTP_STATUS" != "000" ]; then echo " ✓ Gitea is reachable (HTTP ${HTTP_STATUS})" break fi if [ "$i" -eq 30 ]; then echo " ✗ Gitea not reachable after 30 attempts" exit 1 fi echo " Attempt ${i}/30 — waiting 5s..." sleep 5 done echo "" # ------------------------------------------------------- # Step 1: Create admin user # ------------------------------------------------------- echo "--- Step 1: Create admin user ---" # Check if admin user already exists by attempting to query the API with credentials HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 \ -H "${AUTH_HEADER}" \ "${API}/user") if [ "$HTTP_CODE" = "200" ]; then echo " ✓ Admin user '${GITEA_ADMIN_USER}' already exists and credentials are valid" elif [ "$HTTP_CODE" = "404" ]; then # Gitea is on the install page — API not available yet echo " Gitea API not available (install page) — completing initial setup..." INSTALL_RESPONSE=$(curl -s -w "\n%{http_code}" \ -X POST "${GITEA_URL}/" \ -H "Content-Type: application/x-www-form-urlencoded" \ --data-urlencode "db_type=sqlite3" \ --data-urlencode "db_host=localhost:3306" \ --data-urlencode "db_user=root" \ --data-urlencode "db_passwd=" \ --data-urlencode "db_name=gitea" \ --data-urlencode "ssl_mode=disable" \ --data-urlencode "db_path=/data/gitea/gitea.db" \ --data-urlencode "app_name=Gitea: Git with a cup of tea" \ --data-urlencode "repo_root_path=/data/git/repositories" \ --data-urlencode "lfs_root_path=/data/git/lfs" \ --data-urlencode "run_user=git" \ --data-urlencode "domain=git.celestium.life" \ --data-urlencode "ssh_port=22" \ --data-urlencode "http_port=3000" \ --data-urlencode "app_url=https://git.celestium.life/" \ --data-urlencode "log_root_path=/data/gitea/log" \ --data-urlencode "admin_name=${GITEA_ADMIN_USER}" \ --data-urlencode "admin_passwd=${GITEA_ADMIN_PASSWORD}" \ --data-urlencode "admin_confirm_passwd=${GITEA_ADMIN_PASSWORD}" \ --data-urlencode "admin_email=${GITEA_ADMIN_EMAIL}") INSTALL_CODE=$(echo "$INSTALL_RESPONSE" | tail -n 1) if [ "$INSTALL_CODE" = "200" ] || [ "$INSTALL_CODE" = "302" ]; then echo " ✓ Gitea initial install completed with admin user" # Gitea restarts after install — wait for API to become available echo " Waiting for Gitea API to become available after install..." for j in $(seq 1 30); do API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "${API}/version" 2>/dev/null || echo "000") if [ "$API_STATUS" = "200" ]; then echo " ✓ Gitea API is ready" break fi if [ "$j" -eq 30 ]; then echo " ✗ Gitea API not available after install (waited 150s)" exit 1 fi sleep 5 done else echo " ✗ Install wizard returned HTTP ${INSTALL_CODE}" echo " Response: $(echo "$INSTALL_RESPONSE" | head -n -1 | tail -5)" exit 1 fi else echo " Admin user not found or credentials invalid — creating via admin API..." # Try creating the user via Gitea's admin create-user API # This works when Gitea has been initialized but no admin user exists, # or when using the built-in admin creation endpoint RESPONSE=$(curl -s -w "\n%{http_code}" \ -X POST "${API}/admin/users" \ -H "Content-Type: application/json" \ -H "${AUTH_HEADER}" \ -d "{ \"username\": \"${GITEA_ADMIN_USER}\", \"password\": \"${GITEA_ADMIN_PASSWORD}\", \"email\": \"${GITEA_ADMIN_EMAIL}\", \"must_change_password\": false, \"login_name\": \"${GITEA_ADMIN_USER}\", \"source_id\": 0, \"visibility\": \"public\" }") BODY=$(echo "$RESPONSE" | head -n -1) CODE=$(echo "$RESPONSE" | tail -n 1) if [ "$CODE" = "201" ]; then echo " ✓ Admin user '${GITEA_ADMIN_USER}' created" elif [ "$CODE" = "422" ]; then echo " ✓ Admin user '${GITEA_ADMIN_USER}' already exists (422)" else echo " ✗ Unexpected response creating admin user: HTTP ${CODE}" echo " Response: ${BODY}" exit 1 fi fi echo "" # ------------------------------------------------------- # Step 2: Create OAuth2 application for Woodpecker CI # ------------------------------------------------------- echo "--- Step 2: Create OAuth2 application '${OAUTH2_APP_NAME}' ---" # Check if the OAuth2 app already exists EXISTING_APPS=$(curl -s \ -H "${AUTH_HEADER}" \ "${API}/user/applications/oauth2") EXISTING_APP=$(echo "$EXISTING_APPS" | python3 -c " import sys, json apps = json.load(sys.stdin) for app in apps: if app.get('name') == '${OAUTH2_APP_NAME}': print(json.dumps(app)) break " 2>/dev/null || echo "") if [ -n "$EXISTING_APP" ]; then echo " ✓ OAuth2 app '${OAUTH2_APP_NAME}' already exists" OAUTH2_CLIENT_ID=$(echo "$EXISTING_APP" | python3 -c "import sys,json; print(json.load(sys.stdin)['client_id'])") # Note: Gitea does not return client_secret for existing apps. # If we need the secret, we must delete and recreate. OAUTH2_CLIENT_SECRET=$(echo "$EXISTING_APP" | python3 -c " import sys, json data = json.load(sys.stdin) print(data.get('client_secret', '')) " 2>/dev/null || echo "") if [ -z "$OAUTH2_CLIENT_SECRET" ]; then echo " ✓ OAuth2 app exists, secret stored in Woodpecker DB (not recreating)" # Write client_id only — secret is only available on first creation cat > "${OAUTH2_ENV_FILE}" < "${OAUTH2_ENV_FILE}" <