¿Cuál es una forma realista de manejar parches de software específicos del cliente?

16

Estoy tratando de reunir formas efectivas para que otros hayan resuelto el siguiente problema. En el trabajo, nos hemos visto obligados a lanzar un parche de software (que se instalará en los sistemas de usuario final) que solo queremos que sea visible para un cliente específico. El código personalizado está en su propia rama de control de fuente. El problema es que tenemos dos líneas de código paralelas (y scripts de compilación) para mantener sincronizadas, y cada vez que revisamos el código original tenemos que revisar y probar el código específico del cliente.

Tengo curiosidad, ¿cómo manejan otras organizaciones este escenario? Estamos abiertos a soluciones comerciales y no solo técnicas (relacionadas con el control de origen). Por ejemplo, hemos hablado acerca de decirle al cliente que no pueden recibir actualizaciones en esa sucursal.

Nuestra estrategia de ramificación es así (basada en la Guía de ramificación de Visual Studio TFS , aunque estamos usando Subversion para ello) ingrese la descripción de la imagen aquí

Vimes
fuente
Si estaba usando hgo gitpodría sugerirle que mire el uso de Patch Queues ( Mercurial Queues Extension o Stacked Git ) pero no sé si TFS tiene algo similar.
Mark Booth
Tal vez debería haber especificado que estamos usando Subversion a pesar de que usamos una estrategia de ramificación que sugiere TFS: P ¿Las colas de parche reducirían las pruebas necesarias? Parece que estos son para parches de control de fuente? Estamos tratando con parches que el cliente instala en los sistemas de usuario final.
Vimes
2
Una solución comercial sería: no lo hagas.
JeffO
@JeffO good call =) En cualquier caso, ¿hay alguna forma de hacer de esto un interruptor de tiempo de ejecución impulsado por datos?
Patrick Hughes
1
@JohnB - Lo siento, no lo sé, pero si tiene parches de origen, entonces su sistema de compilación debería poder automatizar las pruebas, además de mantener los parches por cliente fuera de svnlo que significa que no saturan su flujo de trabajo normal. Si parece que las colas de parche podrían ser útiles, puede probarlas usando git-svn o hgsubversion . El uso de una interfaz DVCS para suavizar un flujo de trabajo complicado svnpodría incluso alentar a las personas a considerar la posibilidad de cambiar a un DVCS al por mayor, para obtener todos los demás beneficios.
Mark Booth

Respuestas:

5

Cuando comienza a entregar parches específicos para el cliente, ha creado inmediatamente una nueva versión de su producto que debe mantenerse junto a él. Eso significa que los cambios deben propagarse entre las dos versiones. Por lo general, los parches específicos del cliente son personalizaciones que deben ser propiedad del cliente, incluido el código fuente.

Parece poco probable que un parche para arreglar algo no llegue a la rama principal a menos que sea una solución temporal menos que óptima para un problema inmediato. Si ese es el caso, entonces el parche solo tendrá que mantenerse hasta que la solución esperada llegue a la línea principal.

Charles Lambert
fuente
5

Me parece que la clave es "visible": ¿qué hay de no tener una rama de código separada, sino una opción de configuración que cambia el comportamiento?

Loren Pechtel
fuente
Esto podría funcionar para personalizaciones simples, pero las más complejas podrían hacer que el producto sea más incómodo e inestable para todos los clientes.
FrustratedWithFormsDesigner
3
@FrustratedWithFormsDesigner Las personalizaciones complejas para clientes individuales representan una grave negligencia en la gestión y el diseño del producto. Cualquier solución que requiera una sucursal separada para un solo cliente para un producto representa una deficiencia grave en el producto para satisfacer todas las necesidades de los clientes y una administración deficiente por parte del propietario del producto.
maple_shaft
2
También he visto esta mordedura de mi empleador anterior una y otra vez. Es solo una mala práctica, pero generalmente es algo que la gerencia quiere y no retrocederá. Particularmente si está usando Subversion, esto es solo una pesadilla que no desaparecerá: mantener el código sincronizado dolerá, una y otra vez.
Steve Hill
1
@maple_shaft - ¿Pero pensó hacer la pregunta "¿alguna vez ha utilizado la ramificación de código para implementar la internacionalización"?
psr
3
@maple_shaft: estaba bromeando, pero, en realidad, ese era mi punto, usar la ramificación para manejar la internacionalización es al menos tan malo como las sucursales específicas del cliente. No es discutible en el sentido de que probablemente tampoco quieras trabajar en un lugar así. Es discutible que me fuera bastante fuera de tema.
psr
3

¿Ves esto como algo a corto o largo plazo? El hecho es que el negocio ya ha decidido acomodar a este cliente a tan corto plazo que ya ES una decisión comercial que debe resolverse principalmente mediante prácticas comerciales (aceptar el costo adicional / cobrarle al cliente el costo).

Si es a largo plazo, probablemente verá ahorros si vuelve a factorizar el software para acomodar fácilmente las necesidades de los clientes a través de la configuración (o configuración, etc.).

Si es relativamente a corto plazo, significa que pronto fusionará esos cambios nuevamente en la rama principal / desarrollo y todos los usuarios también verán los cambios, entonces probablemente sea aceptable trabajar dentro de las limitaciones de su situación actual. Como dije, la decisión de qué hacer debería haberse tomado cuando se tomó la decisión de acomodar al cliente.

Larga historia corta. Arreglo técnico a largo plazo, trato a corto plazo.

Por supuesto, hay un punto donde es un lanzamiento de moneda. Si estás en ese punto, entonces haría lo que prefieran los desarrolladores.

ElGringoGrande
fuente
2

También usamos subversión, y nos encontramos con tal escenario exacto.

Aquí hay algunos puntos clave para recordar:

  1. Si bien es necesario uno debe evitar sucursales específicas para los clientes, la necesidad debe ser minimizada lo más posible; siempre pregunte si es posible generalizar la solución que podría funcionar para todos.

  2. Las sucursales específicas del cliente deben originarse en una nueva versión. Supongamos que tiene una versión 1.2 y que ha derivado de la versión 1.2.1 hasta 1.2.11: las sucursales del cliente deben tener permitidos todos los parches, por lo tanto, la sucursal del cliente debe seguir siendo compatible con respecto a la versión principal.

  3. La sucursal específica del cliente debe crearse de nuevo cuando comience una nueva versión no compatible. La parte desafortunada es que de alguna manera puede requerir volver a hacer el trabajo. Una solución puede ser crear todos los parches de las sucursales de los clientes que se deben extraer y todo lo que sea compatible puede aplicarse a la nueva sucursal del cliente.

  4. Siempre, bajo ninguna circunstancia, debe retrasar los cambios específicos del cliente para liberar la rama o la troncal. Sin embargo, idealmente uno debería tratar de generalizar el trabajo de tal manera que dicho trabajo específico del cliente se mantenga reducido.

He intentado juntar esta idea para mostrarla diagrama a continuación:

Dipan Mehta
fuente
1

¿Qué tal introducir un mecanismo de extensión en su código?

Tu código principal tiene:

class Foo
{
}

Cuando se inicia el programa, busca DLL / equivalente moral, en su carpeta de inicio para las personalizaciones locales. Si encuentra uno, se carga y puede contener una versión específica de la compañía de Foo

class FooForABC : Foo
{
}

FooForABC implementa el mismo comportamiento que Foo, pero anula las funciones según sea necesario para proporcionar el comportamiento específico que ABC necesita. La técnica debe ser lo suficientemente flexible como para manejar cualquier escenario que necesite soportar.

Winston Ewert
fuente