Files
aiworker/GITEA-GUIDE.md
Hector Ros db71705842 Complete documentation for future sessions
- CLAUDE.md for AI agents to understand the codebase
- GITEA-GUIDE.md centralizes all Gitea operations (API, Registry, Auth)
- DEVELOPMENT-WORKFLOW.md explains complete dev process
- ROADMAP.md, NEXT-SESSION.md for planning
- QUICK-REFERENCE.md, TROUBLESHOOTING.md for daily use
- 40+ detailed docs in /docs folder
- Backend as submodule from Gitea

Everything documented for autonomous operation.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
2026-01-20 00:37:19 +01:00

17 KiB

📚 Gitea - Guía Completa de Uso

Toda la información de Gitea en un solo lugar: autenticación, API, registry, webhooks, y CI/CD.


🌐 Acceso Web

URL: https://git.fuq.tv

Credenciales Admin:

  • Usuario: admin
  • Password: admin123

Primera vez: Ya configurado, listo para usar.


🔑 Autenticación y Tokens

Tokens Existentes

Nombre Token Scopes Uso
full-access 159a5de2a16d15f33e388b55b1276e431dbca3f3 all API completa
docker-registry 7401126cfb56ab2aebba17755bdc968c20768c27 write:package, read:package Container registry

Crear Nuevo Token (CLI)

# Desde el pod de Gitea
kubectl exec -n gitea gitea-0 -- su git -c "gitea admin user generate-access-token \
  --username admin \
  --scopes all \
  --token-name my-token \
  --raw"

Crear Token (Web UI)

  1. Login en https://git.fuq.tv
  2. Perfil → Settings → Applications
  3. Generate New Token
  4. Seleccionar scopes necesarios
  5. Copiar token (solo se muestra una vez)

Scopes importantes:

  • write:repository - Crear repos, push
  • write:package - Push imágenes Docker
  • read:package - Pull imágenes Docker
  • write:issue - Gestionar issues
  • write:user - Operaciones de usuario
  • all - Acceso completo

🐳 Container Registry

Configuración

Registry URL: git.fuq.tv Formato de imágenes: git.fuq.tv/<owner>/<package>:<tag>

Login Docker

# Con token de registry
docker login git.fuq.tv -u admin -p 7401126cfb56ab2aebba17755bdc968c20768c27

# O de forma segura
echo "7401126cfb56ab2aebba17755bdc968c20768c27" | docker login git.fuq.tv -u admin --password-stdin

Build y Push

# Build
docker build -t git.fuq.tv/admin/aiworker-backend:v1.0.0 .

# Push
docker push git.fuq.tv/admin/aiworker-backend:v1.0.0

# Tag como latest
docker tag git.fuq.tv/admin/aiworker-backend:v1.0.0 git.fuq.tv/admin/aiworker-backend:latest
docker push git.fuq.tv/admin/aiworker-backend:latest

Pull

docker pull git.fuq.tv/admin/aiworker-backend:latest

Ver Imágenes (UI)

  1. https://git.fuq.tv
  2. Perfil → Packages
  3. O: https://git.fuq.tv/admin/-/packages

Kubernetes Pull Secret

Ya creado en namespaces control-plane y agents:

# Verificar
kubectl get secret gitea-registry -n control-plane

# Crear en nuevo namespace
kubectl create secret docker-registry gitea-registry \
  --docker-server=git.fuq.tv \
  --docker-username=admin \
  --docker-password=7401126cfb56ab2aebba17755bdc968c20768c27 \
  --docker-email=hector@teamsuqad.io \
  -n <namespace>

Uso en deployment:

spec:
  template:
    spec:
      imagePullSecrets:
      - name: gitea-registry
      containers:
      - name: app
        image: git.fuq.tv/admin/myapp:latest

🔌 API de Gitea

Base URL: https://git.fuq.tv/api/v1 Documentación: https://git.fuq.tv/api/swagger

Autenticación API

Header:

Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3

Ejemplos de Uso

Crear Repositorio

curl -X POST "https://git.fuq.tv/api/v1/user/repos" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-new-repo",
    "description": "My description",
    "private": false,
    "auto_init": true
  }'

Listar Repositorios

curl "https://git.fuq.tv/api/v1/user/repos" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3"

Crear Branch

curl -X POST "https://git.fuq.tv/api/v1/repos/admin/myrepo/branches" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "new_branch_name": "feature-x",
    "old_branch_name": "main"
  }'

Crear Pull Request

