Ciclo impar de lanzamiento de la compañía: ¿Ir al control de la fuente distribuida?

13

Lo siento por este largo post, pero creo que vale la pena.

Acabo de comenzar con una pequeña tienda de .NET que funciona de manera bastante diferente a otros lugares en los que he trabajado. A diferencia de cualquiera de mis posiciones anteriores, el software escrito aquí está dirigido a múltiples clientes y no todos los clientes obtienen la última versión del software al mismo tiempo. Como tal, no hay una "versión de producción actual". Cuando un cliente obtiene una actualización, también obtiene todas las funciones agregadas al software desde su última actualización, lo que podría ser hace mucho tiempo. El software es altamente configurable y las funciones se pueden activar y desactivar: las llamadas "funciones alternadas". Los ciclos de lanzamiento son muy ajustados aquí, de hecho no están programados: cuando se completa una función, el software se implementa para el cliente relevante.

El equipo solo el año pasado se trasladó de Visual Source Safe a Team Foundation Server. El problema es que todavía usan TFS como si fuera VSS y aplican los bloqueos de Checkout en una sola rama de código. Cada vez que se pone una solución de error en el campo (incluso para un solo cliente) simplemente construyen lo que sea en TFS, se prueba que el error se solucionó y se implementó en el cliente. (Yo vengo de un fondo de software farmacéutico y de dispositivos médicos, ¡esto es increíble!). El resultado es que el código de desarrollo semicocido se pone en producción sin siquiera ser probado. Los errores siempre se están deslizando hacia las versiones de lanzamiento, pero a menudo un cliente que acaba de obtener una versión no verá estos errores si no usa la función en la que se encuentra el error. El director sabe que esto es un problema ya que la compañía está empezando a crecer. de repente, con algunos clientes grandes a bordo y más pequeños.

Se me ha pedido que mire las opciones de control de código fuente para eliminar la implementación de código con errores o sin terminar, pero para no sacrificar la naturaleza un tanto asincrónica de los lanzamientos de los equipos. He usado VSS, TFS, SVN y Bazaar en mi carrera, pero TFS es donde ha estado la mayor parte de mi experiencia.

Anteriormente, la mayoría de los equipos con los que he trabajado utilizan una solución de dos o tres sucursales de Dev-Test-Prod, donde durante un mes los desarrolladores trabajan directamente en Dev y luego los cambios se fusionan para probar, luego Prod, o se promueven "cuando se hace". en lugar de en un ciclo fijo. Se utilizaron construcciones automatizadas, utilizando el control de crucero o la creación de equipos. En mi trabajo anterior, Bazaar se usaba sentado en la parte superior de SVN: los desarrolladores trabajaban en sus propias sucursales de características pequeñas y luego aplicaban sus cambios a SVN (que estaba vinculado a TeamCity). Esto fue agradable porque fue fácil aislar los cambios y compartirlos con las sucursales de otras personas.

Con ambos de estos modelos había una rama central de desarrollo y producto (y, a veces, de prueba) a través de la cual se insertó el código (y se usaron etiquetas para marcar las compilaciones en la que se hicieron las versiones ... y éstas se convirtieron en ramas para correcciones de errores a las versiones y fusionadas de nuevo a dev). Sin embargo, esto no se adapta realmente a la forma de trabajar aquí: no hay ningún orden en el que se lanzarán varias funciones, sino que se eliminarán cuando estén completas.

Con este requisito, el enfoque de "integración continua" tal como lo veo se rompe. Para obtener una nueva característica con integración continua, se debe enviar mediante dev-test-prod y eso capturará cualquier trabajo no finalizado en dev.

Estoy pensando que para superar esto deberíamos utilizar un modelo con muchas funciones y SIN ramas de dev-test-prod, sino que la fuente debería existir como una serie de ramas de características que cuando el trabajo de desarrollo está completo se bloquean, se prueban, Fijado, bloqueado, probado y luego liberado. Otras ramas de características pueden captar cambios de otras ramas cuando lo necesitan / desean, por lo que eventualmente todos los cambios son absorbidos por los demás. Esto se ajusta mucho a un modelo de Bazar puro de lo que experimenté en mi último trabajo.

