Estructura de Proyectos en Control de Versión

Sé que hay al less 10 forms diferentes de estructurar proyectos en el control de versiones. Tengo curiosidad por saber qué methods se usan y cuáles funcionan para ti. He trabajado con SVN, TFS y actualmente / desafortunadamente VSS. He visto el control de versiones implementado muy mal y simplemente está bien, pero nunca genial.

Para que todo salga a la luz, aquí hay una reseña de las cosas que he visto.

Este ejemplo está basado en SVN, pero se aplica a la mayoría de los VCS (no tanto al control de versión distribuida).

  1. ramificar los proyectos individuales que forman parte de site / division / web / projectName / vb / src / [trunk | branches | tags]

  2. ramificar todo el sitio, en el caso que he visto, se ramificó todo el sitio, excepto los componentes principales. / division / [trunk | branches | tags] / web / projectName / vb / src /

  3. Use main-line como una twig pnetworkingeterminada, solo cuando sea necesario para grandes cambios.

Practicamos el desarrollo altamente componente utilizando Java, tenemos alnetworkingedor de 250 modules en el tronco que tienen ciclos de vida independientes. Las dependencies se gestionan a través de Maven (es una buena práctica allí), cada iteración (dos veces por semana) los modules desarrollados activamente se labeln con una nueva versión. Números de versión de 3 dígitos con estricta semántica (major.minor.build – cambios importantes significan incompatibilidad hacia atrás, cambios menores significan compatibilidad con versiones anteriores y cambios en el número de compilation significan compatibilidad con versiones anteriores y posteriores). Nuestro último producto de software es un ensamble que atrae docenas de modules individuales, nuevamente como dependencies de Maven.

Ramificamos modules / ensamblajes cuando necesitamos corregir errores o mejorar una versión lanzada y no podemos entregar la versión HEAD. Después de haber labeldo todas las versiones hace que esto sea fácil pero las sucursales aún incurren en una sobrecarga administrativa significativa (específicamente manteniendo las sucursales sincronizadas con ciertos sets de cambios HEAD) que en parte son causadas por nuestras herramientas, Subversion no es óptima para administrar sucursales.

Encontramos que una estructura de tree bastante plana y sobre todo pnetworkingecible en el repository es crucial. Nos ha permitido crear herramientas de lanzamiento que eliminan el dolor y el peligro de un process de lanzamiento manual (notas de la versión actualizadas, comstackciones de proyectos, testings de unidades ejecutadas, tags creadas, sin dependencies SNAPSHOT, etc.). Evite poner demasiada categorización u otra lógica en la estructura de su tree.

Más o less hacemos algo como lo siguiente:

 svnrepo/ trunk/ modules/ m1/ --> will result in jar file m2/ ... assemblies/ a1/ ... tags/ modules/ m1/ 1.0.0/ 1.0.1/ 1.1.0/ m2/ ... assemblies/ a1/ iteration-55/ ... branches/ m1/ 1.0/ ... 

Para las dependencies externas, no puedo exagerar el énfasis en algo como Maven: administre sus dependencies como references a artefactos binarys versionados, identificados de manera única en un repository.

Para la estructura del module / proyecto intenal: apegarse a un estándar. La uniformidad es la key. Nuevamente, Maven puede ayudar aquí ya que dicta una estructura. Muchas estructuras están bien, siempre y cuando te apegues a ellas.

Ejemplo para SVN:

el maletero/

twig/

tags /

El tronco debe mantenerse en un punto donde siempre puedas empujar una liberación desde él. No debe haber grandes errores que conozca (por supuesto que habrá eventualmente, pero eso es lo que debería esforzarse).

Cada vez que necesite crear una nueva característica, realice un cambio de layout, sea lo que sea, bifurque. Marque esa twig al comienzo. Luego, cuando haya terminado con la twig, etiquetela al final. Esto ayuda con la fusión de nuevo en el tronco.

Cada vez que necesites presionar un lanzamiento, label. De esta forma, si algo sale mal, puede retroceder a la versión anterior.

