Pull Requests, una guía de buenas prácticas

Esta es una guía desde la experiencia propia, durante mi carrera como desarrollador he revisado cientos, sino miles de pull requests, es un proceso aparentemente simple, pero para que cumpla su objetivo es recomendado seguir algunas prácticas que traemos en este artículo. Quiero expresar que esta es una entrada de opinión, la tuya puede diferir de esta y lo respeto.

¿Qué es un Pull Request ?

Un Pull Request (PR) es una solicitud que un desarrollador hace a los miembros del equipo para que revisen y consideren los cambios que ha realizado en un proyecto. Se utiliza comúnmente en plataformas de control de versiones como GitHub, GitLab o Bitbucket.

El proceso comienza cuando un desarrollador crea una nueva rama (branch) en el repositorio para implementar nuevas funcionalidades, corregir errores o realizar cualquier tipo de modificación en el código. Una vez que el desarrollo en la nueva rama está completo y se han realizado pruebas locales, el desarrollador solicita la integración de esos cambios en la rama principal del repositorio a través de un Pull Request.

El uso de Pull Requests facilita la colaboración entre desarrolladores proporcionando un marco para la mejora del código y el crecimiento del equipo de desarrollo.

Es, o debe ser una práctica obligatoria en todos los equipos de desarrollo.

A continuación la lista de buenas practicas.

Mantén pequeña la solicitud de cambios

Este es el elemento mas importante de un Pull Request. Un PR grande es difícil de revisar. Existe una idea en muchos programadores de que si es larga la lista de cambios no se revisa, lo cual va contra el objetivo del PR, entonces mejor, mantenlo chico.

Dividir el trabajo en cambios pequeños y específicos tiene varios beneficios. Primero, facilita la revisión por parte de los compañeros, ya que cada cambio es más manejable y comprensible. Esto ayuda a identificar y corregir problemas de manera más eficiente. Además, reduce el riesgo de introducir errores difíciles de detectar en la revisión, ya que los cambios son más localizados y específicos. Un PR pequeño y bien definido también es más fácil de integrar en el código base (se evitan los posibles conflictos, o al menos se reduce la posibilidad de ellos), lo cual mejora la agilidad del desarrollo y reduce el tiempo entre la implementación y la entrega.

Mantén el código fácil de leer

Escribir código claro y comprensible es fundamental para la mantenibilidad a largo plazo del software, es un principio básico del desarrollo (KISS), es, además fundamental que sea legible para que al revisor le sea sencillo entender y revisar. Esto implica utilizar nombres significativos para variables, métodos y clases, así como seguir las convenciones de estilo de código establecidas en el proyecto.

Un código bien estructurado no solo facilita su comprensión por parte de otros desarrolladores, sino que también hace que sea más fácil de depurar y mantener en el futuro. La legibilidad del código es clave para la colaboración efectiva dentro del equipo, ya que permite a los desarrolladores trabajar de manera más eficiente y reducir la posibilidad de introducir errores al realizar modificaciones.

Incluye pruebas unitarias a tus cambios

Las pruebas unitarias son fundamentales para garantizar la calidad del software. Acompañar tus cambios con pruebas unitarias adecuadas asegura que las nuevas funcionalidades funcionen correctamente y que los cambios no introduzcan problemas en el código (o al menos reduce la posibilidad de ello).

Esto proporciona una capa adicional de seguridad al validar el comportamiento esperado del código en diferentes situaciones.

Las pruebas unitarias actúan como “documentación natural”, mostrando cómo se supone que deben utilizarse los métodos y componentes del código. En conjunto con una integración continua robusta, las pruebas unitarias automatizadas permiten detectar y corregir errores de manera temprana, lo que reduce los costos y el tiempo asociados con la corrección de errores en etapas avanzadas del desarrollo, disminuyendo como punto fundamental la capacidad de introducir bugs en el entorno de producción.

Incluye documentación junto a la solicitud de cambios

Adjunta, junto a los commits de tu código y junto a la solicitud de cambios al menos la información del ticket de la feature/bug que estas sumando/solucionando. Proporcionar documentación clara y concisa junto con tu código es fundamental para facilitar su comprensión del revisor y que este pueda tener contexto de lo que esta revisando.

Si el cambio que se esta introduciendo es complejo, es útil adjuntar diagramas de flujo o cualquier otra información que contribuya a que el/los revisores puedan comprender la magnitud e impacto de los cambios. Esto incluye explicar el propósito del cambio, cómo se debe probar y cualquier consideración especial que deba tenerse en cuenta al revisar o integrar los cambios. La documentación puede incluir detalles sobre el diseño y la arquitectura, decisiones de implementación y consideraciones de rendimiento o seguridad.

Además, documentar las interfaces públicas y las dependencias ayuda a los desarrolladores a entender cómo interactuar con el código modificado de manera efectiva. Una buena práctica es mantener la documentación actualizada a medida que evoluciona el código, asegurando que siempre esté sincronizada con las últimas modificaciones y mejoras. Para el caso de cambios de arquitectura o actualización de elementos relevantes de la misma puede usarse la variante de diagrama como código, como por ejemplo C4, que es versionable y puede evolucionar junto al código de forma simple.

