README – cómo saber

Los archivos README tienen una larga tradición en los proyectos de software. Originalmente, estos archivos de texto sin formato contenían información sobre la licencia e instrucciones sobre cómo compilar el artefacto correspondiente a partir del código fuente o notas importantes sobre la instalación del programa. No existe ningún estándar real sobre cómo construir un archivo README de este tipo.

Desde que GitHub (adquirida por Microsoft en 2018) inició su marcha triunfal como plataforma de alojamiento de código libre para proyectos de código abierto, existe desde bastante pronto la función de mostrar el archivo README como página de inicio del repositorio. Todo lo que se necesita es crear un simple archivo de texto llamado README.md en el directorio raíz del repositorio.

Para poder estructurar los archivos README de forma más clara, se buscó una posibilidad de formato simple. Rápidamente se eligió la notación markdown porque es fácil de usar y se puede renderizar de forma bastante eficiente. Esto facilita la lectura de las páginas de resumen y permite utilizarlas como documentación del proyecto.

Es posible enlazar varios archivos markdown como documentación del proyecto. Así se crea una especie de mini WIKI que se incluye en el proyecto y también se versiona a través de Git.

El asunto tuvo tanto éxito que soluciones de autoalojamiento como GitLab o la comercial BitBucket también han adoptado esta función.

Ahora, sin embargo, se plantea la cuestión de qué contenido es mejor escribir en un archivo README de este tipo para que también represente un verdadero valor añadido para los forasteros. Con el paso del tiempo, se han establecido los siguientes puntos:

  • Breve descripción del proyecto
  • Condiciones de uso del código fuente (licencia)
  • Cómo utilizar el proyecto (por ejemplo, instrucciones para compilar o cómo integrar la biblioteca en proyectos propios)
  • Quiénes son los autores del proyecto y cómo se puede contactar con ellos
  • Qué hacer si desea apoyar el proyecto

Mientras tanto, las llamadas insignias (pegatinas) se han hecho muy populares. A menudo hacen referencia a servicios externos, como el servidor gratuito de integración continua TravisCI. Ayudan a evaluar la calidad del proyecto.

También hay varias plantillas para archivos README en GitHub. Sin embargo, tienes que fijarte en las circunstancias reales de tu propio proyecto y juzgar qué información es realmente relevante para los usuarios. Estas plantillas ayudan mucho a averiguar si se ha pasado por alto algún punto.

El hecho de que prácticamente todos los fabricantes de soluciones de servidores de gestión de control de código fuente hayan integrado ya la función de mostrar el archivo README.md como página de inicio del proyecto para el repositorio de código significa que un README.me también es algo útil para los proyectos comerciales.

Aunque la sintaxis para markdown es fácil de aprender, puede ser más conveniente utilizar directamente un editor MARKDOWN para la edición extensiva de este tipo de archivos. Debes asegurarte de que la vista previa también se muestra correctamente y no se ofrece un simple resaltado de sintaxis.

Los enlaces sólo son visibles para los usuarios registrados.

Los enlaces sólo son visibles para los usuarios registrados.

La Ley de Conway

Durante mi trabajo como Gestor de Configuración / DevOps para grandes proyectos web, he observado cómo las empresas hacían caso omiso de la Ley de Conway y fracasaban estrepitosamente. Ese fracaso a menudo se traducía en importantes sobrecostes presupuestarios y plazos incumplidos.

La infraestructura interna en la colaboración del proyecto se modeló exactamente según las estructuras organizativas internas y todas las experiencias y normas establecidas se “doblaron” para adaptarlas a la organización interna. Esto dio lugar a problemas que hicieron que las canalizaciones de CI/CD fueran especialmente engorrosas y provocaron largos tiempos de ejecución. Pero además, los ajustes sólo podían hacerse con mucho esfuerzo. En lugar de simplificar los procesos existentes y adaptarlos a los estándares establecidos, se pusieron excusas para mantener todo como estaba. Veamos qué es la Ley de Conway y por qué hay que respetarla.