Por más flexible que parezca, parece extraño no tener un tronco dev o una rama prod., y me preocupa que las ramas no se reintegren nunca o que se realicen pequeños cambios tardíos que nunca lleguen a otras ramas y desarrolladores quejándose de los desastres de fusión ...

¿Qué piensan los pueblos sobre esto?

Una segunda pregunta final: estoy algo confundido acerca de la definición exacta de control de fuente distribuida: algunas personas parecen sugerir que se trata simplemente de no tener un repositorio central como TFS o SVN, algunos dicen que se trata de estar desconectado (SVN es 90% desconectado y TFS tiene un modo fuera de línea perfectamente funcional) y otros dicen que se trata de la bifurcación de características y la facilidad de fusión entre sucursales sin relación padre-hijo (¡TFS también tiene una fusión sin fundamento!). ¡Quizás esta es una segunda pregunta!

    
pregunta MrLane 19.03.2012 - 08:00

5 respuestas

5

¿Qué define un DVCS?

El distribuido en DVCS significa que cada clon de un repositorio tiene toda la información requerida para confirmar, actualizar, ramificar, fusionar o buscar cualquier revisión en ese repositorio, sin tocar nunca un servidor . Lo único que puede hacer sin conexión en svn es en realidad editar los archivos : necesita acceso al servidor para casi todos los comandos de svn , incluido hacer algo tan simple como grepping un svn log , por lo que en realidad está más cerca del 0% que del 90%!

Cualquier repositorio central autorizado que pueda configurar en un flujo de trabajo DVCS es simplemente otro clon , y la única vez que necesite para interactuar con él son cuando abres las actualizaciones de otras personas o cuando presionas tus propios cambios para que otras personas puedan verlos, casi todo lo demás se puede hacer fuera de línea.

¿Qué modelo de ramificación es adecuado?

He estado en la situación en la que estás ahora. Tales sistemas pueden ser un verdadero dolor, pero tienes que entender las razones pragmáticas por las que se convirtieron en esto y darte cuenta de que no están más allá de la redención . Se han desarrollado muchas herramientas que pueden ayudar a gestionar este tipo de complejidad .

En primer lugar, hagas lo que hagas, no le muestres a las personas el exitoso modelo de bifurcación de git , simplemente los confundirá y los apagará. En su lugar, desarrolle su propio modelo que refleje su flujo de trabajo existente , pero resuelva los problemas con su flujo de trabajo existente .

Algunos recursos que tal vez desee considerar incluyen cosas como git submodules que permitirán especificar diferentes lanzamientos de clientes Diferentes combinaciones de configuración de clientes, módulos de aplicaciones y bibliotecas. Otra opción sería el uso de un sistema de administración de parches para aplicar al cliente / colas de parche específicas del producto.

Estas dos opciones brindarán mucha más flexibilidad, transparencia y seguridad que su flujo de trabajo actual, y podrían ser más fáciles de usar que una estrategia de sucursal aún más compleja. Ciertamente me gustaría tener acceso a estas herramientas cuando estaba en tu situación.

Para obtener más información sobre estas opciones, consulte mis respuestas a Estrategia para usar el control de versiones en un sistema modular . ¿Cómo utilizar el repositorio de Subversion dentro del repositorio Git? y Control de fuente / versión para la aplicación utilizada por varias compañías .

En última instancia, esto es realmente algo que tendrá que desarrollar con el resto del equipo. Si tiene la visión de proponer algo que funcione mejor que lo que ya tiene, y puede obtener la aceptación de sus compañeros desarrolladores, tendrá un tiempo mucho más fácil.

Lo más importante es mostrar a tus colegas cómo lo que propones hará que sus vidas sean más fáciles . Una vez que estén convencidos, tendrá una mejor oportunidad de obtener la gestión para deshacerse de su inversión en TFS y comenzar a usar un modelo más apropiado para sus métodos de trabajo.

    
respondido por el Mark Booth 19.03.2012 - 13:18
5

En primer lugar, DVCS es una pista falsa para los problemas que tiene: la herramienta de control de versiones en uso no es la raíz de los problemas que deben resolverse. Puede ser que haya aspectos de las soluciones DVCS que sean "mejores" que TFS, pero no es lo que se necesita arreglar en este momento.

