32blogby Studio Mitsu

GitHub CLI (gh): patrones prácticos para PRs, issues y API

Domina GitHub CLI (gh) con patrones prácticos para PRs, issues y scripting con gh api y jq. Maneja GitHub completo desde tu terminal.

by omitsu18 min read
Contenido

gh es el CLI oficial de GitHub: un único binario en Go que te deja crear pull requests, gestionar issues, ver workflows en vivo y llamar a las APIs REST y GraphQL de GitHub sin abrir nunca el navegador. Las funciones estrella son gh pr create (de la rama al PR abierto en un solo comando), gh api --paginate --jq (acceso completo a REST/GraphQL conectado directamente a tus pipes), y gh run watch (estado de CI en vivo que sale con código distinto de cero si el workflow falla — perfecto para scripts). Tras instalarlo y ejecutar gh auth login una sola vez, todo lo demás vive dentro de tu terminal.

git termina en git push. Todo lo que ocurre después — abrir el PR, elegir revisores, leer comentarios, esperar a que la matriz de CI se ponga verde, mergear, borrar la rama, publicar la release — históricamente significaba saltar a una pestaña del navegador, pulsar tres menús y romper tu flujo cada vez. El coste es invisible pero enorme: un análisis de SmartScope de 2026 calcula 20 minutos diarios por desarrollador en tareas de PR en el navegador, y la mayor parte son clics mecánicos que un único comando gh reemplaza.

GitHub CLI es la respuesta oficial de GitHub al problema. Está escrito en Go — la única herramienta no-Rust de esta serie — y es la decisión correcta: Go tiene un cliente HTTP de primera clase en su librería estándar, compila a un binario único en cualquier plataforma y reutiliza los SDK internos de GitHub. El resultado es una herramienta que se siente como si hubiera nacido al lado de git mismo. Este artículo recorre los patrones del día a día: workflows de PR, triaje de issues, scripting con gh api y monitoreo de CI, con las recetas que vas a usar de verdad.

Por qué gh CLI une tu terminal con GitHub

git se terminó en 2005 y todavía hace su trabajo a la perfección. Pero la capa de plataforma encima — pull requests, code review, issue tracking, GitHub Actions — la atornilló la empresa diez años después, y durante años solo se podía usar desde la web. Ahí es donde encaja gh.

La palanca que gh te da consiste en eliminar cinco tipos de cambio de contexto:

  1. Abrir un PR. Sin gh: empujas la rama, copias la URL que imprime el remoto, la pegas en el navegador, pulsas "compare & pull request", rellenas el formulario y pulsas submit. Con gh pr create --fill, el título y el body salen de tus commits y el PR se abre en medio segundo.
  2. Leer comentarios de revisión. La UI por defecto entierra los comentarios inline bajo pestañas y timelines. gh pr view 123 --comments vuelca cada comentario, en hilos, dentro de tu terminal donde puedes hacer grep, scroll y copiar código.
  3. Comprobar el estado de CI. gh pr checks muestra el estado vivo de cada workflow del PR, y gh run watch se queda enganchado a un workflow con --exit-status para que puedas encadenarlo con && notify-send done.
  4. Scripting de la API. ¿Necesitas listar todos los issues abiertos de una organización, todos los tags de release, todos los PRs etiquetados como bug? gh api --paginate --jq es curl + jq + token de auth + paginación en un único comando, con la auth resuelta una vez por gh auth login.
  5. Workflows propios. gh extension install te deja añadir extensiones de la comunidad o escribir las tuyas — gh dash para un dashboard TUI, gh poi para limpiar ramas, gh-pr-await para vigilar cambios en un PR.

Cada una de estas cosas sería medio día de shell scripting si tuvieras que hacerla a pelo con curl y un flujo OAuth artesanal. gh viene con todo eso ya cableado.

Instalar gh y autenticarse

Instalación = un paquete + un login interactivo. La página oficial de instalación lista todas las plataformas; el resumen rápido está debajo.

powershell
# winget (incluido en Windows 11)
winget install GitHub.cli

# o Scoop
scoop install gh

# o Chocolatey
choco install gh

Después de instalar, ejecuta gh --version y luego autentícate una vez:

bash
gh auth login

Esto lanza un prompt interactivo: eliges GitHub.com (o un host de GitHub Enterprise), eliges HTTPS o SSH para las operaciones git y seleccionas Login with a web browser. gh imprime un código de 8 caracteres y abre el navegador — pegas el código, apruebas los scopes OAuth y el token queda guardado en el llavero del SO (Keychain en macOS, Credential Manager en Windows, libsecret en Linux).

