20  Prácticas de desarrollo de software

En esta última parte del libro, nos alejamos para considerar prácticas de desarrollo que pueden hacerlo más productivo y elevar la calidad de su trabajo. Aquí discutiremos el uso del control de versiones y la integración continua. En Capítulo 21 analizamos cómo varía la naturaleza del mantenimiento del paquete a lo largo del ciclo de vida de un paquete.

Notarás que recomendamos utilizar ciertas herramientas:

Se podría pensar que estas herramientas de estilo profesional son excesivas para alguien que no se gana la vida desarrollando software. Si bien no recomendamos obligarse a hacer todo lo anterior el primer día de su primer proyecto de “hola mundo”, en realidad creemos que estas herramientas son ampliamente aplicables para el desarrollo de paquetes R.

La razón principal es que estas herramientas hacen que sea mucho más fácil hacer lo correcto, por ejemplo, experimentar, documentar, probar, verificar y colaborar. Al adoptar un conjunto de herramientas compartido, los desarrolladores de paquetes nuevos y a tiempo parcial obtienen acceso a los mismos flujos de trabajo utilizados por los expertos. Esto requiere cierta fe e inversión inicial, pero creemos que vale la pena.

20.1 Git y GitHub

Git es un sistema de control de versiones que se creó originalmente para coordinar el trabajo de un grupo global de desarrolladores que trabajan en el kernel de Linux. Git gestiona la evolución de un conjunto de archivos — llamado repositorio — de una manera altamente estructurada y recomendamos que cada paquete R también sea un repositorio Git (y también, probablemente, un proyecto RStudio; Sección 4.2).

Un desarrollador independiente que trabaje en una sola computadora se beneficiará al adoptar el control de versiones. Pero, para la mayoría de nosotros, ese beneficio no es lo suficientemente grande como para compensar el dolor de instalar y usar Git. En nuestra opinión, para la mayoría de las personas, las ventajas de Git solo superan las desventajas una vez que das el paso adicional de conectar tu repositorio local a un host remoto como GitHub. El uso conjunto de Git y GitHub ofrece muchos beneficios que justifican con creces la curva de aprendizaje.

20.1.1 Práctica estándar

Esta recomendación está bien alineada con las prácticas generales actuales en el desarrollo de software. A continuación se muestran algunos datos relevantes de la encuesta para desarrolladores de Stack Overflow de 2022, que se basa en aproximadamente 70.000 respuestas.

  • El 94% reporta usar Git. El segundo sistema de control de versiones más utilizado fue SVN, utilizado por el 5% de los encuestados.

  • Para proyectos personales, el 87% de los encuestados afirma utilizar GitHub, seguido de GitLab (21%) y Bitbucket (11%). La clasificación es la misma, aunque menos sesgada para el trabajo profesional: GitHub sigue dominando con un 56%, seguido de GitLab (29%) y Bitbucket (18%).

Incluso podemos aprender un poco sobre los hábitos de los desarrolladores de paquetes R, basándonos en las URL que se encuentran en los archivos DESCRIPTION de los paquetes CRAN. En marzo de 2023, hay alrededor de 19.000 paquetes en CRAN, de los cuales aproximadamente el 55 % tienen un campo “URL” no vacío (más de 10.000). De ellos, el 80% tiene una URL de GitHub (más de 8K), seguido de GitLab (poco más del 1%) y Bitbucket (alrededor del 0,5%).

La prevalencia de Git/GitHub, tanto dentro de la comunidad R como más allá, debería ayudarle a sentirse seguro de que la adopción tendrá beneficios tangibles. Además, la gran popularidad de estas herramientas significa que hay muchos recursos disponibles para aprender a usar Git y GitHub y para despegarse1.

Dos recursos específicos que abordan la intersección de Git/GitHub y el mundo R son el sitio web Happy Git y GitHub para el usuarioR y el artículo “Disculpe, ¿tiene ¿Un momento para hablar sobre el control de versiones?” (Bryan 2018).

Concluimos esta sección con algunos ejemplos de por qué Git/GitHub puede ser valioso específicamente para el desarrollo de paquetes R:

  • Comunicación con los usuarios: los problemas de GitHub son adecuados para recibir informes de errores y solicitudes de funciones. A diferencia del correo electrónico enviado al responsable, otras personas pueden acceder a estas conversaciones y realizar búsquedas.

  • Colaboración: las solicitudes de extracción de GitHub son una forma muy sencilla para que los contribuyentes externos ayuden a corregir errores y agregar funciones.

  • Distribución: Funciones como devtools::install_github("r-lib/devtools") y pak::pak("r-lib/devtools") permiten a las personas instalar fácilmente la versión de desarrollo de su paquete, según un repositorio de fuentes. De manera más general, cualquiera puede instalar su paquete desde cualquier referencia de Git válida, como una rama, un SHA específico, una solicitud de extracción o una etiqueta.

  • Sitio web: GitHub Pages es una de las formas más sencillas de ofrecer un sitio web para su paquete (Sección 19.2).

  • Integración continua: este es en realidad el tema de la siguiente sección, así que sigue leyendo para obtener más información.

20.2 Integración continua

Como dijimos en la introducción, la integración y el despliegue continuos se abrevian comúnmente como CI/CD o simplemente CI. Para el desarrollo de paquetes R, lo que esto significa en la práctica es:

  1. Alojas tu paquete fuente en una plataforma como GitHub. El punto clave es que el repositorio alojado proporciona la estructura formal para integrar el trabajo de múltiples contribuyentes. A veces, varios desarrolladores tienen permiso para enviar (así es como se administran los paquetes tidyverse y r-lib). En otros casos, sólo el responsable principal tiene permiso de inserción. En cualquiera de los modelos, los contribuyentes externos pueden proponer cambios mediante una solicitud de extracción.

  2. Configura una o más tareas de desarrollo para que se ejecuten automáticamente cuando ocurren ciertos eventos en el repositorio alojado, como una solicitud de inserción o extracción. Por ejemplo, para un paquete R, es extremadamente valioso configurar una ejecución automática de R CMD check. Esto le ayuda a descubrir roturas rápidamente, cuando es más fácil de diagnosticar y reparar, y es de gran ayuda para evaluar si acepta una contribución externa.