El investigador y programador estadounidense Melvin E. Conway se doctoró en la Case Western Reserve University en 1961. Su especialidad son los lenguajes de programación y el diseño de compiladores.

En 1967, presentó su artículo “How Do Committees Invent?” (¿Cómo inventan los comités?) en The Harvard Business Review. (Engl.: ¿Cómo inventan los comités?) y fue rechazado. La razón aducida fue que su tesis no estaba fundamentada. Sin embargo, Datamation, la mayor revista de informática de la época, aceptó su artículo y lo publicó en abril de 1968. Y este artículo es ahora ampliamente citado. La afirmación central es:

Cualquier organización que diseñe un sistema (en el sentido más amplio) creará un diseño cuya estructura sea una copia de la estructura de comunicación de la organización.

Conway, Melvin E. “How do Committees Invent?” 1968, Datamation, vol. 14, num. 4, pp. 28–31

Cuando Fred Brooks citó el ensayo en su legendario libro de 1975 “The Mythical Man-Month”, llamó a esta afirmación central Ley de Conway. Brooks reconoció la conexión entre la Ley de Conway y la teoría de la gestión. En el artículo encontramos el siguiente ejemplo:

Dado que el diseño elegido en primer lugar casi nunca es el mejor posible, el sistema imperante puede necesitar cambiar conceptos del sistema. Por ello, la flexibilidad de la organización es importante para un diseño eficaz.

The Mythical Man-Month: Essays on Software Engineering

Un ejemplo a menudo citado del tamaño “ideal” de un equipo en términos de la Ley de Conway es la regla de las dos pizzas de Amazon, que establece que los equipos de proyectos individuales no deben tener más miembros de los que dos pizzas puedan llenar en una reunión. Sin embargo, el factor más importante que hay que tener en cuenta en la alineación de equipos es la capacidad de trabajar entre equipos y no vivir en silos.

La Ley de Conway no pretendía ser un chiste ni un koan zen, sino una observación sociológica válida. Fijémonos en las estructuras de las administraciones públicas y su implantación digital. Pero también los procesos de las grandes empresas han sido emulados por sistemas informáticos. Estas aplicaciones se consideran muy engorrosas y complicadas, por lo que encuentran poca aceptación entre los usuarios, que prefieren recurrir a alternativas. Por desgracia, a menudo es casi imposible simplificar los procesos en las grandes estructuras organizativas por motivos políticos.

Entre otras cosas, hay un detallado artículo de Martin Fowler, que trata explícitamente de las arquitecturas de software y elabora la importancia del acoplamiento de objetos y módulos. La comunicación entre desarrolladores desempeña un papel esencial para lograr los mejores resultados posibles. Este hecho sobre la importancia de la comunicación también fue recogido por el desarrollo ágil de software e implementado como un punto esencial. Especialmente cuando equipos distribuidos trabajan en un proyecto conjunto, la diferencia horaria es un factor limitante en la comunicación del equipo. Por tanto, ésta debe organizarse de forma especialmente eficaz.

En 2010, Jonny Leroy y Matt Simons acuñaron el término Inverse Conway Maneuver en el artículo “Dealing with creaky legacy platforms”:

La Ley de Conway… puede resumirse así: “Las organizaciones disfuncionales tienden a crear aplicaciones disfuncionales”. Parafraseando a Einstein: No se puede solucionar un problema desde la misma mentalidad que lo creó. Por lo tanto, a menudo merece la pena investigar si la reestructuración de su organización o equipo evitaría que la nueva aplicación tuviera las mismas disfunciones estructurales que la original. En una especie de “maniobra Conway a la inversa”, se puede empezar por romper los silos que limitan la capacidad del equipo para trabajar juntos con eficacia.

Desde la década de 2010, un nuevo estilo arquitectónico ha entrado en la industria del software. Son los llamados microservicios, creados por pequeños equipos ágiles. El criterio más importante de un microservicio en comparación con un monolito modular es que un microservicio puede verse como un módulo o subsistema independientemente viable. Por un lado, esto permite reutilizar el microservicio en otras aplicaciones. Por otro lado, existe un fuerte encapsulamiento del dominio funcional, lo que abre una flexibilidad muy elevada para las adaptaciones.