Sigue un único estilo de codificación

La consistencia en el estilo de codificación es importante para mantener la legibilidad y la coherencia en todo el código base del proyecto. Esto incluye aspectos como la indentación, el uso de espacios o tabulaciones, el formato de los comentarios y la disposición de los bloques de código.

Seguir un único estilo de codificación facilita la lectura y la comprensión del código por parte de los desarrolladores, especialmente cuando trabajan en diferentes partes del proyecto o cuando se integran cambios de múltiples programadores. Utilizar herramientas automáticas de formateo de código puede ayudar a mantener el orden y reducir las discusiones sobre estilos personales, permitiendo que el equipo se enfoque en aspectos más críticos del desarrollo de software.

Evita mezclar nuevas funcionalidades con refactorización

Nunca mezcles nuevas features o resolución de bugs con refactorización del código. Separar los cambios que introducen nuevas funcionalidades de aquellos que se centran en la refactorización del código existente ayuda a mantener la claridad y la transparencia en los PR. Mezclar estos tipos de cambios puede dificultar la revisión y la comprensión de los objetivos específicos de cada solicitud de cambios.

Centrarse en un tipo de cambio a la vez permite una implementación más controlada y una mejor evaluación de su impacto en el código y en el producto final. Esto facilita también la identificación y la resolución de problemas relacionados con cada tipo de cambio por separado, mejorando así la calidad y la estabilidad del software en general.

Pasa los cambios por herramientas de análisis estático

Siempre tenemos que tratar de que cuando el código llegue al/los revisores arribe con los menores problemas posibles. Utilizar herramientas de análisis estático es fundamental para identificar y corregir problemas potenciales (y code smells) antes de que el código sea revisado por otros desarrolladores.

Estas herramientas pueden detectar errores de sintaxis, problemas de rendimiento, violaciones de buenas prácticas de programación y vulnerabilidades de seguridad. Corregir estos problemas temprano en el proceso de revisión de código ayuda a mejorar la calidad del software y a reducir el tiempo necesario para realizar cambios y correcciones.

Integrar herramientas de análisis estático en el flujo de trabajo de desarrollo (incluso local, por ejemplo sonarlint que se integra con IDEs como Intellij) garantiza que los estándares de calidad y las mejores prácticas se mantengan consistentemente en todo el código base del proyecto.

Elige las personas adecuadas para revisar tu código

No solo basta con que la(s) persona que revise tu código tenga un alto señority en el stack tecnológico de la aplicación que se esta revisando, cuestión que es indispensable para poder hacer una buena revisión de la PR. También es importante conozca el flujo de negocio sobre el cual estas introduciendo el cambio.

Una buena revisión además de identificar problemas en el código, malas practicas aplicadas y recomendar mejoras técnicas tiene, sí o sí que evaluar el impacto de los cambios en los flujos de negocio. Existen muchas aplicaciones que por diferentes situaciones han ido acumulando deuda técnica, cuestión que complejiza la revisión, algunos elementos que agregan dificultad son, por ejemplo: código duplicado, funciones incorrectamente parametrizadas, métodos con parámetros mágicos etc; hay ocasiones donde meter un cambio en el sector A de la aplicación no impacta el sector B donde se requiere también el mismo cambio; con esto quiero recomendarte que para revisar el código elijas personas con alto nivel técnico y del negocio, es importante que el revisor tenga una visión global del paisaje.

Feedback

En este punto hay dos elementos importantes, primero como dar el feedback por parte del revisor y luego, como el solicitante acepta el feedback y actúa con la información brindada.

Cuando un revisor ofrece feedback, es esencial adoptar una actitud que fomente la mejora continua del código y el aprendizaje mutuo en el equipo. Debe asegurarse de que los comentarios sean claros, específicos y basados en hechos y evidencias técnicas (si recomienda cambios, es útil en ocasiones agregar enlaces y/o recomendar lecturas de ciertos temas, esto ayuda a comprender el problema/mejora), manteniendo siempre un tono profesional y respetuoso.

Es importante proporcionar sugerencias constructivas y explicar el razonamiento detrás de las observaciones para ayudar al desarrollador a comprender. Además, reconocer el trabajo bien hecho.

Por otro lado, el receptor del feedback debe mantener una actitud receptiva y profesional. Debe escuchar/leer activamente los comentarios, asumiendo siempre la buena voluntad detrás de las sugerencias recibidas. Es importante no tomarse los comentarios como una crítica personal.

El que recibe el cambio debe agradecer por el tiempo y esfuerzo dedicados a revisar su código, y no dudar en pedir aclaraciones si algo no está claro. El que recibe la revisión debe aceptar las críticas como oportunidades de aprendizaje y mejora, considerando cuidadosamente cada sugerencia antes de decidir implementar cambios.

Si la persona que creo el PR decide que una solicitud de cambio de un comentario no procede, debe abrir un espacio para el dialogo y entre ambos llegar a un acuerdo.

Hasta acá el articulo de hoy, espero te haya sido útil, si ha sido así considera compartirlo, seguirnos en YouTube y apoyar nuestro trabajo.