Ha identificado que necesita una estructura de bifurcación viable que se adapte a su organización. Creo que encontrará que todavía tiene un troncal, cuando una característica está completa, se fusiona nuevamente en el troncal y se cierra. También hay algunos buenos pensamientos acerca de cómo implementar dependencias comunes.

También es necesario que funcione la integración continua (no hay razón para no tener una compilación automatizada para todas y cada una de las sucursales activas para que pueda confiar en que puede construir esa sucursal y que pase las pruebas relevantes). Me siento incómodo cuando un commit (o al menos un "push") no activa una compilación para mí.

Y necesita comenzar con las pruebas automatizadas en todos los niveles, pero especialmente las pruebas unitarias y las pruebas de integración para comenzar a reducir las posibilidades de que nuevos errores se escapen a la naturaleza. Esto último es enorme y algo con lo que todavía estoy luchando, pero está claro que una vez que sepas que puedes construir cosas, todo esto tendrá el mayor valor.

Debe combinar esto con asegurarse de que los paquetes de implementación provienen de su servidor de compilación y que la implementación esté automatizada en la medida de lo posible (debería poder pasar del artefacto del servidor de compilación al código implementado en vivo con un esfuerzo mínimo y una tensión mínima) ).

Hmm, asumí que hay una buena configuración de seguimiento de problemas bien ordenada ... también lo necesita y para estar seguro de que se está utilizando correctamente. Lo ideal es que desee que sus aplicaciones en vivo realicen errores a este sistema (o para la clasificación) automáticamente.

Por último, no intentes resolver todos tus problemas a la vez; a mí me parece que construir y probar son los lugares en los que deberías enfocarte primero.

    
respondido por el Murph 19.03.2012 - 15:08
1

La segunda pregunta es más fácil y breve, así que intentaré comenzar con ella

DVCS es un sistema en el que no es posible una fuente de código "autorizada" (excepto "en acuerdo", cuando se usa) y el intercambio de datos P2P sin niveles adicionales (definición personal, no canónica)

Sobre el tema, la primera pregunta

Me temo que la empresa debe reconstruir el flujo de trabajo y replantearse el estilo para obtener "un código predecible y administrado de alguna manera". No puedo decir sobre TFS (excepto la opinión personal y la sensación, que es un sistema débil en la parte de Control de versiones / fusión sin fundamento es malvado /), pero para cualquier VCS en su situación ("Producto" es un conjunto de "Módulos" independientes, cada "Cliente" obtiene "Productos" diferentes: ¿se asume esto correctamente? Prefiero el desarrollo dividido de módulos en sucursales separadas, ¿el Producto tiene como "Supermódulo" (¿también sucursal?), cada módulo vinculado a una revisión específica del módulo- rama, el módulo de desarrollo utiliza el paradigma rama por tarea (y el módulo rama consiste únicamente en conjuntos de combinación).

De esta forma, siempre podrá saber qué "Colección" (es decir, el conjunto de módulos y sus revisiones correspondientes) forman cada "Producto", tiene la posibilidad de hacer CI (para terminar y fusionar ramas de tareas ), Unit-testing and Builds

    
respondido por el Lazy Badger 19.03.2012 - 09:58
1

Pregunta principal del anuncio: Creo que lo que está hablando es exactamente lo que git modelo de ramificación exitoso (y la herramienta de ayuda git flow para admitirlo) se trata. Tener una rama maestra, que siempre está en estado desplegable y hacer todo el trabajo en las ramas de características.

También puede utilizar el proceso utilizado por git en sí, que se deriva del mismo principio básico. En el desarrollo de git-core, todo el trabajo sucede en las ramas características. Las ramas de características se envían al integrador, que ejecuta un script para fusionarlas todas para crear una rama llamada pu (actualizaciones propuestas). Varias personas toman esta rama y trabajan con ella para probarla.

En lugar de integrador, puede hacer que el servidor de integración continua haga esta combinación al comienzo de una compilación. De esa manera, cada vez que alguien del equipo inserta cambios en el repositorio central como una rama de características (probablemente use alguna convención de nomenclatura para indicar qué ramas deben seleccionarse).

En git, la rama de características va a next , master o maint dependiendo de la versión a la que se dirige (maint es para la versión actual de corrección de errores, master para la versión actual en preparación y la siguiente para la siguiente eso), pero no tendrás tantos.

Si bien las características están en pu ("cocinando" en la terminología del mantenedor de git), se rebobinan y la rama pu se descarta y se vuelve a crear cada vez, lo que facilita su revisión, pero no es adecuado para basar otras. trabajar en. Cuando la rama de la función se fusiona en una de las líneas principales, se cierra para rebobinar y las correcciones adicionales se realizan como nuevas confirmaciones.

Personalmente recomendaría git best. Es un poco más difícil de aprender inicialmente, porque crece más orgánicamente, pero al final parece ser más flexible. Pero cualquiera de los tres sistemas distribuidos, git, mercurial y bazaar le servirá bien (y, a menudo, incluso puede mezclarlos, por ejemplo, mercurial puede tirar y empujar desde / hacia el repositorio de git y creo que también puede hacerlo).

Segunda pregunta del anuncio: Me enseñaron que "distribuido", en general, significa que puedes mover objetos y mantener su identidad. Que es exactamente lo que hace el control de versiones distribuido: clonas el repositorio y contiene los mismos compromisos y permite hacer lo mismo con ellos. La facilidad de bifurcación y la operación desconectada son las características principales a nivel de usuario que se derivan del principio de mover las confirmaciones y el diseño gráfico dirigido que lo permite.

    
respondido por el Jan Hudec 19.03.2012 - 12:05
1

Desafortunadamente, no hay una solución conocida para errores en el código :)