La ley de Conway también puede aplicarse a muchos otros ámbitos y no se limita exclusivamente a la industria del software. Esto es lo que hace que el trabajo sea tan valioso.

Resourcen

Los enlaces sólo son visibles para los usuarios registrados.

Anti-Pattern de números de versión

publicado también en inglés en DZone 04.2020

Después de que la banda de los cuatro (GOF) Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides publicaran el libro Design Patterns: Elements of Reusable Object-Oriented Software, aprender a describir problemas y soluciones se hizo popular en casi todos los campos del desarrollo de software. Del mismo modo, aprender a describir lo que no se debe hacer y los antipatrones se hizo igualmente popular.

En las publicaciones que trataban estos conceptos, encontramos recomendaciones útiles para el diseño de software, la gestión de proyectos, la gestión de la configuración y mucho más. En este artículo, compartiré mi experiencia con los números de versión para artefactos de software.

La mayoría de nosotros ya estamos familiarizados con un método llamado versionado semántico, un conjunto de reglas potentes y fáciles de aprender sobre cómo deben estructurarse los números de versión y cómo deben aumentar los segmentos.

Ejemplo de numeración de versiones:

  • Mayor: Cambios incompatibles en la API.
  • Menor: Añade nuevas funcionalidades.
  • Patch: Corrección de errores y correcciones.
  • Label: SNAPSHOT que marca el estado “en desarrollo”.

Un cambio de API incompatible se produce cuando se elimina o cambia el nombre de una función o clase accesible desde el exterior. Otra posibilidad es un cambio en la firma de un método. Esto significa que el valor de retorno o los parámetros se han modificado con respecto a su implementación original. En estos escenarios, es necesario aumentar el segmento Mayor del número de versión. Estos cambios suponen un alto riesgo para los consumidores de la API porque tienen que adaptar su propio código.

Cuando se trata de números de versión, también es importante saber que 1.0.0 y 1.0 son iguales. Esto tiene efecto en el requisito de que las versiones de una versión de software tienen que ser únicas. Si no, es imposible distinguir entre artefactos. En mi experiencia profesional, he participado varias veces en proyectos en los que no había procesos bien definidos para crear números de versión. El efecto de estas circunstancias era que el equipo tenía que asegurar la calidad del artefacto y se confundía con qué versión del artefacto estaba tratando en ese momento.

El mayor error que he visto es el almacenamiento de la versión de un artefacto en una base de datos junto con otras entradas de configuración. El procedimiento correcto debería ser: colocar la versión dentro del artefacto de forma que nadie después de una liberación pueda cambiarla desde fuera. La trampa en la que podrías caer es el proceso de cómo actualizar la versión después de un lanzamiento o instalación.

Puede que tenga una lista de comprobación para todas las actividades manuales durante una publicación. Pero, ¿qué sucede después de que una versión se instala en una etapa de prueba y por alguna razón otra versión de la aplicación tiene que ser instalada. ¿Todavía tiene que cambiar manualmente el número de versión? ¿Cómo averiguar qué versión está instalada o cuándo la información de la base de datos es incorrecta?

Detectar la versión correcta en esta situación es un reto muy difícil. Por esa razón, tenemos el requisito de mantener la versión dentro de la aplicación. En el próximo paso, discutiremos una forma segura y simple de resolver este problema de forma automática.

Nuestra precondición es una simple construcción de una librería Java con Maven. Por defecto, el número de versión del artefacto está escrito en el POM. Después del proceso de construcción, nuestro artefacto es creado y nombrado como: artefacto-1.0.jar o similar. Mientras no renombremos el artefacto, tendremos una forma adecuada de distinguir las versiones. Incluso después de un renombrado con un simple truco de empaquetado y comprobación, entonces, en la carpeta META-INF, somos capaces de encontrar el valor correcto.