curl -X POST "https://git.fuq.tv/api/v1/repos/admin/myrepo/pulls" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My PR",
    "body": "Description",
    "head": "feature-x",
    "base": "main"
  }'

Merge Pull Request

curl -X POST "https://git.fuq.tv/api/v1/repos/admin/myrepo/pulls/1/merge" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "Do": "merge",
    "merge_when_checks_succeed": false
  }'

Cliente TypeScript (Backend)

Ubicación: backend/src/services/gitea/client.ts

Uso:

import { GiteaClient } from './services/gitea/client'

const gitea = new GiteaClient({
  url: 'https://git.fuq.tv',
  token: process.env.GITEA_TOKEN,
  owner: 'admin'
})

// Crear repo
const repo = await gitea.createRepo('my-app', {
  description: 'My application',
  private: false,
  autoInit: true
})

// Crear branch
await gitea.createBranch('admin', 'my-app', 'feature-auth', 'main')

// Crear PR
const pr = await gitea.createPullRequest('admin', 'my-app', {
  title: 'Add authentication',
  body: 'Implements JWT auth',
  head: 'feature-auth',
  base: 'main'
})

Referencia completa: docs/02-backend/gitea-integration.md


🪝 Webhooks

Configurar Webhook (API)

curl -X POST "https://git.fuq.tv/api/v1/repos/admin/myrepo/hooks" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "gitea",
    "config": {
      "url": "https://api.fuq.tv/api/webhooks/gitea",
      "content_type": "json",
      "secret": "webhook-secret-123"
    },
    "events": ["push", "pull_request"],
    "active": true
  }'

Handler Backend

// backend/src/api/routes/webhooks.ts
export async function handleGiteaWebhook(req: Request) {
  const signature = req.headers.get('x-gitea-signature')
  const event = req.headers.get('x-gitea-event')
  const payload = await req.json()

  // Verify signature
  // ... verification logic

  switch (event) {
    case 'push':
      await handlePushEvent(payload)
      break
    case 'pull_request':
      await handlePREvent(payload)
      break
  }

  return Response.json({ success: true })
}

Eventos importantes:

  • push - Nuevo commit
  • pull_request - PR creado/actualizado
  • pull_request_closed - PR cerrado/mergeado

🔄 Gitea Actions (CI/CD)

Workflow File

Ubicación: .gitea/workflows/<name>.yml

Ejemplo (Build Docker image):

name: Build and Push

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Build image
        run: docker build -t git.fuq.tv/admin/myapp:latest .

      - name: Login to registry
        run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login git.fuq.tv -u admin --password-stdin

      - name: Push image
        run: docker push git.fuq.tv/admin/myapp:latest

Secrets en Repositorio

Crear secret (API):

curl -X PUT "https://git.fuq.tv/api/v1/repos/admin/myrepo/actions/secrets/MY_SECRET" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{"data":"my-secret-value"}'

Crear secret (Web UI):

  1. Repo → Settings → Secrets → Actions
  2. Add Secret
  3. Name: REGISTRY_TOKEN
  4. Value: 7401126cfb56ab2aebba17755bdc968c20768c27

Uso en workflow:

- name: Use secret
  run: echo "${{ secrets.REGISTRY_TOKEN }}"

Ver Workflows

UI: https://git.fuq.tv/admin//actions

Runner logs (K8s):

kubectl logs -n gitea-actions deployment/gitea-runner -c runner --tail=100

Runner Status

Verificar runner activo:

kubectl get pods -n gitea-actions

# Logs
kubectl logs -n gitea-actions deployment/gitea-runner -c runner

# Restart si es necesario
kubectl rollout restart deployment/gitea-runner -n gitea-actions

Ver en UI: https://git.fuq.tv/admin/runners


👥 Gestión de Usuarios

Crear Usuario (CLI)

kubectl exec -n gitea gitea-0 -- su git -c "gitea admin user create \
  --username myuser \
  --password mypass123 \
  --email user@example.com \
  --admin"

Cambiar Password

kubectl exec -n gitea gitea-0 -- su git -c "gitea admin user change-password \
  --username admin \
  --password newpassword"

Listar Usuarios

kubectl exec -n gitea gitea-0 -- su git -c "gitea admin user list"

📂 Organizaciones

Crear Organización (API)

curl -X POST "https://git.fuq.tv/api/v1/orgs" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "aiworker",
    "full_name": "AiWorker Organization",
    "description": "AiWorker platform repos"
  }'