Esta configuration mantiene el tronco lo más limpio posible y le permite corregir rápidamente los errores y expulsarlos mientras mantiene la mayoría de su desarrollo en las twigs.

Editar: para cosas de terceros, depende. Si puedo evitarlo, no lo tengo bajo control de fuente. Lo guardo en un directory fuera del control de código fuente y lo incluyo desde allí. Para cosas como jquery, lo dejo bajo control de fuente. La razón es que simplifica mi script para empujar. Simplemente puedo hacer que haga una export svn y rsync.

Para mis proyectos, siempre uso esta estructura.

  • el maletero
    • config
    • documentos
    • sql
      • inicial
      • actualizaciones
    • src
      • aplicación
      • testing
    • tercero
      • lib
      • herramientas
  • tags
  • twigs
  • config: se usa para almacenar las templates de configuration de mi aplicación. Durante el process de compilation, tomo estas templates y reemploop los marcadores de position de los tokens con los valores reales, según la configuration que estoy haciendo.
  • documentos: toda la documentation de la aplicación se coloca aquí.
  • sql – Rompo mis scripts sql en dos directorys. Uno para la configuration inicial de la database para cuando comienzas de nuevo y otro lugar para mis scripts de actualización que se ejecutan basados ​​en el número de versión de la database.
  • src – Los files fuente de la aplicación. Aquí rompo los files fuente basados ​​en la aplicación y las testings.
  • tercero: aquí es donde coloco las bibliotecas de terceros a las que hago reference dentro de mi aplicación y que no están disponibles en el GAC. Lo dividí en base a lib y herramientas. El directory lib contiene las bibliotecas que deben includese con la aplicación real. El directory de herramientas contiene las bibliotecas a las que hace reference mi aplicación, pero solo se usan para ejecutar testings unitarias y comstackr la aplicación.

Mi file de solución se coloca justo debajo del directory troncal junto con mis files de compilation.

Puedo apreciar la lógica de no poner binarys en el repository, pero creo que también hay una gran ventaja. Si desea poder sacar una revisión específica del pasado (generalmente una label más antigua) me gusta poder tener todo lo que necesito provenga de la verificación de svn. Por supuesto, esto no incluye Visual Studio o .NET Framework, pero tener la versión correcta de nant, nunit, log4net, etc. hace que sea muy fácil pasar de la compra a la compilation. De esta manera, comenzar es tan fácil como "svn co project" seguido de "nant build".

Una cosa que hacemos es poner los binarys de ThirdParty en un tree separado y usar svn: external para traer la versión que necesitamos. Para facilitar la vida, tendremos una carpeta para cada versión que se haya utilizado. Por ejemplo, podríamos traer la carpeta ThirdParty / Castle / v1.0.3 al proyecto actual. De esta forma, todo lo que necesita para build / probar el producto está dentro o debajo de la raíz del proyecto. La compensación en el espacio del disco bien vale la pena en nuestra experiencia.

Como tenemos todos los artefactos y la construcción en el mismo tree tenemos algo así como:

  • El maletero

    • Planificación y seguimiento
    • Req
    • Diseño
    • Construcción
      • Compartimiento
      • Base de datos
      • Lib
      • Fuente
  • Desplegar

  • Control de calidad
  • MAMÁ

Prefiero repositorys estructurados, muy organizados, independientes y detallados. Hay un diagtwig que ilustra el enfoque general (ideal) del process de mantenimiento del repository. Por ejemplo, mi estructura inicial de repository (debe tener cada repository de proyecto) es:

 /project /trunk /tags /builds /PA /A /B /releases /AR /BR /RC /ST /branches /experimental /maintenance /versions /platforms /releases 

PA significa pre-alfa A significa alfa B significa beta AR significa alfa-release BR significa beta-release RC significa liberación del candidato ST significa estable

Hay diferencias entre comstackciones y lanzamientos .

  • Las tags en la carpeta de comstackciones tienen un número de versión correspondiente a un patrón NxK , donde N y K son integers. Ejemplos: 1.x.0 , 5.x.1 , 10.x.33
  • Las tags en la carpeta de lanzamientos tienen un número de versión correspondiente a un patrón NMK , donde N , M y K son integers. Ejemplos: 1.0.0 , 5.3.1 , 10.22.33 .