Si usted tiene la Versión hardcoded en una propiedad o archivo de clase, también funcionaría bien, siempre y cuando no se olvide de actualizar siempre. Tal vez la ramificación y la fusión en los sistemas SCM como Git podría necesitar su atención especial para tener siempre la versión correcta en su código base.

Otra solución es utilizar Maven y el mecanismo de colocación de tokens. Antes de que corras a probarlo en tu IDE, ten en cuenta que Maven utiliza dos carpetas diferentes: sources y resources. La sustitución de tokens en sources no funcionará correctamente. Después de una primera ejecución, tu variable es reemplazada por un número fijo y desaparece. Una segunda ejecución fallará. Para preparar tu código para el reemplazo de tokens, necesitas configurar Maven como primero en el ciclo de vida de construcción:

<build>
   <resources>
      <resource>
         <directory>src/main/resources/</directory>
         <filtering>true</filtering>
      </resource>
   </resources>
   <testResources>
      <testResource>
         <directory>src/test/resources/</directory>
         <filtering>true</filtering>
      </testResource>
   </testResources>
</build>
XML

Después de este paso, necesita conocer la propiedad ${project.version} del POM. Esto le permite crear un archivo con el nombre version.property en el directorio resources. El contenido de este archivo es sólo una línea: version=${project.version}. Después de una compilación, encontrará en su artefacto la version.property con el mismo número de versión que utilizó en su POM. Ahora, usted puede escribir una función para leer el archivo y utilizar esta propiedad. Podrías almacenar el resultado en una constante para usarla en tu programa. ¡Eso es todo lo que tienes que hacer!

Ejemplo: https://github.com/ElmarDott/TP-CORE/blob/master/src/main/java/org/europa/together/utils/Constraints.java

Opciones de automatización en la gestión de la configuración del software

El desarrollo de software ofrece algunas formas extremadamente eficaces de simplificar tareas recurrentes mediante la automatización. La eliminación de tareas tediosas, repetitivas y monótonas y la consiguiente reducción de la frecuencia de errores en el proceso de desarrollo no son, ni mucho menos, todas las facetas de este tema.

(c) 2011 Marco Schulz, Materna Monitor, Ausgabe 1, S.32-34
Artículo original traducido del Deutsch

La motivación para establecer automatismos en el panorama informático es en gran medida la misma. Las tareas recurrentes deben simplificarse y ser resueltas por máquinas sin intervención humana. Las ventajas son menos errores en el uso de los sistemas informáticos, lo que a su vez reduce los costes. Por sencilla y ventajosa que parezca la idea de que los procesos se ejecuten de forma independiente, la puesta en práctica no es tan trivial. Rápidamente se hace evidente que para cada posibilidad de automatización identificada, la implantación no siempre es factible. Aquí también se aplica el principio: cuanto más complejo es un problema, más difícil es resolverlo.

Para sopesar si merece la pena el esfuerzo económico que supone introducir determinados automatismos, hay que multiplicar los costes de una solución manual por el factor de la frecuencia con que hay que repetir este trabajo. Estos costes deben compararse con los gastos de desarrollo y funcionamiento de la solución automatizada. Sobre la base de esta comparación, rápidamente queda claro si una empresa debe aplicar la mejora prevista.

Herramientas de apoyo al proceso de desarrollo

Especialmente en el desarrollo de proyectos de software, existe un considerable potencial de optimización mediante procesos automáticos. Los desarrolladores cuentan con el apoyo de multitud de herramientas que deben ser hábilmente orquestadas. La gestión de configuraciones y versiones, en particular, trata con gran detalle el uso práctico de una amplia variedad de herramientas para automatizar el proceso de desarrollo de software.

La existencia de una lógica de compilación independiente, por ejemplo en forma de un simple script de shell, ya es un buen enfoque, pero no siempre conduce a los resultados deseados. En estos casos, son necesarias soluciones independientes de la plataforma, ya que es muy probable que el desarrollo tenga lugar en un entorno heterogéneo. Una solución aislada siempre supone un mayor esfuerzo de adaptación y mantenimiento. Por último, los esfuerzos de automatización deben simplificar los procesos existentes. Las herramientas de compilación actuales, como Maven y Ant, aprovechan esta ventaja de la independencia de la plataforma. Ambas herramientas encapsulan toda la lógica de compilación en archivos XML independientes. Dado que XML ya se ha establecido como estándar en el desarrollo de software, la curva de aprendizaje es más pronunciada que con las soluciones rudimentarias.