En general, el uso del control de versiones alojado y la integración continua pueden hacer que el desarrollo avance más fluida y rápidamente.

Incluso para un desarrollador en solitario, ejecutar “R CMD check” de forma remota, posiblemente en un par de sistemas operativos diferentes, es un arma poderosa contra el temido problema de “funciona en mi máquina”. Especialmente para los paquetes destinados a CRAN, el uso de CI disminuye la posibilidad de sorpresas desagradables justo antes del lanzamiento.

20.2.1 Acciones de GitHub

TLa forma más sencilla de empezar a utilizar CI es alojar su paquete en GitHub y utilizar su servicio complementario, GitHub Actions (GHA). Luego puede utilizar varias funciones de usethis para configurar los llamados flujos de trabajo GHA. usethis copia los archivos de configuración del flujo de trabajo de r-lib/actions, que es donde el equipo de tidyverse mantiene la infraestructura de GHA útil para la comunidad R.

20.2.2 R CMD check a través de GHA

Si solo usa CI para una cosa, debería ser ejecutar “R CMD check”. Si llama a usethis::use_github_action() sin argumentos, puede elegir entre algunos de los flujos de trabajo más útiles. Así es como se ve ese menú al momento de escribir este artículo:

> use_github_action()
Which action do you want to add? (0 to exit)
(See <https://github.com/r-lib/actions/tree/v2/examples> for other options) 

1: check-standard: Run `R CMD check` on Linux, macOS, and Windows
2: test-coverage: Compute test coverage and report to https://about.codecov.io
3: pr-commands: Add /document and /style commands for pull requests

Selection: 

check-standard es muy recomendable, especialmente para cualquier paquete que esté (o aspire a estar) en CRAN. Ejecuta R CMD check en algunas combinaciones de sistema operativo y versión R. Esto aumenta sus posibilidades de detectar rápidamente código que depende de las idiosincrasias de una plataforma específica, al tiempo que sigue siendo fácil hacer que el código sea más portátil.

Después de hacer esa selección, verá algunos mensajes como este:

#> ✔ Creating '.github/'
#> ✔ Adding '*.html' to '.github/.gitignore'
#> ✔ Creating '.github/workflows/'
#> ✔ Saving 'r-lib/actions/examples/check-standard.yaml@v2' to .github/workflows/R-CMD-check.yaml'
#> • Learn more at <https://github.com/r-lib/actions/blob/v2/examples/README.md>.
#> ✔ Adding R-CMD-check badge to 'README.md'

Las cosas clave que suceden aquí son:

  • Se escribe un nuevo archivo de flujo de trabajo de GHA en .github/workflows/R-CMD-check.yaml. Los flujos de trabajo de GHA se especifican mediante archivos YAML. El mensaje revela la fuente de YAML y ofrece un enlace para obtener más información.

  • Se pueden realizar algunas adiciones útiles a varios archivos “ignorados”.

  • Se agrega una insignia que informa el resultado de R CMD check a su archivo README, si se creó con usethis y tiene una insignia identificable “área de estacionamiento”. De lo contrario, se le proporcionará un texto que podrá copiar y pegar.

Confirme estos cambios de archivos y envíelos a GitHub. Si visita la sección “Acciones” de su repositorio, debería ver que se ha iniciado una ejecución de flujo de trabajo de GHA. A su debido tiempo, su éxito (o fracaso) se informará allí, en su insignia README y en sus notificaciones de GitHub (dependiendo de su configuración personal).

¡Felicidades! Su paquete ahora se beneficiará de controles aún más regulares.

20.2.3 Otros usos de GHA

Como lo sugiere el menú interactivo, usethis::use_github_action() le brinda acceso a flujos de trabajo prediseñados distintos de R CMD check. Además de las opciones destacadas, puede usarlo para configurar cualquiera de los flujos de trabajo de ejemplo en r-lib/actions pasando el nombre del flujo de trabajo. Por ejemplo:

  • use_github_action("test-coverage") configura un flujo de trabajo para rastrear la cobertura de prueba de su paquete, como se describe en Sección 14.1.1.

Dado que GHA le permite ejecutar código arbitrario, hay muchas otras cosas para las que puede usarlo:

  • Construir el sitio web de su paquete e implementar el sitio renderizado en GitHub Pages, como se describe en Sección 19.2. Véase también ?usethis::use_pkgdown_github_pages().

  • Volver a publicar el sitio web de un libro cada vez que se realiza un cambio en la fuente. (¡Como lo hacemos con este libro!).

Si los flujos de trabajo de ejemplo no cubren su caso de uso exacto, también puede desarrollar su propio flujo de trabajo. Incluso en este caso, los flujos de trabajo de ejemplo suelen resultar útiles como inspiración. El repositorio r-lib/actions también contiene importantes bloques de construcción de nivel inferior, como acciones para instalar R o instalar todos los dependencias indicadas en un archivo DESCRIPTION.


  1. Presentamos GitHub aquí, para el control de versiones alojadas, porque es lo que usamos y lo que tiene el mejor soporte en devtools. Sin embargo, todos los principios generales e incluso algunos detalles son válidos para plataformas alternativas, como Gitlab y Bitbucket.↩︎