~/codigoagente
Agentes de IA

Revisión de código con IA en cada pull request: Open Code Review en GitHub Actions y GitLab CI

La forma en que más se nota Open Code Review es cuando nadie tiene que acordarse de lanzarlo: cada pull request recibe una primera revisión con comentarios en las líneas exactas antes de que llegue un humano. En esta última parte de la guía montamos esa automatización con la GitHub Action oficial y con GitLab CI, explicamos cada secreto y cada opción, y vemos cómo controlar el coste y no abrir un agujero de seguridad.

Partimos de lo que ya sabes de las partes anteriores: instalar y configurar ocr y escribir reglas con rule.json. Todo lo que hay aquí procede del workflow, la acción y la documentación de la v1.13.2. No lo hemos ejecutado en un repositorio con una API key de pago, así que donde citamos comportamiento es el documentado por el proyecto.

Cómo funciona la revisión en CI

Esquema del flujo de Open Code Review en GitHub Actions: disparo, checkout con historial, instalación, revisión en modo rango y publicación de comentarios
El patrón que siguen todas las integraciones de CI del proyecto · codigoagente

Todas las recetas (GitHub, GitLab, Gerrit, Bitbucket, GitFlic, Codeup) siguen el mismo esquema:

  1. Un evento del PR o MR dispara el job.
  2. Se instala ocr con npm (el runner es efímero).
  3. Se configura el LLM con ocr config set a partir de los secretos del CI.
  4. Se ejecuta la revisión en modo rango con salida para máquinas:

``bash ocr review --from "origin/<rama-base>" --to "origin/<rama-del-pr>" --format json --audience agent ``

  1. Un script lee comments[] y publica cada hallazgo como comentario en línea. Los que no tienen línea (start_line: 0) van a un comentario resumen.

Hay siempre dos credenciales: la del LLM, para generar la revisión, y un token con permiso de escritura en el PR, para comentar. En GitHub la segunda es el GITHUB_TOKEN automático.

GitHub Actions paso a paso

1. Copia el workflow

terminalsh
mkdir -p .github/workflows
curl -o .github/workflows/ocr-review.yml \
  https://raw.githubusercontent.com/alibaba/open-code-review/main/examples/github_actions/ocr-review.yml

2. Crea los secretos y variables

En Settings → Secrets and variables → Actions:

NombreTipoEjemploPara qué
`OCR_LLM_URL`Secreto`https://api.anthropic.com` o `https://api.openai.com/v1/chat/completions`Endpoint del modelo
`OCR_LLM_AUTH_TOKEN`Secreto`sk-…`Clave del proveedor
`OCR_LLM_MODEL`Variable`claude-sonnet-4-6`Modelo. No tiene valor por defecto.
`OCR_LLM_USE_ANTHROPIC`Variable`true``true` para Anthropic, `false` para APIs compatibles con OpenAI

3. Lo que hace el workflow oficial

Esta es la parte central del archivo (simplificada; el original añade el mismo filtro en el concurrency):

.github/workflows/ocr-review.ymlyaml
on:
  pull_request_target:
    types: [opened, synchronize, reopened]
  issue_comment:
    types: [created]

permissions:
  contents: read
  pull-requests: write

jobs:
  code-review:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    if: |
      github.event_name == 'pull_request_target'
      || (
        github.event_name == 'issue_comment'
        && github.event.issue.pull_request
        && github.event.comment.user.type != 'Bot'
        && contains(fromJSON('["MEMBER","OWNER","COLLABORATOR"]'), github.event.comment.author_association)
        && (startsWith(github.event.comment.body, '/open-code-review')
            || startsWith(github.event.comment.body, '@open-code-review'))
      )
    steps:
      - name: Get PR context
        id: pr-context
        if: github.event_name == 'issue_comment'
        uses: actions/github-script@v7
        with:
          script: |
            const { data: pr } = await github.rest.pulls.get({
              owner: context.repo.owner, repo: context.repo.repo,
              pull_number: context.issue.number });
            core.setOutput('base_ref', pr.base.ref);
            core.setOutput('head_sha', pr.head.sha);

      - name: Run OpenCodeReview
        uses: alibaba/open-code-review@main
        with:
          llm_url: ${{ secrets.OCR_LLM_URL }}
          llm_auth_token: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
          llm_model: ${{ vars.OCR_LLM_MODEL }}
          llm_use_anthropic: ${{ vars.OCR_LLM_USE_ANTHROPIC }}
          base_ref: ${{ steps.pr-context.outputs.base_ref }}
          head_sha: ${{ steps.pr-context.outputs.head_sha }}

