La automatización de procesos es clave para el incremento de nuestra productividad y nuestra eficiencia, pero la planificación y la organización también juegan un papel importante para conseguirlo. Como vimos en la lección sobre GitHub Projects, tenemos que ser organizados y no tener que invertir mucho tiempo en determinar qué hacer de entre todas las cosas que tenemos pendientes. GitHub Projects y GitHub Issues son claves en esta planificación y organización.

Al finalizar, sabrá:

  • Qué es GitHub Issues.

  • Qué es una propuesta y para qué se usan.

  • Cómo crear propuestas.

  • Cómo suprimir propuestas.

  • Cómo crear plantillas de propuestas.

Introducción

GitHub Issues es un servicio gratuito proporcionado por GitHub que, junto con GitHub Projects, permite la planificación y la organización del trabajo. Es importante tener claro que ambas herramientas se complementan la una a la otra. GitHub Projects permite tener una visión más global del proyecto repartida entre los distintos repositorios con los que trabajamos. En cambio, GitHub Issues está centrada en un determinado repositorio. Se recomienda el uso de ambos servicios para llevar a cabo una mejora en la organización del trabajo de nuestro proyecto.

De cara a GitHub Issues, una issue, en español traducido como propuesta o incidencia, no es más que algo a realizar o proponer para su realización. Puede representar una notificación de un fallo en el software que habría que corregir, una idea que gustaría se realizara, una funcionalidad a llevar a cabo, etc. Podemos verlo también como un trabajo (work) que hay que realizar. La idea es que no deberíamos ponernos a trabajar en algo sin tener su correspondiente issue o propuesta.

Por ejemplo, en el momento de escribir estas líneas, la redacción de este libro se realiza de la siguiente manera. Por un lado, tenemos un proyecto en GitHub Projects en el cual registramos las tareas o ítems propuestos, a realizar o a debatir para los libros de una determina serie editorial, en este caso, la de desarrollo de backends seguros. Para poder trabajar en algo, debe estar registrado en el proyecto, lo priorizamos para centrarnos, por un lado, en los más importantes con respecto a los de menos interés y, por otro lado, en los que tienen un hito más cercano. Una vez se termina un ítem, pasamos al siguiente, desplazando el ítem entre sus distintos estatus (Backlog, Todo, In Progress y Done). Cuando el ítem llega a Todo, no puede pasar a In Progress sin tener claro a qué repositorios va a afectar, por lo que habrá que crearle sus respectivas propuestas en los repositorios correspondientes con GitHub Issues. En nuestro caso, las propuestas se suelen crear primero y, a continuación, se asocian al proyecto correspondiente. Pero en ocasiones, es posible que se cree un ítem en el proyecto y, posteriormente, se cree su propuesta. La clave es que debe aparecer en el proyecto. Cuando llega su momento, se desplaza a In Progress, se tiene en cuenta los repositorios con los que hay que trabajar y manos a la obra. En este punto, se realiza el trabajo, se abre una solicitud de integración, se aprueba y se combina con la rama principal. Una vez hecho, se mueve a Done. ¡Y a por la siguiente tarea!

Siempre que hay una idea, se registra en el proyecto y, así, no se olvida. Si después se implementa o no, es otra historia. La clave es la planificación y la organización del trabajo para mejorar la productividad y reducir los tiempos muertos.

Lo mismo que se hace en la redacción de un libro, se hace, claro está, en el desarrollo de software. Generalmente, es más marcada la cosa porque el software es mucho más difícil de desarrollar que la escritura de un libro. Para quien escribe, ambas son difíciles, pero si tuviera que elegir cuál de las dos lo es más, sin ninguna duda, el desarrollo y el mantenimiento de software ganarían por goleada.

Concepto de propuesta (o issue)

Básicamente, podemos ver una propuesta (issue) como una tarea a realizar. Actualmente, se puede abrir propuestas para solicitar información al proyecto, para notificar incidencias o fallos, proponer funcionalidades, etc. Y todas ellas, son correctas. Aunque para las relacionadas con la información del proyecto, igual es mejor recurrir a GitHub Discussions, centrando las propuestas en incidencias, fallos, funcionalidades y cosas que describan algo que hacer.

A partir de ahora, utilizaremos principalmente el término propuesta, aunque en ocasiones usaremos también issue, porque son muchas las organizaciones que utilizan este término anglosajón, a pesar de la riqueza de nuestro maravilloso idioma.

