Nuestro ciclo de desarrollo — To-DO

¿Habéis entendido estas primeras líneas? ¿Sabéis qué son? Seguramente no, y es una técnica que hoy os queremos presentar desde el equipo técnico de Finizens. Es un concepto que usamos a diario y que nos aporta muchísimo valor en nuestro ciclo de desarrollo. Pero antes, os debemos poner en contexto.

Para comenzar, hoy vamos a contaros cómo es nuestro ciclo de desarrollo, de principio a fin, es decir, desde que a un desarrollador se le presenta una historia de usuario definida en Producto hasta que está implementada y desplegada en producción.

La ejecución con éxito de este flujo es uno de los principales “drivers” por lo que se puede medir un equipo de desarrollo sobre todo en una startup. En la que, en la mayoría de casos, se estará probando ideas y ver cuál va funcionando mejor en mercado, para destacarse y conseguir una viabilidad de negocio.

El equipo técnico tiene que ser capaz de implementar las peticiones de negocio y no ser un bloqueo, por ello, desde Finizens siempre nos hemos cuestionado nuestro ciclo de desarrollo. Hemos ido mejorándolo (y continuamos haciéndolo) para encontrar una eficiencia máxima. De ahí, han surgido soluciones como haber implantado SCRUM, ser fieles a CI/CD y añadir el concepto del To-DO.

Asignación de tareas

Como habéis podido leer anteriormente, en Finizens usamos Scrum, tenemos esa mentalidad “Agile” y se nos ajusta muy bien para ir aportando valor de manera incremental a negocio. (Nota: Este no es un post para contar las bondades de Scrum)

Hacemos sprints quincenales, por lo que todo lo relativo e importante para el ciclo de desarrollo de una tarea, comienza en la ceremonia del Sprint Planning, donde pasamos las historias de usuario a tareas “técnicas”, las puntuamos y definimos el límite (en cuanto a número de tareas) que desde el equipo técnico nos comprometemos a entregar durante y al finalizar dicho sprint.

Cabe destacar que antes del Sprint Planning, tenemos reuniones de Grooming para refinar el Backlog y hacer un análisis previo o simplemente bajar un poco a la tierra las tareas para que desde Producto puedan hacerse una idea relativa del esfuerzo que pueden llegar a ser.

Por lo que, ya yendo al detalle, el resultado del Sprint Planning es un “tablero” como el de la imagen en el que todas las tareas están en la 1º columna de la izquierda (Backlog — To do) esperando a ser resueltas. En este punto, todos nos conocemos, los desarrolladores ya estamos “ansiosos” por ir analizándolas, “atacándolas” y resolverlas a nivel técnico.

Tablero del Sprint

En este apartado, maximizamos la visión de ir resolviéndolas como equipo, e intentamos que todos los desarrolladores ataquen la primera tarea, para sacarla a producción lo antes posible. Esto lo tenemos como máxima, ya que el sprint consiste en entregar valor, por lo que tiene más valor 1 sprint con una tarea resuelta que 1 sprint con 200 tareas empezadas y ninguna resuelta.

Dependiendo del alcance de la tarea, si vemos que con 1 desarrollador es suficiente, ya que va a generar más bloqueos que beneficios, se la asigna uno (decisión total por parte del equipo) y el resto pasan a la siguiente, y así sucesivamente.

To-DO

Una vez que los desarrolladores tienen tareas asignadas se comienza a realizar el análisis técnico de la misma, en la práctica, se comienza a pensar cómo puede resolverla de principio a fin, teniendo como meta el Definition of Done (DoD) de Producto.

Aquí es donde entra en juego el “famoso” término en cuestión y el que os queremos presentar del To-DO.

El concepto, y para nosotros muy importante, es cómo el desarrollador va a implementar la “posible” solución de la tarea sin todavía llegar a implementarla. Y el resultado es, lo que os ponía al principio del post, una simple lista de “cosas” a realizar para llegar a la solución de la tarea.

Por definir esas “cosas”, que así dicho es algo muy abstracto, simplemente piensa y tiene en cuenta todas las piezas de código y de datos, que va a tener que crear, modificar o borrar para llegar a la solución. Después de eso las lista y las describe, pero lo más importante, todavía no escribe código.

Por poner un ejemplo, aquí podéis ver un posible To-DO de una tarea, que va a añadir, por ejemplo, la fecha de cumpleaños a un usuario.

Una vez hecho el To-DO, el desarrollador que lo ha planteado se lo envía a otro desarrollador para que lo revise. En nuestro caso, esto es un simple comentario en la tarea de GitHub y jugamos con la asignación de la misma. El desarrollador que lo va a revisar, tiene como misión llegar a un acuerdo y darle un OK a la posible solución.

En este proceso de revisión, tienen lugar muchas conversaciones interesantes, teniendo en cuenta factores como:

  • Asegurar que se cumplen todos los requisitos.
  • Planteamiento de la solución técnica, piezas de código, naming, namespaces (rutas donde se van a crear las cosas), posibles errores de la solución, etc.
  • Casuísticas a tener en cuenta de lo que ya hay implementado y que no choque con nada.

Este proceso de revisión, lo realizamos tanto en asíncrono como síncrono. En tareas simples, solemos simplemente esperar el comentario del revisor en Github. Ante tareas más complejas o revisiones que requieran de un cambio importante de lo planteado, solemos hacerlo en síncrono, normalmente teniendo una conversación, para explicar más en detalle los cambios.