Qué conviene entender:

  • Se dispara al abrir, actualizar o reabrir un PR, y cuando un miembro, propietario o colaborador comenta /open-code-review o @open-code-review. Los comentarios de bots y de desconocidos no gastan tu cuota.
  • pull_request_target se usa para que los secretos estén disponibles también en PRs desde forks. El proyecto lo considera seguro porque la acción solo lee el diff y no ejecuta código del PR. No añadas pasos que ejecuten el código del PR (npm install, tests, builds) en este mismo workflow: con pull_request_target tendrían acceso a tus secretos.
  • concurrency cancela la revisión anterior del mismo PR si llega un push nuevo.
  • La acción compuesta alibaba/open-code-review@main instala ocr, lo configura, ejecuta la revisión y publica los comentarios. Si fallan en bloque, los publica uno a uno, y deja un comentario resumen con estadísticas.

4. Ajustes de la acción que más vas a usar

Todo va bajo with: del paso Run OpenCodeReview:

snippetyaml
      - name: Run OpenCodeReview
        uses: alibaba/open-code-review@main
        with:
          llm_url: ${{ secrets.OCR_LLM_URL }}
          llm_auth_token: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
          llm_model: ${{ vars.OCR_LLM_MODEL }}
          llm_use_anthropic: ${{ vars.OCR_LLM_USE_ANTHROPIC }}
          language: Spanish
          effort: medium
          max_tokens_budget: '3000000'
          rule: .opencodereview/rule.json
          background: ${{ github.event.pull_request.title }}
          ocr_version: '1.13.2'
          incremental: 'true'
          resolve_outdated: 'true'
          stream_progress: 'true'
InputPor defectoQué hace
`language``English`Idioma de los comentarios
`effort`(medium)`low`, `medium` o `high`: 1, 2 o 3 pasadas
`max_tokens_budget`ilimitadoTope de tokens por ejecución; publica lo revisado y marca el resto como `failed(budget)`
`rule`—Archivo de reglas pasado a `--rule`
`background`—Contexto pasado a `--background` (el título del PR funciona muy bien con Conventional Commits)
`review_concurrency`8Subagentes en paralelo; bájalo si tu proveedor te limita
`ocr_version``latest`Fija una versión para builds reproducibles
`sticky_summary``true`Actualiza el mismo comentario resumen en cada ejecución
`incremental``false`Solo añade comentarios que no se solapen con los que ya publicó
`resolve_outdated``false`Resuelve sus hilos que GitHub ya marcó como desactualizados
`checkpoint_range``false`En cada push revisa solo lo nuevo desde el último commit revisado
`route_severity_below` / `route_categories`—Manda los hallazgos menores al resumen en vez de en línea
`llm_extra_body``{"thinking":{"type":"disabled"}}`Campos extra para el proveedor (por defecto desactiva el *thinking*)
`llm_reasoning_effort`—`minimal` a `max` para modelos OpenAI-compatibles con razonamiento

Sobre background: si construyes tus propios comandos run: en lugar de usar la acción, pasa el título del PR por env: y nunca con ${{ }} dentro del script. GitHub sustituye ${{ }} como texto antes de que se ejecute el shell, y un título con caracteres especiales podría ejecutar comandos en tu runner:

snippetyaml
      - name: Run OCR review
        env:
          PR_TITLE: ${{ github.event.pull_request.title }}
          BASE_REF: ${{ github.base_ref }}
          HEAD_REF: ${{ github.head_ref }}
        run: |
          ocr review --background "$PR_TITLE" \
            --from "origin/$BASE_REF" --to "origin/$HEAD_REF" \
            --format json --audience agent > ocr-result.json

5. Hallazgos en Security → Code scanning (SARIF)

Si prefieres ver los hallazgos en la pestaña de seguridad de GitHub en lugar de como comentarios:

snippetyaml
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: npm install -g @alibaba-group/open-code-review
      - name: Run OCR review
        env:
          OCR_LLM_URL: ${{ secrets.OCR_LLM_URL }}
          OCR_LLM_TOKEN: ${{ secrets.OCR_LLM_AUTH_TOKEN }}
          OCR_LLM_MODEL: ${{ vars.OCR_LLM_MODEL }}
          BASE_REF: ${{ github.base_ref }}
          HEAD_REF: ${{ github.head_ref }}
        run: |
          ocr review --from "origin/$BASE_REF" --to "origin/$HEAD_REF" \
            --format sarif --audience agent > results.sarif
      - uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif

fetch-depth: 0 es obligatorio: sin historial completo no hay merge-base. Para subir SARIF, el job necesita el permiso security-events: write.

6. Comentar como un bot con nombre propio

Por defecto los comentarios aparecen como github-actions[bot]. Para que salgan como "OpenCodeReview Bot", crea una GitHub App (permisos: Pull requests de lectura y escritura, Contents de solo lectura), instálala en el repo, guarda GITHUB_APP_ID y GITHUB_APP_PRIVATE_KEY como secretos y genera el token con actions/create-github-app-token@v1. Después pásalo a la acción con el input github_token.

GitLab CI

terminalsh
curl -o .gitlab-ci.yml \
  https://raw.githubusercontent.com/alibaba/open-code-review/main/examples/gitlab_ci/.gitlab-ci.yml

Si ya tienes un .gitlab-ci.yml, guarda la receta en otra ruta e inclúyela con include: - local: 'ci/ocr-review.gitlab-ci.yml'.

Variables en Settings → CI/CD → Variables:

VariableObligatoriaEnmascaradaDescripción
`OCR_LLM_URL`SíNoEndpoint del modelo
`OCR_LLM_AUTH_TOKEN`SíSíClave del proveedor
`OCR_LLM_MODEL`SíNoModelo
`GITLAB_API_TOKEN`RecomendadaSíToken con alcance `api` para publicar comentarios; sin él usa `CI_JOB_TOKEN`

El núcleo del job es este:

.gitlab-ci.ymlyaml
script:
  - npm install -g @alibaba-group/open-code-review
  - |
    ocr config set llm.url "$OCR_LLM_URL"
    ocr config set llm.auth_token "$OCR_LLM_AUTH_TOKEN"
    ocr config set llm.model "$OCR_LLM_MODEL"
    ocr config set llm.use_anthropic false
    ocr config set llm.extra_body '{"thinking": {"type": "disabled"}}'
  - mkdir -p .ocr
  - |
    ocr review --background "$CI_MERGE_REQUEST_TITLE" \
      --from "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" \
      --to "${CI_COMMIT_SHA}" \
      --format json --audience agent > .ocr/ocr-result.json
  - python3 post_review.py .ocr/ocr-result.json

El script de publicación calcula base_sha, start_sha y head_sha con el endpoint versions del MR para que cada comentario caiga en la línea correcta como *discussion*, usa notas normales para lo que no se puede anclar y cierra con un resumen. También deja artefactos (.ocr/ocr-result.json, .ocr/ocr-stderr.log) durante una semana y un informe dotenv con contadores.

Dos detalles de GitLab:

  • GitLab rechaza variables de menos de 8 caracteres, así que llm.use_anthropic está fijado a false en el script. Para Claude, edítalo a mano.
  • Con only: [merge_requests] se revisa en cada push. La documentación incluye un wrapper en Python que consulta las notas del MR y se salta la revisión si ya hay una de OpenCodeReview. Si nombras el token de proyecto "OpenCodeReview Bot", ese es el nombre que aparecerá en los comentarios.

Para GitLab autoalojado no hay que cambiar nada: usa CI_SERVER_URL.

Otros sistemas de CI

En la carpeta examples/ del repo hay recetas listas para Gerrit (Jenkinsfile + script de publicación), Bitbucket Pipelines, GitFlic CI y Codeup (Alibaba Cloud DevOps). Todas siguen el mismo patrón de cinco pasos.

Controlar el coste