Una vez autenticado, dos comandos verifican que todo va bien:

bash
gh auth status
gh api user --jq '.login'

El primero te dice en qué host estás logueado y qué scopes tiene tu token. El segundo llama a la API de GitHub como tú e imprime tu nombre de usuario — si los dos funcionan, el resto de los comandos del artículo también funcionará.

Workflows de PR: de gh pr create a gh pr merge

Esta es la sección que paga la instalación. El bucle diario completo cabe en unos seis comandos.

Crear un PR

Después de git push -u origin mi-rama, la creación más simple es una línea:

bash
gh pr create --fill

--fill toma el último mensaje de commit y lo usa como título y body. Si quieres control explícito:

bash
gh pr create \
  --title "Arregla regresión del estado hover en delta" \
  --body "Closes #142. El handler de hover se disparaba dos veces." \
  --base main \
  --reviewer omitsu-dev,@studio-mitsu/reviewers \
  --label bug,frontend \
  --assignee @me \
  --draft

Los ejemplos oficiales cubren las flags menos comunes (--project, --milestone, --template). Un patrón que vale la pena recordar: --reviewer acepta personas y slugs de equipo @org/team en la misma flag, así que una sola línea pide review a una persona y a todo un equipo.

Si tu rama todavía no está empujada, gh pr create te ofrece empujarla — di que sí y la rama llega al remoto y el PR se abre en el mismo paso.

Ver y leer un PR

bash
gh pr view 142                  # Resumen Markdown en tu terminal
gh pr view 142 --comments       # Más cada comentario de revisión, en hilos
gh pr view 142 --web            # Abre en el navegador si necesitas la UI rica
gh pr diff 142                  # Diff unificado plano
gh pr diff 142 | delta          # Pasa por delta para syntax highlight side-by-side

Esa última línea es justo la razón por la que cubrimos delta en el artículo anterior. gh pr diff | delta es lo más cerca que un terminal llega a la pestaña Files Changed de GitHub — y va más rápido.

Revisar y aprobar

bash
gh pr checkout 142              # Checkout local de la rama del PR (maneja forks)
gh pr review 142 --approve --body "LGTM, lánzalo"
gh pr review 142 --request-changes --body "Mira los comentarios inline"
gh pr review 142 --comment --body "Algunas dudas más abajo"

gh pr checkout es el que toca recordar — gestiona forks cruzados (user:branch) y configura la upstream tracking branch correctamente para que los git push posteriores no peten.

Mergear y limpiar

bash
gh pr merge 142 --squash --delete-branch
gh pr merge 142 --merge --auto      # auto-merge: espera a las checks obligatorias
gh pr merge 142 --rebase --delete-branch

La flag --auto cambia cómo trabajas: actívala en un PR draft, marca el PR como ready for review, y gh lo mergeará en el momento exacto en que pasen todas las checks obligatorias. Se acabó vigilar CI.

Workflows de issues: buscar, triar y comentar

Los issues reciben menos cariño que los PRs, pero gh issue es donde el mantenimiento masivo se vuelve rápido. La sintaxis de búsqueda de issues es la misma que en la UI web, así que todo lo que ya sabes se transfiere.

bash
# Issues abiertos asignados a ti
gh issue list --assignee @me --state open

# Buscar por etiqueta y autor
gh issue list --search "is:open label:bug author:omitsu-dev"

# Crear uno rápido
gh issue create --title "El estado hover se rompe en Safari móvil" \
  --body "Reproducido en iOS 18.3. Hay captura." \
  --label bug,mobile

# Leerlo
gh issue view 142 --comments

# Comentar, cerrar, reabrir
gh issue comment 142 --body "Arreglado en #198."
gh issue close 142 --reason completed
gh issue reopen 142

La combinación que te ahorra horas son las operaciones masivas con pipes. Imagina que quieres cerrar todos los issues con etiqueta wontfix que llevan más de seis meses sin tocarse:

bash
gh issue list \
  --label wontfix \
  --search "updated:<2025-10-10" \
  --json number \
  --jq '.[].number' |
  xargs -I{} gh issue close {} --reason "not planned"

Dos cosas a notar. La primera: --json devuelve JSON estructurado en vez de la tabla para humanos — esa es la flag mágica que convierte a gh de UI a herramienta de scripting. La segunda: el resultado se canaliza por xargs exactamente como describe el mapa de herramientas CLI. En este momento gh deja de ser una comodidad y empieza a ser un multiplicador de fuerza.

gh api: scripting de GitHub con jq y paginación