Una vez tenidas esas conversaciones y alcanzado un acuerdo común, se marca como revisado, en nuestro caso con una label de GitHub y el desarrollador que lo ha revisado, se lo vuelve a asignar al que ha planteado el To-DO y es el momento de ponerse a desarrollarlo.

Ejemplo real de To-DO

¿Qué ventajas hemos observado con esta técnica?

  • Las decisiones son consensuadas y quedan documentadas, es decir, en un futuro podemos volver a ellas y ver porque las tomamos.
  • Añade una visión de principio a fin de la tarea, y de verdad, eso ayuda mucho, para no encontrarnos luego errores en el DoD de Producto.
  • Evita silos de información, al menos 2 desarrolladores conocen la solución de la tarea. Además de que cualquier desarrollador del equipo, puede ver que solución se ha propuesto y conoce el alcance la misma. Además, si fuese necesario, cualquier desarrollador puede ponerse a programar la solución propuesta.
  • Definición del naming, al hacer que otro desarrollador tenga que leer la posible solución, es el momento en el que podemos pensar en ello y evaluarlo antes de implementarlo, que es el momento menos doloroso, ya que si hay que modificarlo, es simplemente cambiar un comentario de GitHub y no el código con los posibles errores que eso puede conllevar.
  • Reducimos el tiempo de coding y de code review, y volviendo a repetirme, es mucho mejor hacer un cambio en este punto que cuando ya esté implementado.
  • Nos ayuda a la hora de dividir las tareas, ya que una vez listada la posible solución, es muy sencillo dividirlo en distintos pasos, incluso ir programándolos por varios desarrolladores e ir enviándolo a producción, atomizando el nº de cambios y una code review más efectiva.
  • 🔝 Ayuda bastante en el OnBoarding de un nuevo compi, ya que solemos definir los primeros To-DOs conjuntamente y se alcanza una solución común, siendo un buen momento de ir explicándole conceptos del negocio y de la arquitectura implementada.

Cabe destacar, que en algunas tareas, sobre todo en las que tienen una capa de investigación muy alta, esta técnica es complicada de seguir sin escribir código. En estos casos es mejor lanzarse a la piscina y probar algo de código, antes de plantear el To-DO.

Code, Pull Request, Code Review — Continuous Integration

Una vez revisado el To-DO, el desarrollador ya empieza a programar la solución, y es muy sencillo, ya que simplemente debe de implementar los pasos que ya ha analizado anteriormente. Es decir, debe llevar a código el To-DO planteado anteriormente.

Aquí, por nuestra parte, hacemos uso de Continuous Integration (CI), cada commit que se pushea en GitHub, pasa una serie de checks, tanto de estilo, como pruebas (unitarias, integración, e2e) para asegurar la calidad del mismo.

Una vez implementado, nuestro flujo es bastante usual. El desarrollador abre una Pull Request y la manda a revisión, normalmente, a la misma persona que le ha revisado el To-DO, ya que ambos han estado hablando de la solución de la tarea y tienen el contexto de la misma.

Ejemplo de Pull Request
Timeline de una Pull Request con CI/CD

En este punto, es donde más se pueden ver las principales bondades del To-DO, ya que minimizamos muchísimo los comentarios típicos de:

  • “¿Has planteado hacerlo así? Yo habría optado por esta solución”
  • “Este naming, no me parece preciso, ¿qué te parece XXX?,
  • “¿Has caído en este caso? No está contemplado…”

Por nuestra parte, además en la Pull Request, se especifica el “How to test”, ya que además de Code Review, el desarrollador que verifica la PR, es el encargado de testear lo que pretende solucionar dicha PR, ya que no tenemos equipo de Q&A.

Esto lo contaremos en un post más adelante y explicaremos porqué nosotros de momento, hemos decidido no tener equipo de Q&A.

Deploy — Continuous Deployment

Y ahora lo más sencillo, una vez que la PR está testeada y aprobada, a producción.

En nuestro caso, esto se limita simplemente a darle al botón de “Merge pull request” y arranca toda nuestra “maquinaria” automatizada para desplegar el código en producción.

Como decíamos al principio, somos fieles a CI/CD, desde el día 0 hemos tenido este proceso automatizado, ya que consideramos que es una de las partes más importante, por tanto no queremos tener errores “humanos” y, además, es una parte que se repite muchísimo, por lo que merece la pena automatizarla.

Ejemplo de Continuous Deployment

Y después de todo esto, ¡el código está en producción! 🚀 👏

Conclusiones

Por concluir, simplemente comentar, que por el momento este ciclo de desarrollo nos funciona muy bien y nos permite ir avanzando a un ritmo bastante bueno.

Además de que estamos muy seguros del mismo, ya que toda parte de nuestro proceso está consensuado y revisado por al menos 2 miembros del equipo.

El concepto del To-DO hemos observado, que es una técnica como cualquier otra, conlleva una asimilación y requiere ser dominada y una vez dominada se vuelve mucho más efectiva. Sabes valorar lo que es importante a describir en cada tarea y sirve para identificar qué partes son las más complejas y requieren de una validación. De hecho, ante tareas muy simples, nos lo saltamos, ya que simplemente hemos visto que no es necesaria.

Y vosotros, ¿hacéis alguna revisión antes de escribir código? ¿Cómo es vuestro ciclo de desarrollo?

Es un tema que nos encanta y nos gusta escuchar cómo lo hacen en otras empresas. Además, cualquier sugerencia / comentario / mejora siempre es bienvenida.