Crear Repo en Organización

curl -X POST "https://git.fuq.tv/api/v1/org/aiworker/repos" \
  -H "Authorization: token 159a5de2a16d15f33e388b55b1276e431dbca3f3" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "auto_init": true
  }'

🔧 Configuración de Gitea

Ver Configuración Actual

kubectl exec -n gitea gitea-0 -- cat /data/gitea/conf/app.ini

Configuración Importante

Database:

[database]
DB_TYPE = mysql
HOST = mariadb.control-plane.svc.cluster.local:3306
NAME = gitea
USER = root
PASSWD = AiWorker2026_RootPass!

Server:

[server]
DOMAIN = git.fuq.tv
ROOT_URL = https://git.fuq.tv/
HTTP_PORT = 3000
SSH_PORT = 2222

Packages (Container Registry):

[packages]
ENABLED = true

Restart Gitea

kubectl delete pod gitea-0 -n gitea
# Esperar a que se recree automáticamente

🔐 SSH Access a Repos

SSH URL Format

ssh://git@git.fuq.tv:2222/<owner>/<repo>.git

SSH Clone

# Nota: Puerto 2222, no 22
git clone ssh://git@git.fuq.tv:2222/admin/aiworker-backend.git

Agregar SSH Key (UI)

  1. Login → Settings → SSH/GPG Keys
  2. Add Key
  3. Paste public key

Agregar SSH Key (CLI)

# Generar key
ssh-keygen -t ed25519 -C "agent@aiworker.dev" -f ~/.ssh/gitea_key

# Agregar a Gitea (manual en UI o via API)

🎬 Gitea Actions - Guía Completa

Runner en K8s

Namespace: gitea-actions Pod: gitea-runner-*

Status:

kubectl get pods -n gitea-actions
kubectl logs -n gitea-actions deployment/gitea-runner -c runner

Workflow Syntax