gh api es la pieza que convierte a gh de herramienta de productividad en cimiento de tu automatización. Es curl + autenticación + paginación + filtrado JSON, todo en un comando, usando el token que ya tienes de gh auth.

La forma básica:

bash
gh api repos/cli/cli/releases/latest --jq '.tag_name'
# v2.89.0

Eso es todo. gh api PATH es un GET contra https://api.github.com/PATH, con el token ya enganchado. --jq pasa la respuesta por jq e imprime el resultado. Sin headers, sin paginación, sin auth — gh se encarga de todo.

Filtrado y plantillas

bash
# Las últimas 10 releases de un repo: tag + fecha
gh api repos/cli/cli/releases \
  --jq '.[0:10] | .[] | "\(.tag_name)\t\(.published_at)"'

# Los mismos datos con plantillas Go en lugar de jq
gh api repos/cli/cli/releases \
  -t '{{range .}}{{.tag_name}}{{"\t"}}{{.published_at}}{{"\n"}}{{end}}'

La flag -t es una funcionalidad oculta valiosa: cuando no tienes jq instalado (un contenedor minimalista, por ejemplo), las plantillas Go cubren la mayoría de lo que necesitas.

Paginación

GitHub pagina casi cada endpoint de listado en bloques de 30 por defecto. Para obtenerlos todos:

bash
gh api --paginate repos/cli/cli/issues --jq '.[].number'

--paginate sigue el header Link: rel="next" hasta que la API se queda sin páginas. Hay una limitación actual a tener en cuenta: según el issue #10459, --paginate --slurp --jq no se pueden combinar. Usa --paginate --jq (jq corre en cada página) o --paginate --slurp (junta todas las páginas en un único array JSON y luego pipeas a jq aparte).

POST, PATCH, DELETE

bash
# Comentar en un issue
gh api repos/omitsu-dev/32blog/issues/142/comments \
  -f body='Arreglado en 0a1b2c3.'

# Añadir una etiqueta
gh api repos/omitsu-dev/32blog/issues/142/labels \
  -f labels[]=bug -f labels[]=frontend

# DELETE de una release
gh api -X DELETE repos/omitsu-dev/32blog/releases/12345

-f envía un campo string estático, -F envía un campo tipado (números, booleanos, contenidos de fichero con @path). La sintaxis @- incluso lee de stdin, así que cat body.md | gh api ... -F body=@- es trivial.

GraphQL

El mismo comando habla con el endpoint GraphQL. El recorrido oficial del blog de GitHub merece un bookmark.

bash
gh api graphql -F owner=cli -F name=cli -f query='
  query($owner:String!, $name:String!) {
    repository(owner:$owner, name:$name) {
      stargazerCount
      defaultBranchRef { name }
    }
  }
' --jq '.data.repository'

La paginación en GraphQL necesita una cláusula pageInfo { hasNextPage, endCursor } y la variable mágica $endCursor: String — la plantilla completa está en el manual de gh api. Con eso en su sitio, --paginate --slurp recorre todas las páginas automáticamente.

gh run watch, extensiones y aliases

La última capa es todo lo que convierte a gh en tu dashboard personal del terminal.

Vigilar CI

bash
gh run list                          # Workflows recientes
gh run view 1234567890               # Un run, con desglose de jobs/steps
gh run view 1234567890 --log         # Streaming de todos los logs
gh run view --log-failed             # Solo los steps fallados
gh run watch                         # Estado en vivo del último run en marcha
gh run watch --exit-status           # Sale con código distinto de cero si falla
gh run rerun 1234567890 --failed     # Reintenta solo los jobs fallados
gh pr checks                         # Estado de cada check del PR actual

gh run watch --exit-status es la piedra angular de los scripts. Según el manual de gh run watch, sondea cada 3 segundos (configurable con -i) y sale con código distinto de cero si el workflow falla — así que puedes encadenarlo con cualquier cosa:

bash
git push && gh run watch --exit-status && notify-send "Build verde"

La notificación salta cuando el build está realmente verde, no cuando te has acordado de mirar la pestaña del navegador.

Extensiones

bash
gh extension install dlvhdr/gh-dash       # Dashboard TUI para PRs e issues
gh extension install yusukebe/gh-markdown-preview
gh extension list
gh extension upgrade --all
gh extension remove gh-dash

El manual de extensiones explica cómo escribir las tuyas — una extensión es solamente un ejecutable llamado gh-foo en tu $PATH, así que un script bash de una línea ya cuenta.

Aliases

