Estrategia de ramificación y control de versiones para bibliotecas compartidas

12

Estas publicaciones parecen relacionadas, pero mi cerebro está comenzando a derretirse, tratando de pensar esto: P

Mi empleador acaba de comenzar a usar el control de fuente, principalmente porque antes de contratar a más desarrolladores, el "repositorio" era el disco duro del único desarrollador, que trabaja principalmente desde su casa. Todo el código .NET que había escrito se verificó en masa , y hay muchas funciones duplicadas (leer: copiar-pegar). En este momento, nuestro sistema SCM es un respaldo glorificado.

Me gustaría extraer parte del código duplicado en las bibliotecas compartidas. Dejo solo el repositorio original para que no rompamos nada: podemos mover y / o refactorizar el código existente cuando sea necesario. Así que configuré un repositorio solo para el nuevo código, incluidas las bibliotecas.

Mi problema gira en torno a la versión de las bibliotecas sin que nos veamos envueltos en un proceso excesivo: habiendo reconocido que necesitamos un enfoque más coherente, con más desarrolladores que escriben código muy similar, la administración y los otros desarrolladores están abiertos a reorganizar las cosas, pero probablemente no lo hará. baje bien si la solución comienza a afectar la productividad.

La solución ideal en mi mente obsesiva es construir las bibliotecas por separado, con cada proyecto dependiente construido contra versiones deliberadamente elegidas y compatibles de ellas. De esa manera, sabemos exactamente qué clientes tienen qué versiones de qué bibliotecas, pueden reproducir errores de manera más confiable, mantener ramificaciones de lanzamiento independientes para productos y bibliotecas, y no romper los proyectos de los demás al cambiar el código compartido.

Sin embargo, esto hace que la actualización de las bibliotecas sea engorrosa, particularmente para el desarrollador que trabaja desde casa. Espero que las bibliotecas cambien rápidamente, al menos inicialmente a medida que (finalmente) unimos los bits comunes. Es muy posible que esté pensando demasiado en esto y estaríamos bien compilando todo contra las confirmaciones de biblioteca más recientes, pero al menos me gustaría estar preparado para el día en que decidamos que algunos componentes deben ser versionados de forma independiente y repartido. El hecho de que algunas de las bibliotecas tengan que instalarse en el GAC hace que el control de versiones sea particularmente importante.

Entonces mi pregunta es: ¿qué me estoy perdiendo? Siento que me he concentrado en una solución y ahora estoy tratando de encontrar variaciones que hagan que los cambios sean más suaves. ¿Qué tipo de estrategias has usado para resolver este tipo de problema antes? Me doy cuenta de que esta pregunta está por todas partes; Haré todo lo posible para limpiar y aclarar cualquier punto de incertidumbre.

Y por mucho que me encantaría usar Mercurial, ya hemos gastado dinero en un SCM comercial centralizado (Vault) y el cambio no es una opción. Además, creo que el problema aquí va más allá de la elección de la herramienta de control de versiones.

shambulator
fuente
el costo fijo está hundido
alternativa el

Respuestas:

1

Elogio su iniciativa. Esto debería generar una serie de beneficios para la organización a medida que implementa esto. Me gustaría mover el código en lugar de copiarlo. Tener copias probablemente dará como resultado cambios incompatibles que deberán resolverse.

Habrá algo de dolor a medida que las bibliotecas se desarrollen y estabilicen. Una vez hecho esto, los beneficios llegarán. Recuerde que las interfaces a la biblioteca son esencialmente un contrato con los proyectos que trabajan con el contrato. Puede tener la ventaja de eliminar las interfaces antiguas, ya que puede determinar si se utilizan.

Mientras las bibliotecas se están estabilizando, obtener nuevas bibliotecas probablemente debería ser parte del proceso de actualización del código. Es posible que desee programar confirmaciones de cambios en la biblioteca. Anunciar el código que se está moviendo puede ayudar a reducir los cambios conflictivos.

Las bibliotecas deben tratarse como proyectos separados y estabilizarse lo antes posible. Una vez que se estabilizan (particularmente las interfaces), debería ser más fácil integrar los cambios con otros proyectos. Las nuevas bibliotecas deberían funcionar con el código antiguo. Etiquete los lanzamientos de bibliotecas estables con su propia identificación de lanzamiento. Intente tratar las bibliotecas como lo haría con las bibliotecas de terceros.

BillThor
fuente
6

El código que se comparte entre proyectos debe tratarse como proyectos en sí mismos. Deben tratarse con la misma minuciosidad que las bibliotecas de terceros. No hay otra manera.

Si no puede lograr que su grupo adopte una estrategia para el código compartido, puede adoptarla usted mismo con la ayuda de herramientas modernas de administración de código fuente como Mercurial o GIT, incluso si tampoco es el SCM que su empresa utilizará oficialmente. Con un poco de cuidado, dos SCM pueden usar el mismo directorio de trabajo simplemente diciéndole a uno que ignore los archivos internos del otro. Usaría un SCM para lidiar con lo cotidiano y el de la empresa para integrarlo.

En cualquier caso, debe estar a cargo de cuándo actualizar su directorio de trabajo con las modificaciones que otros proyectos han realizado en el código compartido. Esos deberían ocurrir solo cuando esté listo para lidiar con las incompatibilidades que puedan surgir; de lo contrario, su trabajo puede volverse inestable más allá de lo posible.

Apalala
fuente
4