Las propuestas se componen de varios elementos:

  • Un identificador (identifier) numérico incremental para distinguirlo del resto de manera única e inequívoca.

    Estos identificadores se usan en los comentarios precedidos de una almohadilla (#). Así, por ejemplo, en el siguiente ejemplo se muestra el título de una confirmación (commit) que indica la propuesta a la que está asociada: feat(github-pages): added Liquid filters (#85). Es real y está extraída del repositorio del libro sobre GitHub Pages.

  • Un título (title) que describe brevemente el objeto de la propuesta. La redacción de esta lección tiene el siguiente título lesson on GitHub Issues, cuyo identificador es #88.

  • Una descripción (description), una exposición inicial más detallada del objeto de la propuesta. Aquí nos extenderemos todo lo necesario. Recuerde que es posible que la propuesta no la acabe implementando quien la creó.

  • Unas etiquetas (labels) que sirven para categorizar la propuesta como, por ejemplo, enhancement si estamos ante un cambio que añada funcionalidad nueva o una mejora, bug si está relacionada con una notificación de fallo, documentation si estamos ante una mejora de documentación en un proyecto de software, etc.

    La redacción de esta lección se etiquetó como enhancement porque añade algo nuevo al libro.

  • Uno o más responsables (asignees), personas encargadas de llevarla a cabo y/o hacerle seguimiento según el tipo de propuesta. En este caso, el responsable de la propuesta para la redacción de esta lección fue un servidor.

  • Un proyecto (project), aquel de GitHub Projects que tiene asociada la propuesta. Recordemos que un ítem de proyecto puede tener asociadas varias propuestas del mismo o distinto repositorio.

  • Un hito (milestone) que indica en qué iteración se debe realizar. Es recomendable clasificar las propuestas en hitos para que no se escapen del que tienen asignado. Si las clasificamos en un hito u otro, cuando estemos trabajando en alcanzar uno determinado, cogeremos propuestas de ese hito y no de otro.

    Pero ojo, es posible que su proyecto esté relacionado con varios repositorios. Este es el caso de Akromio. El proyecto gestiona, en un punto centralizado, los cambios a realizar en varios repositorios, porque todos ellos forman el proyecto y sus cambios deben administrarse y organizarse de manera conjunta. En este caso, para controlar el hito como tal, o la iteración en la que un ítem se debe implementar, no se realiza mediante Milestone, sino mediante un campo When. Cada proyecto es un mundo y hay que ser flexibles y saber adaptarse a las circunstancias. En el caso de Akromio, hacerlo mediante Milestone conllevaría tener que registrar el mismo hito en todos los repositorios. Teniendo en cuenta que el proyecto tiene asociados más de diez repositorios, se hace inviable.

  • Una o más solicitudes de integración (pull requests) con las que se integrarán los cambios realizados durante la implementación de la propuesta en la rama correspondiente.

    Lo bueno de asignar solicitudes de integración a las propuestas es que cuando se cierra la solicitud automáticamente se cierra también la propuesta. Así, evita tener que ir a las propuestas y marcarlas como cerradas. Incluso si la propuesta está asociada a un proyecto, esto mandará el ítem asociado a la columna Done también de manera automática. En el caso de los ítems de proyecto, realmente esto es así debido a los flujos de trabajo de GitHub Projects que presentaremos más adelante en el libro.

Estado de las propuestas

El estado de una propuesta (issue state) indica la situación en la que se encuentra. Básicamente, abierta (opened) pendiente de atender o en proceso de desarrollo; y cerrada (closed), realizada o descartada por la razón que sea.

Creación de una propuesta

La creación de propuestas se puede hacer de muchas maneras. Nosotros vamos a presentar las principales, pero hay más como, por ejemplo, el comando gh issue create si necesita hacerlo de manera automatizada mediante un flujo de trabajos de GitHub Actions.

Creación de propuesta desde un ítem de proyecto

Si tenemos un ítem ya en un proyecto de GitHub Projects, la manera más sencilla de crear su correspondiente propuesta es como sigue:

  1. Ir al proyecto que contiene el ítem para el que deseamos crear su propuesta asociada.

  2. Hacer clic en el título del ítem, lo que abrirá su formulario de edición.

  3. Hacer clic en Convert to issue, en el panel derecho del formulario, lo que abrirá un menú contextual con los repositorios a los que tiene acceso:

    Creación de propuesta desde un ítem de proyecto

  4. Seleccionar el repositorio donde deseamos crear la propuesta.

    Si no aparece en la lista, escribir parte de su nombre en el cuadro Search repositories para que filtre aquellos que tengan ese texto.

En este punto, la propuesta ya se ha creado y el formulario del ítem del proyecto mostrará una versión compuesta del proyecto y la propuesta. La asignación de responsables, las etiquetas y el hito, por ejemplo, están enlazados a la propuesta, cualquier cambio en este formulario se traslada automáticamente a la propuesta. En cambio, otros campos como la prioridad hacen referencia al ítem del proyecto.

Para abrir la propuesta asociada al ítem del proyecto, haga clic en Open in new tab:

Apertura de propuesta desde ítem de proyecto

Creación de propuesta desde el repositorio de GitHub

En muchas ocasiones, las propuestas se crean antes que sus ítems correspondientes del proyecto. Esto puede suceder cuando proviene de una persona externa que no tiene acceso al proyecto, pero sí al repositorio. En estos casos, el proceso a seguir es el siguiente:

  1. Ir al repositorio de GitHub.

  2. Ir a la pestaña Issues.

  3. Hacer clic en New issue y rellenar la propuesta.

Cuando llegue el momento, puede asociar la propuesta al proyecto correspondiente haciendo clic en Projects:

Asignación de propuesta a un proyecto

Si tiene activado el flujo Item added to project del proyecto, al nuevo ítem se le asignará el estatus ahí indicado o, lo que es lo mismo, se añadirá a la columna correspondiente del tablero del proyecto. Ahora bien, si este flujo lo tiene desactivado, inicialmente se moverá a una columna inicial que no es Backlog. Pero puede moverla en la propia propuesta tras asignarle el proyecto.

Supresión de propuesta

Es posible suprimir una propuesta. La manera más sencilla es mediante GitHub, editando la propuesta y haciendo clic en Delete issue.

También puede hacerlo mediante el comando gh issue delete:

gh issue delete identificador

Plantillas de propuesta

Una plantilla de propuesta (issue template) es una descripción de un tipo de propuesta. No es lo mismo notificar un bug que proponer una mejora o funcionalidad. Por esta razón, se recomienda crear estas plantillas personalizadas en el repositorio para que las aperturas de nuevas propuestas proporcionen toda la información deseada según su tipo.

Estas plantillas se redactan en YAML, antiguamente en Markdown, y deben ubicarse en el directorio .github/ISSUE_TEMPLATE de la rama predeterminada del repositorio. Recordemos que la rama predeterminada suele ser master o main, según los convenios de la organización. El proyecto Akromio, https://github.com/akromio, utiliza plantillas; por ejemplo, consulte su repositorio nodejs-akromio, https://github.com/akromio/nodejs-akromio, como punto de partida. También puede consultar otros proyectos como https://github.com/Azure/azure-sdk-for-net.

Actualmente, los repositorios privados no soportan las plantillas de propuestas en la versión gratuita de GitHub.

A continuación, se muestra un ejemplo para la notificación de un bug:

# archivo: .github/ISSUE_TEMPLATE/bug-report.yaml

name: Bug report
description: Create a report for a bug
title: "[Bug] "
labels: [bug]
body:
  - type: input
    id: package
    attributes:
      label: Package name and version
      description: Name and version of the package used
      placeholder: ex. @owner/package-name x.y.z
    validations:
      required: true
  
  - type: textarea
    id: environment
    attributes:
      label: Environment
      description: |
        Please, provide info on your environment such as, for example,
        your Node.js, OS, etc.
      placeholder: Environment
    validations:
      required: true

  - type: textarea
    id: background
    attributes:
      label: Bug description
      description: Please, provide the description of issue you're seeing.
      placeholder: Description
    validations:
      required: true
  
  - type: textarea
    id: expected
    attributes:
      label: Expected behavior
      description: Please, provide a description of the expected behavior.
      placeholder: Expected
    validations:
      required: true

  - type: textarea
    id: repro-steps
    attributes:
      label: Reproduction Steps
      description: Please, include minimal steps to reproduce the problem if possible.
  
  - type: dropdown
    id: priority
    attributes:
      label: Priority
      description: Please, select the priority level for you
      options:
        - Critical
        - High
        - Medium
        - Low

  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: Please, copy and paste any relevant log output if possible
      render: shell

Formatos de las plantillas

Cada plantilla se creará en su propio archivo YAML dentro de .github/ISSUE_TEMPLATE. Este archivo debe contener las siguientes propiedades.

Propiedad name

Mediante la propiedad name se indica el nombre de la plantilla, el que se mostrará al usuario cuando vaya a crear una nueva propuesta. Debería ser el identificador del tipo de propuesta como, por ejemplo, Bug report, Enhancement request o Feature request. Cuando vaya a crear una propuesta, le aparecerá la lista de plantillas existente para que seleccione aquella que mejor se adapta a sus necesidades:

Selección de la plantilla de propuesta a utilizar

Propiedad description

La propiedad description proporciona una breve descripción de la plantilla. Tiene como objeto ayudar al usuario a determinar si es la plantilla que debe usar. En el ejemplo anterior, es lo que se muestra bajo el nombre de la plantilla.

Propiedad title

Con la propiedad title, indicamos el prefijo que se asociará a toda propuesta creada a partir de la plantilla. Por ejemplo, si la plantilla es para la notificación de un defecto, bug o fallo, podríamos desear que tuviera el prefijo [Bug]. Ejemplo:

title: "[Bug] "

Propiedad labels

La propiedad labels contiene las etiquetas predeterminadas para las propuestas creadas a partir de la plantilla. Ejemplo:

labels: [bug]

Propiedad assignees

Con la propiedad assignees, podemos indicar los responsables iniciales de las propuestas generadas con la plantilla. Debe ser el identificador de la cuenta de GitHub del responsable. Ejemplo:

assignees: [, yo]

Propiedad body

La descripción de las propuestas se indica en la propiedad body. Consiste en un array de elementos donde cada uno de ellos proporciona una sección de información que conoceremos como campos de datos (data fields). Se puede indicar tantos campos como sea necesario y todo dependerá del tipo de propuesta que se vaya a hacer. No pediremos la misma información para una notificación de bug que para una solicitud de nueva funcionalidad.

Campos de área de texto

Un campo con el que el usuario pueda introducir un texto puede ser de una única fila o múltiples. Para uno de una única fila, utilizaremos un elemento similar al siguiente:

type: input
attributes:
  label: título de la sección
  description: |
    breve descripción a mostrar al usuario
    con el objeto de la sección e incluso
    ejemplos si fuera necesario
  placeholder: texto de ejemplo que se mostrará al usuario
  value: texto inicial modificable por el usuario

El placeholder se utiliza para presentar al usuario un ejemplo o texto más descriptivo en la caja de texto donde debe escribir.

Para uno de varias filas:

type: textarea
attributes:
  label: título de la sección
  description: |
    breve descripción a mostrar al usuario
    con el objeto de la sección e incluso
    ejemplos si fuera necesario
  render: markdown  # lenguaje en el que se redactará
  placeholder: texto de ejemplo que se mostrará al usuario
  value: |
    Un texto inicial que se considerará
    como escrito por el usuario pero que puede
    modificar. Generalmente, una plantilla de lo
    que deseamos de quien crea la propuesta.
Cajas de verificación

Para una sección en la que el usuario debe confirmar uno o más posibles valores mediante cajas de verificación, usaremos:

type: checkboxes
id: identificador
attributes:
  label: título de la sección
  description: |
    breve descripción a mostrar al usuario
    con el objeto de la sección
  options:
    - label: texto de la opción 1
      required: true  # o false

    - label: texto de la opción 2
      required: true # o false
Desplegable

Para un desplegable del que el usuario debe seleccionar uno o más valores:

type: dropdown
id: identificador
attributes:
  label: título de la sección
  description: |
    breve descripción a mostrar al usuario
    con el objeto de la sección
  multiple: true  # o false
  options:
    - opción 1
    - opción 2
    - opción 3
Texto de descripción

Es posible mostrar un texto al usuario, pero que no forme parte de su propuesta mediante un elemento como el siguiente:

type: markdown
attributes:
  value: |
    el texto a mostrar al usuario en Markdown
Validaciones

Los campos de datos de una propuesta pueden tener una propiedad de validación (validation), una restricción que debe cumplir el campo. Para indicarle a GitHub que el usuario debe proporcionar una determinada información, o sea, tiene que suministrar un valor para el campo, utilizaremos la validación requerida (required validation). De manera predeterminada, todos los campos son opcionales. He aquí un ejemplo con el que el usuario deberá seleccionar una opción de un desplegable:

type: dropdown
id: priority
attributes:
  label: Priority
  description: Please, select the priority level for you
  options:
    - Critical
    - High
    - Medium
    - Low
validations:
  required: true

Creación de propuestas a partir de plantillas

Si el repositorio define plantillas de propuestas, cuando hagamos clic en Issues > New issue, GitHub listará las plantillas disponibles y nos pedirá que elijamos una de ellas. He aquí un ejemplo:

Selección de plantilla para nueva propuesta

En caso de que ninguna le resulte adecuada, puede crear una propuesta sin usar plantilla haciendo clic en Open a blank issue.

Comentarios de una propuesta

Cuando alguien hace una propuesta, podemos hacer cualquier tipo de comentario. Un comentario (comment) no es más que una solicitud de más información, una explicación o consideración adicional que pueda aportar información extra o un punto de vista complementario o alternativo a lo que se está proponiendo. Una propuesta no es algo estático que debe aceptarse tal cual. Abre un debate sobre su idoneidad y su perfilado que puede conducir a su cierre porque se considera innecesaria o inadecuada o bien a su aceptación con toda la información necesaria encima de la mesa.

Los comentarios se ubican justo debajo de la descripción de la incidencia. Se redactan en Markdown y pueden hacer referencia a:

  • Otras propuestas mediante #númeroPropuesta.

  • Personas con @nombreCuentaGitHub.

Le adjunto un ejemplo de propuesta con comentarios para que pueda hacerse una idea si no lo ha hecho nunca: https://github.com/Azure/azure-sdk-for-net/issues/32833.

Eventos de GitHub Actions relacionados con las propuestas

Al igual que hicimos en la lección Introducción a GitHub Projects, vamos a presentar algunos eventos disparadores de flujos de trabajo de GitHub Actions. Si necesita reaccionar ante un evento relacionado con las propuestas, puede volver aquí y echar un vistazo de nuevo.

Evento issues

El evento issues (issues event) se genera cada vez que ocurre algo relacionado con una propuesta. Mediante su propiedad types, la cual consiste en un array de textos, podemos afinar ante lo que deseamos reaccionar. Entre sus posibles valores encontramos:

Valor Descripción
opened Se acaba de crear una propuesta.
reopened Se acaba de reabrir una propuesta cerrada.
closed Se acaba de cerrar una propuesta.
deleted Se acaba de suprimir una propuesta.
assigned Se acaba de asignar una propuesta a alguien.
unassigned Se acaba de desasignar una propuesta a alguien.
labeled Se acaba de asignar una etiqueta a una propuesta.
unlabeled Se acaba de quitar una etiqueta a una propuesta.
locked Se acaba de bloquear una propuesta.
unlocked Se acaba de desbloquear una propuesta.
milestoned Se acaba de asignar un hito a una propuesta.
demilestoned Se acaba de desasignar el hito de una propuesta.

En el siguiente ejemplo, indicamos que el flujo de trabajo de GitHub Actions se ejecutará automáticamente cuando se cree una propuesta o se le asigne un hito:

on:
  issues:
    types: [opened, milestoned]

La información sobre el evento se encontrará en la propiedad event.issue del contexto github. Esta propiedad de tipo objeto contiene, entre otras, las siguientes propiedades que describen el evento:

Propiedad Descripción
repository Objeto repositorio que donde se encuentra la propuesta.
number Identificador numérico de la propuesta.
title Título de la propuesta.
body Contenido de la propuesta
assignees Quienes tienen asignada la propuesta.
state Estado de la propuesta: CLOSED u OPEN.
locked Valor booleano que indica si la propuesta está bloqueada.
url URL de la propuesta.

Evento issue_comment

El evento issue_comment (issue_comment event) se utiliza para disparar el flujo de trabajo cuando se produce alguna cosa relacionada con un comentario de una propuesta del repositorio. El evento también se puede perfilar con su propiedad types:

Valor Descripción
created Se acaba de crear un comentario de una propuesta.
edited Se acaba de editar un comentario de una propuesta.
deleted Se acaba de suprimir un comentario de una propuesta.

Ejemplo:

on:
  issue_comment:
    types: [created]

La propiedad event del contexto github proporciona un objeto con los datos del evento en cuestión, entre algunas de sus propiedades encontramos:

Propiedad Descripción
repository Objeto representativo del repositorio de la propuesta.
issue Objeto representativo de la propuesta afectada por el comentario.
author Nombre del usuario de GitHub que hizo algo en el comentario.
body Contenido del comentario en Markdown.
bodyText Contenido del comentario en texto plano.