> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raigal.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Pipelines de CI/CD

> Integra Raigal en GitHub Actions, GitLab CI y Bitbucket Pipelines.

Configura Raigal para evaluar pull requests en CI, aplicar reglas de calidad y enviar métricas en tiempo real a tu panel en [app.raigal.dev](https://app.raigal.dev).

Al ejecutar `raigal init`, la CLI detecta tu proveedor de CI y genera el flujo adecuado automáticamente.

## Variables de entorno

Configura estas variables en tu entorno de CI:

| Variable | Requerida | Descripción | Ejemplo |
| - | - | - | - |
| `RAIGAL_TOKEN` | Recomendada\* | Clave de API de la organización (`rgl_live_...`) | `rgl_live_8f3a9b...` |
| `RAIGAL_ORG_ID` | Condicional | ID de la organización (`org_...`), obligatorio si la cuenta pertenece a varias organizaciones | `org_2tQ...` |
| `RAIGAL_API_URL` | Opcional | URL del backend (por defecto `https://app.raigal.dev`) | `https://app.raigal.dev` |

*Nota: En GitHub Actions configurado con `permissions: id-token: write`, los tokens estáticos pueden omitirse porque Raigal valida el runner mediante OIDC criptográfico de GitHub. Aun así, guardar `RAIGAL_TOKEN` como secreto en el repositorio es recomendable para tener la misma configuración en todas las plataformas.*

## GitHub Actions

### 1. Control de calidad en pull requests

Crea `.github/workflows/raigal.yml` para evaluar pull requests, notificar al panel web y generar informes SARIF opcionales:

```yaml theme={null}
name: Raigal quality gate

on:
  push:
    branches: [main, master, develop]
  pull_request:
    branches: [main, master, develop]

permissions:
  contents: read
  id-token: write        # Autenticación OIDC criptográfica sin secretos fijos
  security-events: write # Requerido si se exportan informes SARIF a GitHub Code Scanning

jobs:
  quality-gate:
    name: Code quality gate
    runs-on: ubuntu-latest

    steps:
      - name: Descargar código
        uses: actions/checkout@v4
        with:
          fetch-depth: 0 # Historial completo necesario para calcular diffs con la rama base

      - name: Configurar Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Ejecutar control de calidad
        env:
          RAIGAL_TOKEN: ${{ secrets.RAIGAL_TOKEN }}
          # RAIGAL_ORG_ID: ${{ vars.RAIGAL_ORG_ID }} # Necesario solo si el propietario pertenece a varias organizaciones
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            git fetch origin ${{ github.base_ref }} --depth=1
            npx --yes @methiu/raigal@latest ci --changes --base origin/${{ github.base_ref }}
          else
            npx --yes @methiu/raigal@latest ci .
          fi

      - name: Generar informe de seguridad SARIF (opcional)
        if: always()
        run: npx --yes @methiu/raigal@latest scan . --sarif > raigal-results.sarif

      - name: Subir SARIF a GitHub Code Scanning (opcional)
        if: always() && github.event.pull_request.head.repo.full_name == github.repository
        uses: github/codeql-action/upload-sarif@v3
        continue-on-error: true
        with:
          sarif_file: raigal-results.sarif
          category: raigal
```

> [!NOTE]
>
> Subir informes SARIF a GitHub Code Scanning en repositorios privados requiere GitHub Advanced Security (GHAS) en tu cuenta. En repositorios públicos, GitHub ofrece Code Scanning sin coste adicional.

### 2. Sincronización al fusionar o cerrar pull requests

> [!NOTE]
>
> Si utilizas la **GitHub App oficial de Raigal**, este paso no es necesario. La app recibe los webhooks de GitHub y actualiza el panel automáticamente.

Para entornos de CI sin la GitHub App, sincroniza el estado al fusionar o cerrar ramas:

```yaml theme={null}
name: Sincronización de PRs

on:
  pull_request:
    types: [closed]

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Sincronizar PR con Raigal Cloud
        env:
          RAIGAL_TOKEN: ${{ secrets.RAIGAL_TOKEN }}
        run: |
          npx --yes @methiu/raigal@latest report-pr-closed --pr ${{ github.event.pull_request.number }} ${{ github.event.pull_request.merged && '--merged' || '' }}
```

## GitLab CI

En `.gitlab-ci.yml` (autogenerado con `raigal init`):

```yaml theme={null}
raigal_quality_gate:
  image: node:22
  stage: test
  script:
    - if [ -n "$CI_MERGE_REQUEST_IID" ]; then npx --yes @methiu/raigal@latest ci --changes --base "$CI_MERGE_REQUEST_DIFF_BASE_SHA"; else npx --yes @methiu/raigal@latest ci .; fi
  variables:
    RAIGAL_TOKEN: $RAIGAL_TOKEN
    # RAIGAL_ORG_ID: $RAIGAL_ORG_ID
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```

Configura `RAIGAL_TOKEN` en GitLab en **Settings > CI/CD > Variables**.

## Bitbucket Pipelines

En `bitbucket-pipelines.yml` (autogenerado con `raigal init`):

```yaml theme={null}
pipelines:
  default:
    - step:
        name: raigal quality gate
        image: node:22
        script:
          - npx --yes @methiu/raigal@latest ci .
        secrets:
          - RAIGAL_TOKEN
          # - RAIGAL_ORG_ID
  pull-requests:
    "**":
      - step:
          name: raigal quality gate
          image: node:22
          clone:
            depth: full   # Se requiere historial completo para diffs
          script:
            - git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
            - npx --yes @methiu/raigal@latest ci --changes --base FETCH_HEAD
          secrets:
            - RAIGAL_TOKEN
            # - RAIGAL_ORG_ID
```

Configura `RAIGAL_TOKEN` en Bitbucket en **Repository settings > Repository variables**.

## Códigos de salida y control de calidad

En todos los proveedores de CI, `raigal ci` responde de forma consistente:

* **Código de salida 0 (Aprobado)**: La nota del repositorio es igual o superior a `ci.failBelow` (por defecto: 70) y no hay ninguna incidencia con severidad `error`.
* **Código de salida 1 (Bloqueado)**: La nota cayó por debajo de `ci.failBelow` o se detectó al menos un hallazgo de severidad `error` (riesgos de seguridad, errores de sintaxis o inyecciones en prompts).
* **Código de salida 2 (Vencimiento de licencia)**: Ocurre solo si `licensing.onLapse` está configurado como `"fail-closed"` y la licencia temporal venció sin conexión exterior.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.