Si tiene la capacidad de dividirlos en proyectos separados de "módulos", adoptaría ese enfoque. Una cosa de la que preocuparse es el acoplamiento de código. Crearía una separación de preocupaciones separándolas, lo cual es una buena práctica.

Algunos beneficios:

  1. Depuración más simple de cada módulo.
  2. Ciclos de compilación más rápidos (sin reconstrucción de bibliotecas que no han cambiado)
  3. Una vez que algo funciona, es menos probable que lo rompa cambiando otra área fuera de ese módulo (no al 100%, pero reduce las posibilidades).
  4. Es más fácil dividir las tareas laborales si no es un gran desastre interdependiente.
  5. Distribución más rápida de piezas más pequeñas cuando arregla una biblioteca (una gran razón por la que tiene archivos .dll / .so).

Tengo una pregunta sobre esta parte:

"La solución ideal en mi mente obsesiva es construir las bibliotecas por separado, con cada proyecto dependiente construido contra versiones compatibles elegidas deliberadamente".

¿Vinculas estático todo el proyecto? Si es así, esto conduciría a: 6. Reducción de la hinchazón innecesaria de código.

Algunos negativos

  1. Si el proyecto es pequeño, simplemente agrega complejidad donde no es necesario.
  2. La ramificación de muchos módulos puede convertirse en un problema de mantenimiento para proyectos realmente grandes. No sé "Vault", así que no estoy seguro de si sus operaciones de ramificación son buenas o malas.
jmq
fuente
Es el código C #, por lo que es un "no" a la vinculación estática en su significado habitual. Bóveda es como Subversion, pre-1.5: PI esperó tan ansiosamente seguimiento de la fusión en el SVN, pensando que estaba en el cielo cuando finalmente llegamos. Entonces encontré DVCS.
Shambulator
1

En este momento, parece que tiene una base de código construida de una vez en un solo objetivo. Probablemente no tenga más de cinco desarrolladores. Realmente no veo la utilidad de separar demasiado las bibliotecas. Cambiaría su flujo de trabajo de código -> compilar -> ejecutar a código -> compilar -> copiar DLL -> compilar -> ejecutar ... ick.

Algunas compañías (Google y Amazon) tienen una infraestructura suficiente para el desarrollo que es bastante sencillo tener muchas bibliotecas separadas construidas por separado. La infraestructura para que sea sencillo implica una forma de especificar las versiones de la biblioteca que viven en su SCM (que probablemente tenga), una forma de especificar las versiones de dependencia que viven en su SCM, un servidor de compilación que puede tener sentido y compilar todo correctamente , y una manera de obtener los artefactos de compilación apropiados de su servidor de compilación y de su espacio de trabajo local. Dudo que tengas eso.

Sin esa infraestructura, separaría el proyecto cuando se aplique uno de los siguientes:

  • Tiene varios productos o aplicaciones distintas según esta biblioteca.
  • Trabaja exclusivamente en estas bibliotecas durante varios días a la vez.
  • La funcionalidad de la biblioteca es extremadamente independiente de cualquier cosa relacionada con el negocio (por ejemplo, envoltorios alrededor de API específicas de la plataforma)
  • Los tiempos de construcción para el proyecto combinado crecen demasiado

Me preocuparía construir esa infraestructura cuando tienes muchos proyectos y algunos tienen desarrolladores dedicados y ciclos de lanzamiento independientes.

Lo que puede y debe hacer ahora es configurar un servidor de compilación para compilaciones confiables y repetibles y asegurarse de que pueda encontrar la revisión de origen de un ejecutable dado. Parece que estás usando .NET; es bastante sencillo configurar CruiseControl.NET para insertar una cadena de versión, incluido el número de revisión.

Una vez que tenga un servidor de compilación, dividir una biblioteca será cuestión de moverlo a Vault, agregar otro objetivo en CC.NET y copiar el archivo DLL resultante en la carpeta de la biblioteca de su proyecto principal y confirmarlo. Más fácil en el lado de SCM que el desarrollo diario.

dhasenan
fuente
1

Mercurial tiene una característica llamada subrepositorios. Recientemente leí este blog de Kiln explicando cómo funcionan.

Básicamente, vincula su proyecto a una revisión específica de un repositorio de biblioteca. Puede actualizar la biblioteca tanto como desee sin romper los proyectos dependientes. Cuando esté listo, puede incorporar las nuevas características de la biblioteca a su proyecto y lidiar con cualquier rotura. Los diferentes proyectos pueden vincularse a diferentes revisiones de la biblioteca, por lo que no todos tienen que estar sincronizados y usar la misma revisión de la biblioteca.

Quizás Vault tiene una característica similar.

Erik
fuente
1

Hemos agregado un archivo de metadatos a cada módulo en SC que indica el nombre de todos los demás módulos de los que depende. Un producto tendrá un segundo archivo de metadatos que indica qué versión de cada módulo dependiente se requiere para el producto. Además de esto, hay una herramienta para analizar los archivos de metadatos, consultar todos los módulos necesarios y generar un proyecto para nuestro IDE.

Esto garantiza que nuestras compilaciones sean siempre reproducibles y que los archivos de encabezado correctos siempre se compartan entre los componentes. Se puede aplicar otra complejidad a medida que se desarrolla la necesidad. Tenemos herramientas que ahora pueden generar informes sobre las diferencias entre dos compilaciones de un producto, especificando archivos de origen que cambiaron, comentarios de verificación, comentarios de versión, autores, en todos los módulos independientes en SC. Obtenemos una cantidad fenomenal de reutilización de nuestra base de código.

KJAWolf
fuente