Por lo tanto, lo que está buscando es evitar que los checkins no finalizados queden atrapados en la versión principal, y la única respuesta es la combinación de trabajo de rama para cada desarrollador. Hice esto en una compañía anterior usando Clearcase, funcionó bastante bien (aunque tuvimos que tener una docena de administradores de clearcase).

Ahora, asumo también que realiza la corrección de errores en la versión del producto que cada cliente tiene actualmente ... así que tiene un problema de combinación que trae correcciones de errores de la versión A hasta la versión Z. No hay una manera fácil para lidiar con esto, pero tendrá que tener una sucursal para cada versión enviada. La mejor manera de lidiar con esto es mantener las sucursales de funciones solo en la última versión, y hacer que los clientes se actualicen para obtener las nuevas características, al mismo tiempo, realizar correcciones de errores directamente en la rama de lanzamiento y combinarlas con todas las demás sucursales de lanzamiento cuando termine.

No es demasiado agradable, pero puede funcionar muy bien. Mantienes el código organizado y bien separado. También es fácil de entender para los otros desarrolladores: pequeñas correcciones de errores directamente en "el código", cualquier cosa más que un par de líneas se realiza en una rama dedicada donde pueden tomar todo el tiempo que deseen para completarla. (¡tendrás que resolver los problemas de combinación y asegurarles que está bien si 2 devs funcionan en 2 funciones al mismo tiempo!)

Después de un tiempo, también puede introducir ramas de características en las ramas de lanzamiento, donde los errores se corrigen y luego se combinan, pero en mi humilde opinión, esto suele ser más esfuerzo del necesario. Sin embargo, si necesita agregar funciones a las versiones anteriores, deberá seguir este enfoque: bifurcar una rama de versión, luego fusionar el código nuevamente en esa versión, y combinar el cambio hacia las versiones posteriores también. Eso hará que su equipo de prueba sea muy infeliz ya que los lanzamientos se retrasarán considerablemente debido a la necesidad de probar varias versiones repetidamente, y el equipo de desarrollo será infeliz, ya que tendrán que fusionarse mucho antes de que puedan comenzar con un nuevo código (en mi empresa actual esto sucede, principalmente debido a la cantidad de trabajo que tenemos que siempre debe completarse lo antes posible).

DVCS:

básicamente un DVCS es donde todos tienen su propia copia del servidor repo. Tiene algunas ventajas (especialmente en equipos distribuidos con comunicación limitada), pero también tiene algunas desventajas, así que revíselas antes de cambiar a un DVCS. Si es una tienda de Windows, probablemente encontrará que Mercurial es el mejor DVCS para usted.

    
respondido por el gbjbaanb 19.03.2012 - 19:30

Lea otras preguntas en las etiquetas