El uso de lógicas de compilación centrales constituye la base de otros automatismos durante el trabajo de desarrollo. Las pruebas automatizadas en forma de pruebas unitarias en un entorno de integración continua (IC) son un aspecto de ello. Una solución CI combina todas las partes de un software en un todo y procesa todos los casos de prueba definidos. Si el software no se ha podido construir o una prueba ha fallado, se avisa al desarrollador por correo electrónico para que corrija rápidamente el error. Los servidores CI modernos se configuran con un sistema de gestión de versiones, como Subversion o Git. Esto hace que el servidor inicie una compilación sólo cuando se han realizado realmente cambios en el código fuente.

Los sistemas de software complejos suelen depender de componentes externos (bibliotecas) en los que no puede influir el propio proyecto. La gestión eficaz de los artefactos utilizados en el proyecto es el principal punto fuerte de la herramienta de compilación Maven, lo que ha contribuido a su uso generalizado. Cuando se utiliza correctamente, elimina la necesidad de archivar las partes binarias del programa dentro de la gestión de versiones, lo que se traduce en repositorios más pequeños y tiempos de commit (finalización con éxito de una transacción) más cortos. Las nuevas versiones de las bibliotecas utilizadas pueden integrarse y probarse más rápidamente sin necesidad de realizar copias manuales propensas a errores. Las bibliotecas desarrolladas internamente pueden distribuirse fácilmente de forma protegida en la red de la empresa con el uso de un servidor de repositorios independiente (Apache Nexus) en el sentido de la reutilización.

Al evaluar una herramienta de compilación, no hay que descuidar la posibilidad de elaborar informes. El seguimiento automatizado de la calidad del código mediante métricas, por ejemplo a través de la herramienta Checkstyle, es un excelente instrumento para que la dirección del proyecto evalúe de forma realista el estado actual del proyecto.

No demasiadas nuevas tecnologías

Con todas las posibilidades de automatización de procesos, se pueden tomar varios caminos. No es raro que los equipos de desarrollo mantengan largas discusiones sobre qué herramienta es la más adecuada para el proyecto en curso. Esta pregunta es difícil de responder en términos generales, ya que cada proyecto es único y hay que comparar las ventajas e inconvenientes de las distintas herramientas con los requisitos del proyecto.

En la práctica, la limitación a un máximo de dos tecnologías novedosas en el proyecto ha demostrado su eficacia. La idoneidad de una herramienta también depende de si en la empresa hay personas con los conocimientos adecuados. Una buena solución es una lista publicada por la dirección con recomendaciones de las herramientas utilizadas que ya están en uso o pueden integrarse en el paisaje de sistemas existente. Así se garantiza que las herramientas utilizadas sigan siendo claras y manejables.

Los proyectos que se prolongan durante muchos años deben someterse a una modernización de las tecnologías utilizadas a intervalos más amplios. En este contexto, hay que encontrar momentos adecuados para migrar a la nueva tecnología con el menor esfuerzo posible. Fechas sensatas para pasar a una tecnología más reciente son, por ejemplo, el cambio a una nueva versión principal del propio proyecto. Este procedimiento permite una separación limpia sin tener que migrar los antiguos estados del proyecto a la nueva tecnología. En muchos casos, esto no es tan fácil de hacer.

Conclusión

El uso de automatismos para el desarrollo de software puede, si se emplea con sensatez, contribuir enérgicamente a la consecución del objetivo del proyecto. Como todas las cosas, un uso excesivo conlleva algunos riesgos. La infraestructura utilizada debe seguir siendo comprensible y controlable a pesar de toda la mecanización, para que el trabajo del proyecto no se paralice en caso de fallos del sistema.