- Go 90.5%
- Shell 9.5%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| cmd/reviewer | ||
| conventions | ||
| examples | ||
| k8s | ||
| .gitignore | ||
| go.mod | ||
| README.md | ||
| setup-microservice.sh | ||
Templates de CI/CD y Kubernetes - StartCodex
Templates reutilizables para microservicios Go con Forgejo Actions y Kubernetes.
Estructura
infra/
├── .forgejo/
│ └── workflows/ # Workflows de Forgejo Actions
│ ├── go-microservice.yaml # Workflow monolítico (todo-en-uno)
│ ├── _test.yaml # Modular: Tests & Coverage (multi-lenguaje)
│ ├── _analytics.yaml # Modular: Opengrep + SonarQube (código)
│ ├── _build-docker.yaml # Modular: Build Docker + Trivy (imagen)
│ └── _deploy-k8s.yaml # Modular: Deploy a Kubernetes
├── k8s/ # Templates de Kubernetes con Kustomize
│ ├── base/ # Configuración base
│ └── overlays/ # Configuraciones por ambiente (dev, test, production)
├── examples/ # Ejemplos de uso
├── setup-microservice.sh # Script de setup automatizado (legacy)
└── README.md # Este archivo
Workflows reutilizables (prefijo _): Pueden ser llamados por otros workflows (Node.js, Python, etc.).
Flujo de ramas y ambientes
Tronco en main. Las ramas de trabajo son cortas y entran por PR.
feat/DB-3-migracion-documents ──PR──► main ──auto──► dev
│
└──manual──► test ──manual──► producción
(el mismo digest, sin reconstruir)
No hay ramas dev ni test. Los ambientes no se recorren mergeando: se
recorren promoviendo el mismo digest con promote.yaml, que se dispara a
mano desde la interfaz.
La razón es concreta: con rama por ambiente, cada merge reconstruye la imagen,
así que lo validado en test no es el binario que llega a producción, sino
otro build de un árbol parecido. Por eso _go-build.yaml devuelve el digest
además de la etiqueta, y _go-deploy.yaml despliega por digest.
dev → release → main está descartado por tamaño de equipo. Las ramas de
release existen para estabilizar una versión mientras otros siguen; con dos
o tres personas solo producen tres merges por cambio y ramas que se
desincronizan. Si algún día hay versiones con soporte simultáneo, se añaden
entonces.
Nombre de ramas
<tipo>/<CÓDIGO>-<resumen-corto>
feat/DB-3-migracion-documents
fix/FIN-1-clasificar-rechazo-sin-codigos
chore/BOOT-2-secretos-del-ci
Tipos: feat, fix, chore, docs, refactor — los mismos del commit,
para que la rama y el mensaje hablen igual.
El <CÓDIGO> es el de la tarjeta en el tablero. Con él, de una rama se llega
a la tarjeta y de la tarjeta al plan sin preguntarle a nadie.
Los dos workflows
| Archivo | Cuándo | Qué hace |
|---|---|---|
ci-cd.yaml |
push y PR a main |
lint, pruebas, seguridad, calidad; en main además construye y despliega a dev |
promote.yaml |
a mano | toma una imagen que ya existe y la despliega en test o producción |
promote.yaml acepta una etiqueta o un digest. Si le das una etiqueta, la
resuelve a digest en ese momento y despliega ese: una etiqueta se puede
re-publicar, un digest no. Y promover a producción exige marcar una
confirmación aparte, porque ahí se emiten documentos reales.
Uso Rápido
⚠️ Esta sección quedó vieja y describe las plantillas multilenguaje (
_test,_analytics,_build-docker,_deploy-k8s), con ramasdevytesty referencias@v1. Nada de eso aplica a un repositorio Go nuevo: el flujo es tronco enmaincon promoción por digest (D76), y las plantillas son las_go-*.Para un repo Go, copia
examples/go-service/, que es lo que está probado contra el runner. Lo de abajo se conserva solo como referencia de las plantillas antiguas, que siguen existiendo pero no se recomiendan.
Hay dos formas de usar estos workflows:
-
Workflow Monolítico (
go-microservice.yaml) - Un solo job que ejecuta todo- ✅ Más simple de configurar
- ❌ Menos visibilidad (todos los jobs aparecen colapsados como uno)
-
Workflows Modulares (Recomendado) - Jobs independientes
- ✅ Mejor visibilidad: Cada etapa aparece como un job separado en la UI
- ✅ Fácil identificar qué etapa falló
- ✅ Más flexible
- ⚠️ Configuración inicial un poco más larga
Opción A: Workflow Modular (Recomendado para mejor visibilidad)
En tu microservicio, crea .forgejo/workflows/ci-cd.yaml:
name: CI/CD
on:
push:
branches: [dev, test, main]
pull_request:
branches: [dev, test, main]
jobs:
# Cada job se verá por separado en la UI
test:
uses: startcodex/ci/.forgejo/workflows/_test.yaml@v1
with:
# project_type: auto # auto, go, nodejs, react, nextjs, flutter, python
go_version: '1.25.4' # Para proyectos Go
# node_version: '20' # Para proyectos Node.js
# python_version: '3.12' # Para proyectos Python
analytics:
needs: test
uses: startcodex/ci/.forgejo/workflows/_analytics.yaml@v1
with:
service_name: tu-servicio-ms
sonar_project_key: startcodex-tu-servicio-ms
# project_type: auto # auto, go, nodejs, react, nextjs, flutter, python
secrets:
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
build:
if: >
forgejo.event_name != 'pull_request' &&
(forgejo.ref_name == 'test' || forgejo.ref_name == 'main')
needs: analytics
uses: startcodex/ci/.forgejo/workflows/_build-docker.yaml@v1
with:
service_name: tu-servicio-ms
registry_url: git.startcodex.dev
registry_org: startcodex
secrets:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
deploy:
if: >
forgejo.event_name != 'pull_request' &&
(forgejo.ref_name == 'test' || forgejo.ref_name == 'main')
needs: build
uses: startcodex/ci/.forgejo/workflows/_deploy-k8s.yaml@v1
with:
service_name: tu-servicio-ms
image_tag: ${{ needs.build.outputs.image_tag }}
registry_url: git.startcodex.dev
registry_org: startcodex
k8s_namespace_test: startcodex-test
k8s_namespace_prod: startcodex
service_type: http-only
http_port: '8080'
# ... más configuración según necesites
secrets:
KUBECONFIG: ${{ secrets.KUBECONFIG }}
INFRA_CLONE_TOKEN: ${{ secrets.INFRA_CLONE_TOKEN }}
Ver ejemplo completo en: examples/modular-workflow-example.yaml
Opción B: Workflow Monolítico (Más simple pero menos visible)
En tu microservicio, crea .forgejo/workflows/ci-cd.yaml:
name: CI/CD
on:
push:
branches: [dev, test, main]
pull_request:
branches: [dev, test, main]
jobs:
ci-cd:
uses: startcodex/ci/.forgejo/workflows/go-microservice.yaml@v1.0.0
with:
# Requeridos:
service_name: tu-servicio-ms
sonar_project_key: startcodex-tu-servicio-ms
# Configuración del servicio:
service_type: http-only # http-only, grpc-only, both
k8s_service_type: ClusterIP # ClusterIP, NodePort, LoadBalancer
http_port: '8080'
grpc_port: '50051' # Solo si usas gRPC
# Secrets management (opcional):
use_infisical: false # true para usar Infisical
# infisical_project_slug: startcodex-tu-servicio-ms
# infisical_env_slug_test: staging
# infisical_env_slug_prod: production
# HPA - Autoscaling (opcional):
# hpa_min_replicas_test: 2
# hpa_max_replicas_test: 5
# hpa_cpu_threshold_test: 70
# hpa_memory_threshold_test: 80
# hpa_min_replicas_prod: 3
# hpa_max_replicas_prod: 10
# hpa_cpu_threshold_prod: 60
# hpa_memory_threshold_prod: 70
# Health Checks (opcional):
# enable_health_checks: true # false para deshabilitar liveness/readiness
# Opcionales (tienen defaults):
# registry_url: git.startcodex.dev
# registry_org: startcodex
# k8s_namespace_dev: startcodex-dev
# k8s_namespace_test: startcodex-test
# k8s_namespace_prod: startcodex
# sonarqube_host: https://sonar.startcodex.dev
# go_version: '1.24.1'
secrets: inherit
Versionado de Workflows
IMPORTANTE: Debido a limitaciones en Forgejo Actions, debes usar tags o SHA completo en lugar de nombres de branches (@main no funciona correctamente).
Opción 1: Tags Semánticos (Recomendado)
# Versión estable específica (recomendado para producción)
uses: startcodex/ci/.forgejo/workflows/go-microservice.yaml@v1.0.0
# Última versión minor (recibe bug fixes automáticamente)
uses: startcodex/ci/.forgejo/workflows/go-microservice.yaml@v1.0
# Última versión major (recibe todas las actualizaciones compatibles)
uses: startcodex/ci/.forgejo/workflows/go-microservice.yaml@v1
Semantic Versioning:
v1.0.0 → v1.0.1(PATCH): Bug fixes, sin cambios funcionalesv1.0.0 → v1.1.0(MINOR): Nuevas features compatiblesv1.0.0 → v2.0.0(MAJOR): Breaking changes
Opción 2: SHA Completo
# Si necesitas una versión específica inmutable
uses: startcodex/ci/.forgejo/workflows/go-microservice.yaml@725dfbe7bf4bbc2ac1b5d3193789f25e598c1bd8
Recomendación: Usa tags semánticos para facilitar el mantenimiento y actualizaciones.
Referencia de Inputs
Inputs Requeridos
| Input | Descripción | Ejemplo |
|---|---|---|
service_name |
Nombre del microservicio | users-ms |
sonar_project_key |
Key del proyecto en SonarQube | startcodex-users-ms |
Inputs de Configuración del Servicio
| Input | Descripción | Valores | Default |
|---|---|---|---|
service_type |
Tipo de protocolo del servicio | http-only, grpc-only, both |
http-only |
k8s_service_type |
Tipo de Service de Kubernetes | ClusterIP, NodePort, LoadBalancer |
ClusterIP |
http_port |
Puerto HTTP del servicio | Cualquier puerto | 8080 |
grpc_port |
Puerto gRPC del servicio | Cualquier puerto | 50051 |
enable_health_checks |
Habilitar liveness y readiness probes HTTP | true/false |
true |
Inputs de Secrets Management
| Input | Descripción | Tipo | Default |
|---|---|---|---|
use_infisical |
Usar Infisical para secrets | true/false |
false |
infisical_project_slug |
Project slug en Infisical | string | '' |
infisical_env_slug_test |
Environment slug para test | string | staging |
infisical_env_slug_prod |
Environment slug para production | string | production |
Inputs de Autoscaling (HPA)
| Input | Descripción | Default |
|---|---|---|
hpa_min_replicas_test |
Mínimo de réplicas para HPA en test | 2 |
hpa_max_replicas_test |
Máximo de réplicas para HPA en test | 5 |
hpa_cpu_threshold_test |
Umbral de CPU (%) para escalar en test | 70 |
hpa_memory_threshold_test |
Umbral de memoria (%) para escalar en test | 80 |
hpa_min_replicas_prod |
Mínimo de réplicas para HPA en production | 3 |
hpa_max_replicas_prod |
Máximo de réplicas para HPA en production | 10 |
hpa_cpu_threshold_prod |
Umbral de CPU (%) para escalar en production | 60 |
hpa_memory_threshold_prod |
Umbral de memoria (%) para escalar en production | 70 |
Inputs de Recursos por Ambiente
Recursos para TEST
| Input | Descripción | Default |
|---|---|---|
test_memory_request |
Memoria request para test | 256Mi |
test_memory_limit |
Memoria limit para test | 512Mi |
test_cpu_request |
CPU request para test | 200m |
test_cpu_limit |
CPU limit para test | 500m |
Recursos para PRODUCTION
| Input | Descripción | Default |
|---|---|---|
prod_memory_request |
Memoria request para production | 512Mi |
prod_memory_limit |
Memoria limit para production | 1Gi |
prod_cpu_request |
CPU request para production | 500m |
prod_cpu_limit |
CPU limit para production | 1000m |
Inputs de Infraestructura
| Input | Descripción | Default |
|---|---|---|
registry_url |
URL del Docker registry | git.startcodex.dev |
registry_org |
Organización en el registry | startcodex |
k8s_namespace_dev |
Namespace de Kubernetes para dev | startcodex-dev |
k8s_namespace_test |
Namespace de Kubernetes para test | startcodex-test |
k8s_namespace_prod |
Namespace de Kubernetes para production | startcodex |
sonarqube_host |
URL de SonarQube | https://sonarqube.com |
go_version |
Versión de Go | 1.24.1 |
Secrets Requeridos en Forgejo
| Secret | Descripción | Requerido | Ejemplo |
|---|---|---|---|
REGISTRY_USER |
Usuario del Docker registry (también para repos Go privados) | ✅ Sí | forgejo-ci |
REGISTRY_PASSWORD |
Password del Docker registry (también para repos Go privados) | ✅ Sí | *** |
SONARQUBE_TOKEN |
Token de autenticación de SonarQube | ✅ Sí | squ_*** |
KUBECONFIG |
Configuración de kubectl (base64) | ✅ Sí | apiVersion: v1... |
INFRA_CLONE_TOKEN |
Token para clonar repo infra privado | ⚠️ Solo si infra es privado | *** |
Módulos Go Privados
Si tu microservicio Go depende de módulos privados en git.startcodex.dev, los workflows automáticamente configuran .netrc usando REGISTRY_USER y REGISTRY_PASSWORD.
Dockerfile de ejemplo (ver examples/go.Dockerfile):
# El workflow pasa automáticamente .netrc como secret de BuildKit
RUN --mount=type=secret,id=netrc,target=/root/.netrc \
go mod download
Funcionamiento automático:
- En el job de test: Se configura
~/.netrcantes dego mod tidy - En el build de Docker: Se usa BuildKit secrets para no exponer credenciales en la imagen
2. Configurar Secrets en Forgejo
Configurar Secrets (Settings → Secrets and Variables → Secrets):
Secrets Requeridos:
REGISTRY_USER
REGISTRY_PASSWORD
SONARQUBE_TOKEN
KUBECONFIG
Secret Opcional (solo si el repo infra es privado):
INFRA_CLONE_TOKEN # Token de Forgejo con permisos read:repository
Configuración del Repo Infra
Opción A: Repo Público (Recomendado)
- En Forgejo:
startcodex/ci→ Settings → Make Repository Public - ✅ No requiere
INFRA_CLONE_TOKEN - ✅ Más simple
Opción B: Repo Privado
- Crear Personal Access Token en Forgejo:
- Settings → Applications → Generate New Token
- Name:
infra-workflows-readonly - Scopes:
read:repository
- Agregar secret
INFRA_CLONE_TOKENen cada microservicio - ⚠️ Requiere configuración adicional
Eso es todo! Los manifiestos de Kubernetes se generan automáticamente en el deploy.
3. (Opcional) Configurar Secrets
Tienes dos opciones para manejar secrets:
Opción A: Kubernetes Secrets (default, use_infisical: false)
Crear secrets directamente en Kubernetes:
kubectl create secret generic nombre-servicio-env \
--from-literal=DATABASE_URL="postgresql://..." \
--from-literal=API_KEY="..." \
-n startcodex-test
Opción B: Infisical (use_infisical: true)
Si usas Infisical para secrets management, el workflow genera automáticamente el InfisicalSecret CRD:
with:
use_infisical: true
infisical_project_slug: startcodex-users-ms-mp-t7
infisical_env_slug_test: staging # Para branch test
infisical_env_slug_prod: production # Para branch main
Prerrequisitos:
- Infisical Operator instalado en el cluster
- Secret
universal-auth-credentialscreado en namespacedefault:kubectl create secret generic universal-auth-credentials \ --from-literal=clientId="YOUR_CLIENT_ID" \ --from-literal=clientSecret="YOUR_CLIENT_SECRET" \ -n default
El workflow automáticamente:
- Genera el
InfisicalSecretcon el project y environment correcto - El Infisical operator sincroniza los secrets al secret
SERVICE_NAME-env - El deployment carga los secrets automáticamente
4. Commit y Deploy
git add .
git commit -m "Add CI/CD and K8s configuration"
git push origin dev
Esquema de Ramas
⚠️ El esquema de rama por ambiente quedó descartado (D76, 2026-10-05). Ver «Flujo de ramas y ambientes» arriba. Las plantillas
_go-*asumen tronco enmainy promoción por digest. Las plantillas antiguas (_test,_build-docker,_deploy-k8s,_analytics) todavía suponen ramastestymain; no se han tocado, pero no se usen para repos nuevos.
| Rama | Ambiente | Deploy | Imagen |
|---|---|---|---|
main |
dev | automático al mergear | YYYY.MM.DD.HHMM |
| — | test | manual, promote.yaml |
el mismo digest |
| — | producción | manual, promote.yaml + confirmación |
el mismo digest |
Pipeline CI/CD
- Lint and test: en paralelo; unitarias con umbral de cobertura, componente contra Postgres real, e2e con compose
- Seguridad y calidad: govulncheck, gitleaks, Opengrep, SonarQube con Quality Gate
- Build: multiarquitectura, escaneo antes de publicar, SBOM, devuelve digest
- Deploy a dev: automático, por digest, con migración que bloquea el rollout
- Promoción: manual a test y producción, redesplegando el mismo digest
Security Scanning
Las herramientas de seguridad están integradas en los workflows existentes:
┌─────────────────────────────────────────────────────────────────────────┐
│ PIPELINE DE SEGURIDAD │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ test ──► _analytics.yaml ──────────► _build-docker.yaml ──► deploy │
│ │ │ │
│ ├── Opengrep (SAST) └── Trivy (imagen Docker) │
│ └── SonarQube (Quality) ├── CVEs │
│ ├── Secrets │
│ └── SBOM (CycloneDX) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
| Herramienta | Ubicación | Qué analiza |
|---|---|---|
| Opengrep | _analytics.yaml |
Código fuente: injection, XSS, secrets (100% open source) |
| SonarQube | _analytics.yaml |
Código fuente: bugs, code smells, coverage |
| Trivy | _build-docker.yaml |
Imagen Docker: CVEs, secrets, SBOM |
Code Analytics (Opengrep + SonarQube)
jobs:
analytics:
uses: startcodex/ci/.forgejo/workflows/_analytics.yaml@v1
with:
service_name: tu-servicio-ms
sonar_project_key: startcodex-tu-servicio-ms
# project_type: auto # auto, go, nodejs, react, nextjs, flutter, python
secrets:
SONARQUBE_TOKEN: ${{ secrets.SONARQUBE_TOKEN }}
Nota: Opengrep es un fork 100% open source de Semgrep con análisis avanzado (taint analysis inter-file) sin restricciones de licencia.
Build + Trivy (Docker Image Scan)
jobs:
build:
uses: startcodex/ci/.forgejo/workflows/_build-docker.yaml@v1
with:
service_name: tu-servicio-ms
# Trivy scan de imagen
trivy_enabled: true
trivy_severity: 'CRITICAL,HIGH,MEDIUM'
trivy_exit_code: '1' # 0=warn, 1=fail (bloquea si hay vulns)
secrets:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
Artifacts Generados
opengrep-results-{service_name}: Reporte SARIF de Opengreptrivy-image-{service_name}: Reporte JSON + SBOM (CycloneDX)
Configuración Recomendada
Por defecto, el pipeline bloquea si encuentra vulnerabilidades MEDIUM, HIGH o CRITICAL.
| Parámetro | Default | Descripción |
|---|---|---|
trivy_severity |
CRITICAL,HIGH,MEDIUM |
Severidades a detectar |
trivy_exit_code |
1 |
Bloquea el pipeline si encuentra vulns |
opengrep_enabled |
true |
Habilita SAST en código |
Para ambiente de desarrollo (solo warnings):
trivy_exit_code: '0' # No bloquea, solo reporta
Recursos por Ambiente
| Ambiente | Replicas | Memory | CPU | HPA |
|---|---|---|---|---|
| Dev | 1 | 64Mi / 128Mi | 50m / 100m | 1-3 |
| Test | 2 | 256Mi / 512Mi | 200m / 500m | 2-5 |
| Prod | 3 | 512Mi / 1Gi | 500m / 1000m | 3-10 |
Personalización
Los archivos generados son totalmente editables:
Recursos: Editar k8s/overlays/{dev,test,production}/deployment-patch.yaml
HPA: Editar k8s/overlays/{dev,test,production}/hpa-patch.yaml
ConfigMap: Editar k8s/base/configmap.yaml
Ejemplos
Ver directorio examples/users-ms-example/ para ver un ejemplo completo.
Ejemplo: API REST simple
with:
service_name: orders-api
sonar_project_key: startcodex-orders-api
service_type: http-only
http_port: '8080'
Ejemplo: Servicio gRPC
with:
service_name: payment-service
sonar_project_key: startcodex-payment-service
service_type: grpc-only
grpc_port: '50051'
# enable_health_checks se deshabilita automáticamente para grpc-only
Ejemplo: API sin health checks
with:
service_name: worker-service
sonar_project_key: startcodex-worker-service
service_type: http-only
http_port: '8080'
enable_health_checks: false # Deshabilita liveness y readiness probes
Ejemplo: API híbrida con Infisical
with:
service_name: users-ms
sonar_project_key: startcodex-users-ms
service_type: both
http_port: '8080'
grpc_port: '50051'
use_infisical: true
infisical_project_slug: startcodex-users-ms-mp-t7
infisical_env_slug_test: staging
infisical_env_slug_prod: production
Tipos de Servicio Soportados
Configura el tipo de servicio con el parámetro service_type:
-
http-only: Para APIs REST, webhooks, etc.- Solo puerto HTTP (default: 8080)
- Health checks HTTP en
/healthy/ready(sienable_health_checks: true) - Ejemplo: APIs REST, microservicios web
-
grpc-only: Para servicios gRPC puros- Solo puerto gRPC (default: 50051)
- Health checks HTTP deshabilitados automáticamente
- Ejemplo: Servicios backend internos
-
both: Para servicios que exponen ambos protocolos- Ambos puertos configurables
- Health checks HTTP en
/healthy/ready(sienable_health_checks: true) - Ejemplo: APIs híbridas REST + gRPC
Tipos de Service de Kubernetes
Configura el tipo de Service de Kubernetes con el parámetro k8s_service_type:
-
ClusterIP(default): Acceso solo dentro del cluster- IP interna del cluster
- No accesible desde fuera
- Ideal para servicios internos
- Ejemplo: Microservicios backend que solo hablan entre sí
-
NodePort: Expone el servicio en un puerto del nodo- Accesible desde fuera del cluster en
<NodeIP>:<NodePort> - Puerto asignado en rango 30000-32767
- Útil para desarrollo/testing
- Ejemplo: Servicios que necesitan acceso externo sin Load Balancer
- Accesible desde fuera del cluster en
-
LoadBalancer: Provisiona un Load Balancer externo- Obtiene una IP externa del proveedor de cloud
- Balanceo automático de carga
- Ideal para producción con tráfico externo
- Ejemplo: APIs públicas, servicios expuestos a internet
Ejemplo de uso:
with:
service_type: http-only # Tipo de protocolo (http/grpc)
k8s_service_type: LoadBalancer # Tipo de Service de K8s
http_port: '8080'
Troubleshooting
Workflow no se ejecuta:
- Verificar que existe
.forgejo/workflows/ci-cd.yaml - Verificar nombre de rama:
dev,test, omain
Error al clonar repo infra:
authentication required: Unauthorized
- Solución 1: Hacer el repo
infrapúblico en Forgejo (Settings → Make Public) - Solución 2: Crear token de Forgejo y agregarlo como secret
INFRA_CLONE_TOKEN
Error de Docker registry:
- Verificar secrets
REGISTRY_USERyREGISTRY_PASSWORDen Forgejo
Pods en CrashLoopBackOff:
kubectl logs -n <namespace> <pod-name>
kubectl get secret -n <namespace> nombre-servicio-env
- Si
enable_health_checks: true, verificar que/healthy/readyendpoints estén implementados - Para servicios sin health checks HTTP, usar
enable_health_checks: false
SonarQube falla:
- Verificar variables
SONARQUBE_HOSTySONAR_PROJECT_KEY - Verificar secret
SONARQUBE_TOKEN
Migración de Ramas Antiguas
Si tu proyecto usa integration, staging, master:
# Renombrar localmente
git branch -m integration dev
git branch -m staging test
git branch -m master main
# Push nuevas ramas
git push -u origin dev
git push -u origin test
git push -u origin main
# Actualizar rama por defecto en Forgejo: Settings → Repository → Default Branch → main
Soporte
- Issues en repo
infra - Equipo DevOps/Platform