Después de dividir nuestro código en bits reutilizables, ¿cómo probamos e implementamos?

9

Comenzamos con un desarrollador y un repositorio svn que contenía todo nuestro código:

^/foo/trunk/module-a
^/foo/trunk/module-b
^/foo/trunk/module-b/submodule-b1
^/foo/trunk/website1

(en ese momento esto fue una gran mejora). Después de que esto tuvo la oportunidad de crecer un poco, comenzamos a tener problemas con las dependencias circulares, los paquetes de prueba lentos y las dificultades generales para volver a usar el código (ya que, por ejemplo, el conjunto de características del sitio web1 se había introducido en el módulo genérico a).

Queriendo modularizar la base del código, y esperando que pasemos a git en breve (y después de haber leído en algún lugar que a git no le gusta svn mega-repos), hemos pasado a una estructura mucho más granular:

^/module-a/trunk/
^/module-b/trunk/
^/module-b/trunk/sumbmodule-b1
^/earlier-sub-sub-sub-module-c/trunk
etc. (about 120 such modules)

Esto fue conceptualmente genial. Más código modular, conjuntos de pruebas mucho más rápidos, más fáciles de documentar, etc. Hemos abierto algunos de nuestros componentes más genéricos y hemos instalado todos los módulos pip ( pip install -e .para instalarlos en developmentvirtualenv).

Creamos un ^/srv/trunkrepositorio que contiene la estructura de carpetas del entorno de tiempo de ejecución, es decir. ^/srv/trunk/libpara los módulos, /srv/trunk/srcpara los restos de ^/foo/trunk, ^/srv/trunk/wwwpara sitios web, etc.