Recientemente, he desarrollado una capacitación dedicada a Software Configuration Management donde describo el enfoque de numeración de versiones y por qué exactamente esta estructura de repository es la mejor. Aquí hay diapositivas de presentación .

También está mi respuesta sobre la pregunta sobre "Repositorios SVN múltiples frente a repository de una sola compañía". Puede ser útil siempre que aborde este aspecto de la estructuración del repository en su pregunta.

Creo que las políticas y los procedimientos de SCM que adopte un equipo dependerán en gran medida del process de desarrollo que estén utilizando. Si tiene un equipo de 50 personas con varias personas trabajando en cambios importantes simultáneamente y lanzamientos que solo ocurren cada 6 meses, tiene mucho sentido que cada uno tenga su propia sucursal donde puede trabajar en forma aislada y solo fusionarse en cambios de otras personas cuando él los quiere. Por otro lado, si usted es un equipo de 5 personas sentadas en la misma habitación, tiene sentido ramificarse con mucha less frecuencia.

Suponiendo que trabaje en un equipo pequeño donde la comunicación y la queueboración son buenas y las liberaciones son frecuentes, tiene muy poco sentido siempre ramificar a la OMI. En un proyecto, simplemente lanzamos el número de revisión de SVN en el número de versión del producto para todas nuestras versiones y ni siquiera lo labelmos. En el raro caso de que hubiera una falla crítica encontrada en prod, simplemente ramificaríamos directamente desde la revisión que fue lanzada. Pero la mayoría de las veces simplemente arreglamos el error en la twig y lo liberamos de la cajuela al final de la semana según lo progtwigdo. Si sus lanzamientos son lo suficientemente frecuentes, casi nunca se encontrará con un error que no puede esperar hasta el próximo lanzamiento oficial.

Trabajé en otros proyectos en los que nunca hubiéramos salido con la tuya, pero debido al process de desarrollo liviano y la poca ceremonia, pudimos utilizar una política de control de versiones livianas de manera muy efectiva.

También mencionaré que todo lo que he escrito proviene de un context de TI empresarial donde solo hay una instancia de producción de una base de código determinada. Si estuviera trabajando en un producto que se implementó en 100 sitios diferentes de clientes, las prácticas de bifurcación y labeldo tendrían que ser un poco más extenuantes a fin de administrar todos los ciclos de actualización independientes en todas las instancias.

¿Qué ocurre con las dependencies externas como AJAXTookit o alguna otra extensión de terceros que se utiliza en varios proyectos?

El control de origen es para código fuente, no binarys. Mantenga las asambleas / jarrones de terceros en un repository separado. Si trabajas en el mundo Java testing algo como Maven o Ivy. Para proyectos .Net una unidad compartida simple puede funcionar bien siempre y cuando tenga políticas decentes sobre cómo se estructura y se actualiza.

Migramos del mal mundo de VSS con un repository gigante (más de 4G) antes de cambiar a SVN. Realmente tuve problemas con la configuration del nuevo repository para nuestra empresa. Nuestra compañía es una escuela muy "vieja". Es difícil conseguir el cambio. Soy uno de los desarrolladores más jóvenes y ¡tengo 45 años! Soy parte de un equipo de desarrollo corporativo que trabaja en progtwigs para varios departamentos de nuestra compañía. De todos modos, configuré nuestros directorys como este

 + devroot +--Dept1 +--Dept1Proj1 +--Dept2Proj2 +--Dept2 +--Dept2Proj1 +--Tools +--Purchase3rdPartyTools +--NLog +--CustomBuiltLibrary 

Quería include la posibilidad de twig, pero sinceramente eso es demasiado en este punto. Junte cosas con las que todavía tenemos problemas usando este esquema.

  • Es difícil solucionar los problemas de producción si está trabajando en una actualización importante del producto (es decir, porque no hacemos ramificaciones)
  • Es difícil gestionar el concepto de promoción de "Dev" a "Prod". (Ni siquiera preguntes sobre promocionar a QA)