En CI nadie mira el contador, así que conviene limitarlo de entrada:

  1. max_tokens_budget (o --max-tokens-budget): tope duro por ejecución.
  2. effort: low: una sola pasada por grupo, la palanca de ahorro más grande.
  3. incremental o checkpoint_range: no repetir la revisión completa en cada push.
  4. exclude en rule.json: fuera migraciones, código generado y fixtures.
  5. Disparo bajo demanda: quita synchronize de los eventos y deja que el equipo comente /open-code-review cuando quiera una nueva revisión.
  6. review_concurrency más bajo si tu proveedor te limita: con throttling los reintentos alargan el job.

Errores frecuentes

Cannot find merge-base El checkout se hizo con historial superficial. Pon fetch-depth: 0 en actions/checkout. El workflow oficial ya lo hace; no lo quites si lo editas.

Failed to parse OCR output OCR_LLM_URL o OCR_LLM_AUTH_TOKEN faltan o son incorrectos. Revisa los secretos y mira los artefactos (ocr-result.json y ocr-stderr.log).

Comentarios en líneas equivocadas El diff cambió entre la revisión y la publicación (otro push en medio). El script lo detecta y lo publica como comentario normal.

El job termina en verde pero faltan archivos Algún subagente falló (timeout, límite del proveedor). ocr termina con código 0 si al menos un grupo funcionó; los fallidos aparecen en warnings del JSON y en el resumen.

OCR_DEBUG: "1" no hace nada No está implementado. Para depurar, descarga los artefactos o lanza ocr review en local con las mismas refs.

Preguntas frecuentes

¿Puede bloquear el merge si encuentra algo grave? La acción no falla por hallazgos: comenta. Si quieres bloquear, usa SARIF con Code Scanning y una regla de protección de rama, o lee la salida comments_total de la acción en un paso posterior y haz exit 1 según tu criterio.

¿Es seguro con PRs de forks? El workflow oficial sí, porque solo lee el diff. El riesgo aparece si añades pasos que ejecuten código del PR en el mismo job con pull_request_target.

¿Puedo usar un modelo local en CI? Sí, si el runner llega a tu Ollama o a tu pasarela (LiteLLM, por ejemplo): OCR_LLM_URL apunta a ella y OCR_LLM_USE_ANTHROPIC es false.

¿Cuánto tarda? Según el benchmark del proyecto, entre 1 y 8 minutos por PR real según el modelo. El workflow tiene un timeout-minutes: 30.

Conclusión

Con un archivo YAML, dos secretos y dos variables, cada pull request recibe una revisión con IA anclada a líneas, en tu idioma, con tus reglas y con el coste acotado. Es el punto en el que Open Code Review deja de ser una herramienta que lanzas tú y pasa a ser parte del proceso del equipo.

Con esto termina la guía. Si te la has saltado, empieza por qué es Open Code Review y cómo funciona por dentro, y si buscas más herramientas para tu agente, echa un vistazo a la guía de skills de Claude Code.

// código fuente

Repositorio del artículo
El código del que habla este artículo es público: revísalo, dale una estrella o clónalo desde aquí.

// kit para agencias

¿Haces webs para clientes con Claude Code?
5 skills que preparan la propuesta, crean la web, la revisan antes de entregarla y auditan la de tus prospectos, con una guía de 24 páginas probada en un caso real. Lo vende Safe Build Labs, la agencia que patrocina codigoagente.

// implementación

¿Necesitas implementar esta automatización en tu negocio?
No pierdas semanas configurando servidores, APIs y agentes. Safe Build Labs, la agencia que patrocina codigoagente, lo construye por ti, listo para producción.
Probamos mcp-builder, la skill de Anthropic para crear servidores MCP: hicimos uno para una tienda en 99 segundos por 0,25 USD y hallamos dos fallos de versión.
  • Skills para tus agentes
  • Claude Code
leer artículo
Probamos webapp-testing, la skill oficial de Anthropic que prueba tu web local con Playwright: instalación, with_server.py, dos trampas reales y cuánto cuesta.
  • Skills para tus agentes
  • Claude Code
leer artículo
video-shotcraft es una skill Apache-2.0 con 150 planos para que Claude Code haga el vídeo promo de tu web en Remotion. Cómo funciona y cuánto cuesta.
  • Skills para tus agentes
  • Claude Code
leer artículo