Y finalmente (tomando una idea de forzar, con la que trabajé hace mucho tiempo [ https://www.perforce.com/perforce/r12.1/manuals/cmdref/client.html] ) creamos un "vcs- buscar "archivo de texto que enumera todos los repositorios relevantes y dónde se deben extraer en el entorno de desarrollo, y un comando correspondiente para hacerlo. Por ejemplo, una línea vcs-fetc:

svn srv/lib/module-a ^/module-a/trunk

causaría cualquiera (primera vez)

cd /srv/lib && svn co ^/module-a/trunk module-a

o (después)

cd /srv/lib/module-a && svn up

y de manera similar para los repositorios de github (tanto nuestros paquetes de proveedores propios como los modificados).

Hemos utilizado el mismo proceso vcs-fetch para crear el entorno de producción, pero rápidamente descubrimos que no tenemos forma de saber qué versión solía ejecutarse en prod después de hacer un vcs-fetch.

Con el mega-repositorio, podríamos anotar el número de revisión antes de actualizar el producto desde la troncal, y regresar fue muy sencillo svn -r nnn up .. Con código en svn y git (y un módulo en hg) - y ~ 120 repos, no es obvio cómo hacer esto ...

Leí http://12factor.net/ hoy, y el primer factor es "Una base de código", así que también me pregunto si estoy muy lejos del camino correcto aquí.

Una idea que tuve fue crear un script de despliegue que creara ruedas de "despliegue" instalables en pip y las "agrupara" en un requirements.txtarchivo. Luego, una implementación implicaría crear un nuevo virtualenv, instalar pip el archivo require.txt que enumera las ruedas de implementación y cambiar el virtualenv activo. Volver al anterior solo implicaría cambiar el virtualenv hacia atrás (pero a menos que quisiéramos mantener los virtualenvs para siempre, no nos permitiría volver a ningún punto en el tiempo, aunque en mi experiencia eso nunca ha sido necesario).

En este punto me pregunto si estoy caminando en la dirección incorrecta, o si simplemente no he caminado lo suficiente en el camino correcto ... (todo lo que leo sigue hablando de "su aplicación", y no sé cómo se traduce en ejecutar 14 sitios web fuera de la misma base de código ...)

thebjorn
fuente
¿Puedo suponer que los componentes individuales ahora son desarrollados por diferentes equipos con ciclos de desarrollo divergentes? Si es así, romper el repositorio es inevitable de cualquier manera. Aunque con git, colocaría etiquetas de lanzamiento sincronizadas para configuraciones principales y estables. Echa un vistazo a la herramienta de repositorio de Google. Intentar hacer coincidir las versiones de desarrollo con metadatos integrados es bastante inútil. Vincular la aplicación a través de pip también es perfectamente legítimo.
Ext3h
Si incluye estimaciones KLOC (1000 líneas de código) y medidas de bytes del código, podemos tener una idea del tamaño, por ejemplo, "2000 líneas de código. Código fuente de 50 kilobytes". o "40 KLOC, 2 GB XML". . Parece lo que necesita para migrar a git y git tiene funciones de importación. Puedes comenzar leyendo el libro de git .
Niklas
1
@ Programmer400 la base de código es: .py 670 kloc, .js: 135kloc, .less: 25kloc, .html: 130kloc. Tan grande, pero no enorme. Por lo que he leído, a git no le gustan los repositorios de este tamaño, así que imagino que tendremos que dividirnos en repositorios más pequeños antes de cambiar a git ...
thebjorn

Respuestas:

2

Parece que le faltan ramas (o más bien 'ramas' o 'liberar' ramas).

En lugar de usar su SVN revnum como referencia para determinar qué versión está instalando, debe crear una rama en esa revisión publicada. Luego despliega ese nombre de sucursal.

Hace que sea más fácil ramificarse incluso si no hay cambios, por lo que cada módulo mantiene el mismo número de versión, sin embargo, es posible que sus paquetes OSS no quieran ramificarse sin cambios, por lo que lo mejor es mantener un script de dependencias, por lo que la versión 5 de su producto requiere el módulo OSS X v2 y así sucesivamente.

Cambiaría su secuencia de comandos para dejar de referirse a las versiones y en su lugar trabajaría con los nombres de las ramas (aunque pueden ser cualquier cosa, es mejor decidir sobre una convención de nomenclatura fija, por ejemplo, Release_1_2_3)

Otra sugerencia es mantener un archivo con cada módulo que describa la versión actual, puede generarlos automáticamente si es necesario, y tal vez incluir también un registro de cambios completo, pero significa que cualquiera puede ver qué versión se implementa con solo mirar.

gbjbaanb
fuente
1

Creo que ya tiene muchas buenas ideas, he utilizado la mayoría de ellas en varios proyectos a lo largo de los años, y su principal preocupación parece ser la incapacidad de saber qué versión de todos los módulos se incluyeron en un paquete dado si se divide hacia arriba.

Estoy a favor de dividirlos, en algún nivel de granularidad, especialmente si tiene múltiples equipos y ciclos de lanzamiento variables, como menciona @ Ext3h.

Como no estoy seguro de cuán aislados están sus módulos, o qué tan detallado desea que sea su versión, sugeriré algunas opciones.


Usa submódulos git. Con submódulos, puede almacenar cada módulo en un repositorio de git separado, similar a su configuración de svn y también a lo que está pensando. Luego vincula esos módulos al proyecto raíz que contendrá una referencia a la confirmación relevante de cada submódulo, para cada una de sus propias confirmaciones.

En mi opinión, esta es una configuración teóricamente agradable y razonablemente simple. Los principales inconvenientes son que el flujo de trabajo para los submódulos es un poco incómodo, sin embargo, parece haber resuelto bien estas cosas con scripts antes, por lo que puede que no sea un problema real.

La otra advertencia es que las referencias de confirmación de submódulo serán solo un SHA1, nunca hay detalles legibles por humanos sobre qué rama eres, y es posible que tengas que verificar manualmente la rama correcta cuando quieras trabajar directamente en el submódulo.

Sin embargo, no he usado este patrón ampliamente, por lo que no sé cuánto problema podría ser para un proyecto grande como el suyo.


Otra alternativa es utilizar algún tipo de administrador de dependencias. Esto requiere que cada módulo o conjunto de módulos pueda versionarse, empaquetarse y publicarse individualmente, y que tenga un sistema que pueda agrupar esos paquetes de la manera que desee cuando lo desee.

Ya está sugiriendo pip, y lo que parece faltar en su sugerencia es almacenar los requisitos resultantes .txt junto con la compilación, o en el repositorio del proyecto raíz, para que pueda volver a crear el virtualenv más tarde en lugar de tener que guardar en el disco

También hay otros sistemas; Configuré un proyecto bastante grande usando una versión ligeramente personalizada de Apache Ivy como la herramienta para empaquetar y publicar cada módulo, así como reunirlos para el proyecto final. Ivy también almacena un manifiesto que enumera todas las versiones de todos los módulos a los que hace referencia, si necesita recrear la configuración más adelante.

axl
fuente