Compatible con GitHub Actions. Ubicación: .gitea/workflows/*.yml

Triggers:

on:
  push:
    branches: [main, develop]
    tags: ['v*']
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 0 * * *'  # Diario

Jobs:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run script
        run: echo "Hello"

Actions Disponibles

Compatible con GitHub Actions marketplace:

  • actions/checkout@v4
  • docker/build-push-action@v5
  • docker/login-action@v3
  • Y muchas más

Secrets en Actions

Acceso:

- name: Use secret
  run: echo "${{ secrets.MY_SECRET }}"
  env:
    API_KEY: ${{ secrets.API_KEY }}

Secrets necesarios para builds:

  • REGISTRY_TOKEN - Ya configurado en aiworker-backend

Variables de Entorno Automáticas

${{ github.repository }}      # admin/aiworker-backend
${{ github.sha }}              # Commit hash
${{ github.ref }}              # refs/heads/main
${{ github.actor }}            # Usuario que hizo push
${{ github.event_name }}       # push, pull_request, etc.

Debug de Workflows

# Ver en UI
https://git.fuq.tv/admin/<repo>/actions/runs/<run-id>

# Ver runner logs
kubectl logs -n gitea-actions deployment/gitea-runner -c runner --tail=200

# Ver Docker daemon logs
kubectl logs -n gitea-actions deployment/gitea-runner -c dind --tail=50

🛠️ Operaciones Comunes desde Backend

Inicializar Proyecto Nuevo

// 1. Crear repo en Gitea
const repo = await giteaClient.createRepo('my-project', {
  description: 'Project description',
  autoInit: true
})

// 2. Setup webhooks
await giteaClient.createWebhook('admin', 'my-project', {
  url: 'https://api.fuq.tv/api/webhooks/gitea',
  events: ['push', 'pull_request']
})

// 3. Guardar en DB
await db.insert(projects).values({
  id: crypto.randomUUID(),
  name: 'my-project',
  giteaRepoUrl: repo.clone_url,
  giteaOwner: 'admin',
  giteaRepoName: 'my-project'
})

Workflow de Tarea Completa

// 1. Obtener tarea
const task = await db.query.tasks.findFirst({
  where: eq(tasks.state, 'backlog')
})

// 2. Crear branch para tarea
await giteaClient.createBranch(
  project.giteaOwner,
  project.giteaRepoName,
  `task-${task.id}`,
  'main'
)

// 3. Agente trabaja (commits via git)...

// 4. Crear PR
const pr = await giteaClient.createPullRequest(
  project.giteaOwner,
  project.giteaRepoName,
  {
    title: task.title,
    body: task.description,
    head: `task-${task.id}`,
    base: 'main'
  }
)

// 5. Guardar PR URL
await db.update(tasks)
  .set({ prUrl: pr.html_url })
  .where(eq(tasks.id, task.id))

Merge Automático

await giteaClient.mergePullRequest(
  'admin',
  'my-project',
  prNumber,
  'squash'  // o 'merge', 'rebase'
)

🗂️ Estructura de Archivos en Gitea

En el Pod

# Datos de Gitea
/data/gitea/
├── conf/app.ini        # Configuración
├── log/                # Logs
├── git/repositories/   # Repos Git
├── git/lfs/            # Git LFS
├── packages/           # Container registry
└── attachments/        # Uploads

# Ejecutable
/usr/local/bin/gitea

Comandos CLI de Gitea

# Todos los comandos deben ejecutarse como usuario 'git'
kubectl exec -n gitea gitea-0 -- su git -c "gitea <command>"

# Ejemplos:
gitea admin user list
gitea admin user create --username x --password y --email z
gitea admin regenerate keys
gitea dump  # Backup completo

📊 Monitoring y Maintenance

Logs de Gitea

# Logs del contenedor
kubectl logs -n gitea gitea-0 --tail=100 -f

# Logs de aplicación (dentro del pod)
kubectl exec -n gitea gitea-0 -- tail -f /data/gitea/log/gitea.log

Health Check

# HTTP health
curl https://git.fuq.tv/api/healthz

# Database connection
kubectl exec -n gitea gitea-0 -- su git -c "gitea doctor check --run"

Backup

# Backup completo (crea archivo .zip)
kubectl exec -n gitea gitea-0 -- su git -c "gitea dump -f /tmp/gitea-backup.zip"

# Copiar backup fuera
kubectl cp gitea/gitea-0:/tmp/gitea-backup.zip ./gitea-backup-$(date +%Y%m%d).zip

Storage

PVC: 50Gi con Longhorn (3 réplicas HA)

# Ver PVC
kubectl get pvc -n gitea

# Ver volumen Longhorn
kubectl get volumes.longhorn.io -n longhorn-system | grep gitea

# Ver réplicas
kubectl get replicas.longhorn.io -n longhorn-system | grep $(kubectl get pvc -n gitea gitea-data -o jsonpath='{.spec.volumeName}')

🚀 Quick Actions

Crear Proyecto Completo (Script)

#!/bin/bash
PROJECT_NAME="my-project"
TOKEN="159a5de2a16d15f33e388b55b1276e431dbca3f3"

# 1. Crear repo
curl -X POST "https://git.fuq.tv/api/v1/user/repos" \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"$PROJECT_NAME\",\"auto_init\":true}"

# 2. Crear webhook
curl -X POST "https://git.fuq.tv/api/v1/repos/admin/$PROJECT_NAME/hooks" \
  -H "Authorization: token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"gitea","config":{"url":"https://api.fuq.tv/webhooks/gitea","content_type":"json"},"events":["push","pull_request"],"active":true}'

# 3. Clone
git clone https://git.fuq.tv/admin/$PROJECT_NAME.git
cd $PROJECT_NAME

# 4. Crear workflow
mkdir -p .gitea/workflows
cat > .gitea/workflows/build.yml << 'EOF'
name: Build
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: echo "Build steps here"
EOF

git add .gitea && git commit -m "Add CI/CD" && git push

🎯 Resumen de URLs y Credenciales

Web UI

API

Registry

  • URL: git.fuq.tv
  • Token: 7401126cfb56ab2aebba17755bdc968c20768c27
  • Format: git.fuq.tv/<owner>/<image>:<tag>

SSH

  • URL: ssh://git@git.fuq.tv:2222/<owner>/<repo>.git
  • Port: 2222 (no 22)

💡 Tips

  1. Tokens: Full access token para API, registry token solo para Docker
  2. Branches: Siempre desde main a menos que especifique otro
  3. PRs: Usar squash merge para historial limpio
  4. Webhooks: Verificar que ALLOWED_HOST_LIST incluye tu dominio
  5. Actions: Primer build tarda más (descarga imágenes)
  6. Registry: Las imágenes se guardan en Longhorn HA storage

📖 Referencia completa: docs/02-backend/gitea-integration.md y docs/CONTAINER-REGISTRY.md

🔧 Para implementar en backend: Ver código de ejemplo en docs/02-backend/gitea-integration.md líneas 5-400