bash
gh alias set prs 'pr list --author @me'
gh alias set bugs 'issue list --label bug --state open'
gh alias set ship 'pr merge --auto --squash --delete-branch'
gh alias list

Los aliases viven en ~/.config/gh/config.yml y son sustituciones de string simples. Para algo más flexible (multipaso, lógica condicional), combínalo con la guía de aliases de shell y escribe una función envoltura.

Sobre la extensión gh-copilot

Si en 2026 estás buscando gh copilot suggest, la respuesta cambió: la extensión gh-copilot se retiró el 25 de octubre de 2025. El reemplazo es el GitHub Copilot CLI standalone (binario copilot, actualmente v1.0.22 a fecha de 9 de abril de 2026), que ya no es una extensión de gh — es un asistente agéntico independiente que se instala con brew install copilot-cli o npm install -g @github/copilot. Los aliases viejos ghcs/ghce siguen funcionando para quienes instalaron la extensión antes del retiro, pero las nuevas instalaciones tienen que usar la herramienta standalone.

FAQ

Q. ¿gh y git son lo mismo? No. git gestiona commits y ramas locales; gh gestiona todo lo que vive en GitHub mismo — PRs, issues, releases, runs de workflow y la API. Son complementarias. gh no reemplaza ningún comando de git; añade la capa específica de GitHub encima.

Q. ¿Funciona gh con GitHub Enterprise Server? Sí. Pasa --hostname tu-ghes.example.com a gh auth login y todos los comandos siguientes apuntan a ese host. Puedes estar logueado en varios hosts a la vez y cambiar entre ellos con gh auth switch.

Q. ¿Puedo crear PRs draft desde un script? Sí — gh pr create --draft --fill es la one-liner. Para promocionar un draft a ready: gh pr ready 142.

Q. ¿Cómo listo todos los PRs que he abierto en todos los repos? gh search prs --author @me --state all --limit 1000. La familia gh search golpea la búsqueda global de GitHub y es la herramienta correcta para queries multi-repo — mucho más rápida que iterar gh pr list por repositorio.

Q. ¿Cómo meto la salida de gh api en una variable de shell? Sustitución de comando + --jq para sacar exactamente el campo que necesitas: tag=$(gh api repos/cli/cli/releases/latest --jq .tag_name). Pon comillas siempre que reuses la variable.

Q. ¿Diferencia entre gh run watch y gh pr checks? gh pr checks es una snapshot puntual del estado de los workflows del PR actual. gh run watch es un tail en vivo que bloquea hasta que un único run de workflow termina — y sale con código distinto de cero al fallar, lo que lo hace scriptable.

Q. ¿gh está en Go porque GitHub es una shop de Go? Más o menos. Los servicios internos de GitHub son una mezcla de Ruby y Go, pero el CLI se construyó deliberadamente en Go porque produce un binario estático único por plataforma sin runtime, y su standard library trae un cliente HTTP de primera. Las mismas razones por las que la mayoría de las CLI modernas eligen Rust o Go en lugar de Ruby/Python.

Q. ¿gh copilot suggest sigue funcionando? Solo si instalaste la extensión gh-copilot antes del 25 de octubre de 2025 y nunca la desinstalaste. Las nuevas instalaciones están bloqueadas porque la extensión está retirada. Usa el GitHub Copilot CLI standalone — es la ruta soportada de aquí en adelante.

Conclusión

gh es la mitad que le falta a git. La división es histórica (Git es tres años más viejo que GitHub y seis años más viejo que las pull requests), pero el resultado práctico es que para la mayoría de desarrolladores en 2026, la mitad del trabajo diario en GitHub vive en una pestaña del navegador que nadie pidió. gh colapsa esa pestaña y la mete de vuelta en la terminal, donde ya están todas tus otras herramientas.

Los cuatro comandos que pagan la instalación:

  1. gh pr create --fill — abre un PR desde tu último commit con una sola tecla.
  2. gh pr diff | delta — lee el diff como en una herramienta de code review, dentro de tu terminal.
  3. gh api --paginate --jq — script GitHub como si fuera una base de datos local.
  4. gh run watch --exit-status — bloquea CI dentro de scripts y bucles de shell.

Combina gh con delta para diffs, bat para ver ficheros tras un checkout de PR, ripgrep para buscar dentro de repos clonados, y fzf para elegir números de PR de forma interactiva, y todo tu trabajo diario en GitHub cabe en una sola ventana de terminal. Esa es la meta de la serie de CLI modernas — y gh es la pieza que ata toda la capa de plataforma al resto de tu flujo de trabajo.