visual - ¿Cómo debo usar Nuget para el desarrollo empresarial interno?
nuget microsoft (4)
En nuestra empresa, hemos resuelto el problema de las actualizaciones en cascada con la siguiente configuración. Primero tenemos la siguiente configuración para nuestros repositorios NuGet y servidor de compilación.
- Existe un repositorio NuGet interno que contiene todos los paquetes publicados para la compañía. Este repositorio es solo un directorio compartido en uno de nuestros servidores.
Cada desarrollador puede tener (pero no necesita tener) uno o más directorios en su propia máquina que sirve como un repositorio de paquetes NuGet local. Al usar una configuration NuGet específica para el usuario configuration el desarrollador puede controlar en qué orden NuGet busca en los repositorios de paquetes para encontrar paquetes.
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageRestore> <add key="enabled" value="True" /> </packageRestore> <packageSources> <add key="Dev" value="D:/dev/testpackages" /> <add key="Company" value="<UNC_ADDRESS_COMPANY_REPOSITORY>" /> <add key="NuGet official package source" value="https://nuget.org/api/v2/" /> </packageSources> <disabledPackageSources /> <activePackageSource> <add key="All" value="(Aggregate source)" /> </activePackageSource> </configuration>
Todas las soluciones tienen activada la restauración automática de paquetes, de modo que no tenemos que comprometer los paquetes con nuestro sistema de control de versiones.
- Los desarrolladores solo controlan 3 de los 4 números de versión; por ejemplo, si la versión es
<MAJOR>.<MINOR>.<BUILD>.<REVISION>
desarrolladores solo pueden cambiar los números mayor, menor y de compilación, el número de revisión se establece en 0 excepto en construcciones hechas por el servidor de compilación donde está el número de compilación de la compilación. Esto es importante porque significa que para una versión dada que consiste en un número mayor, menor y de compilación, el servidor de compilación siempre producirá el número de versión más alto. Esto significa nuevamente que NuGet preferirá tomar la versión del paquete proveniente del repositorio de paquetes de la compañía (que solo obtiene paquetes a través del servidor de compilación).
Para realizar un cambio en una de las bibliotecas base, se utilizan dos procesos posibles. El primer proceso es:
- Realice los cambios en la biblioteca base (A). Actualice la versión de (A) si es necesario.
- Ejecute el script MsBuild para construir los binarios y crear los paquetes NuGet de (A)
- Copie los nuevos paquetes NuGet al repositorio de paquetes en la máquina local
- En el proyecto dependiente (B) actualice a los nuevos paquetes de (A) que acaban de colocarse en el repositorio de paquetes de la máquina local (que debe ser de una versión superior a los disponibles en el repositorio de toda la compañía, o NuGet.org)
- Haz los cambios en (B).
Si se requieren más cambios en (A), repita los pasos 1, 2 y 3 y luego elimine el paquete de (A) del directorio de trabajo de (B). La próxima vez que se ejecute la compilación, NuGet buscará la versión específica de (A), la encontrará en el repositorio de la máquina local y la volverá a instalar . Tenga en cuenta que la caché NuGet puede frustrar este proceso algunas veces, aunque parece que NuGet no puede almacenar en caché los paquetes que provienen de la misma máquina (?).
Una vez que se completan los cambios, nosotros:
- Confirme los cambios en (A). El servidor de compilación ejecutará la construcción de integración para verificar que todo funcione.
- Indique al servidor de compilación que ejecute la compilación de lanzamiento, que crea los archivos binarios y envía los paquetes NuGet al repositorio NuGet de toda la empresa.
- En (B), actualice a la última versión de (A) (que debe tener un número de versión mayor que el paquete de prueba porque el paquete de prueba debe tener la versión abc0 mientras que la versión de nueva compilación en el repositorio de toda la compañía debe ser abc donde> 0
- Confirme los cambios en (B). Espere a que el servidor de compilación termine las pruebas de integración
- Dile al servidor de compilación que ejecute la versión de lanzamiento para (B).
Otra forma de hacer el trabajo de desarrollo es siguiendo los siguientes pasos
- Realice los cambios en la biblioteca base (A). Actualice la versión de (A) si es necesario.
- Construye los binarios
- Copie los binarios en la ubicación donde NuGet descomprime el paquete de (A) para el proyecto (B) (por ejemplo,
c:/mysource/projectB/packages/ProjectA.1.2.3.4
) - Realice los cambios necesarios en el proyecto (B)
El proceso de confirmación sigue siendo el mismo, el proyecto (A) debe comprometerse primero y, en el proyecto (B), la referencia de NuGet a (A) debe actualizarse.
El primer enfoque es ligeramente más limpio porque este proceso también advierte si hay fallas en el paquete NuGet de (A) (por ejemplo, se olvidó agregar un nuevo ensamblaje) mientras que en el segundo proceso el desarrollador no sabrá hasta después del paquete para (A) ) ha sido publicado.
Usamos Nuget para nuestro desarrollo interno que nos permite compartir código entre equipos. Sin embargo, nos topamos con problemas cuando una persona está trabajando en un código que se implementará en varios paquetes nuget al mismo tiempo. Por ejemplo
A depende de B, que depende de C.
A, B y C tienen sus artefactos enviados a Nuget y así es como administramos las dependencias entre A, B y C. El problema que encontramos es que si un desarrollador desea hacer cambios en C y ver rápidamente esos cambios reflejados en A, tiene que pasar por el siguiente proceso.
- Haga el cambio en C.
- Empujar cambiar a git
- CI recoge el cambio a C y crea e implementa un nuevo paquete nuget.
- Vaya a B y actualice la referencia a C usando un comando nuget update package.
- Empuje hacia arriba el cambio al archivo packages.config hasta git
- CI toma el cambio a B y construye y despliega nuevo paquete nuget para B
- Ahora abra A y cambie la referencia al paquete de actualización B y nuget
- Haga cambios en A para ir junto con los cambios en B (y transitoriamente C)
Esto parece extremadamente doloroso y está causando que algunos de nuestros desarrolladores cuestionen la elección de Nuget para nuestro código desarrollado internamente. A todos les gusta consumir paquetes externos.
¿Hay algún flujo de trabajo mejor para usar Nuget internamente?
Nuget fue diseñado para compartir libraries de terceros. Planeamos usar Nuget internamente para todos los códigos comunes que pueden compartirse entre proyectos. Cosas como una capa de datos común, cadena y otras funciones de expresión regular, componentes de correo electrónico y otros artefactos como ese.
La única forma en que veo que Nuget es de alguna ayuda es cuando los componentes, código o artefactos que está compartiendo en equipos / proyectos son estables y tienen su propio ciclo de lanzamiento que es diferente al ciclo de lanzamiento de su proyecto. Para sus necesidades, Nuget es un exceso. Es posible que tenga una mejor productividad que vincule todos esos proyectos dentro de la misma solución. La estructura de su solución debe incluir los tres proyectos A, B y C como proyectos dependientes a los que se hace referencia internamente cuando sea necesario.
Tu tienes dos opciones aquí:
- Ejecute una instancia de NuGet Gallery dentro de su organización. Este es el código que ejecuta nuget.org
- Obtenga una licencia para Artifactory Pro , que tiene incorporado el soporte Nuget y actúa como un repositorio de Nuget.
He usado ambos, y el # 1 es una opción razonable para empezar, pero NuGet Galley está optimizado y diseñado para nuget.org, no para uso en las instalaciones / empresas, por lo que eliminar elementos es complicado (se requiere SQL manual). )
Yo diría que debe pagar la tarifa (baja) de la licencia de Artifactory Pro: es un producto excelente, y el equipo de JFrog está realmente entusiasmado y conectado.
No debe usar nuget.org para paquetes internos / empresariales; nuget.org está diseñado para librerías de fuente abierta / de terceros, no para dependencias internas de compilación.
EDITAR : en términos de flujo de trabajo, ¿por qué estás poniendo código compartido en múltiples paquetes? Si el código necesita ser compartido, debe ir en su propio paquete separado.
EDIT 2 : para acelerar el flujo de trabajo de cambio de código para el desarrollador, puede usar nuget.exe
(el cliente de línea de comandos) y usar compilaciones accesibles en la línea de comandos, para que pueda orientar una ejecución de compilación de "desarrollador". Luego, en su compilación de "desarrollador" (a diferencia de la compilación CI), especifique "Fuente como ruta local" (por ejemplo, nuget install B -Source C:/Code/B
) cuando desee extraer la B
recién actualizada como una dependencia. y construir contra eso; del mismo modo para C
u otros paquetes locales recién actualizados. Entonces, cuando A
, B
y C
todos muy correctos, puede hacerlos pasar a todos (en orden inverso de dependencia) y dejar que CI haga lo suyo.
Sin embargo , también debe preguntarse si la separación de su paquete es realmente apropiada si tiene que hacer este ''baile'' de compilación a menudo, ya que esto sugiere que todo el código debe estar en un paquete único o posiblemente dividido en líneas diferentes en paquetes separados. Una característica clave de un paquete bien definido es que no debería causar efectos dominantes en otros paquetes, ciertamente no si está utilizando versiones semánticas de manera efectiva.
Editar 3 Algunas aclaraciones solicitadas por marcelo-oliveira: "compilaciones accesibles por línea de comandos" son compilaciones que pueden tener lugar completamente desde la línea de comandos, sin usar Visual Studio, generalmente a través de archivos por lotes. Una "construcción de desarrollador" es una construcción que un desarrollador ejecuta desde su estación de trabajo, a diferencia de la construcción de CI que se ejecuta en el servidor de CI (ambas construcciones deberían ser esencialmente las mismas).
Si A, B y C tienen la misma solución , puede crear paquetes NuGet para ellos en una sola compilación.
Solo asegúrese de que el paquete que lo usa tenga el nuevo número de versión (suponiendo que su compilación no lo cambie aleatoriamente) del paquete del que depende.
Si A, B y C están intencionalmente bajo diferentes soluciones, por ejemplo, A está bajo una solución de infraestructura y B está bajo una solución de producto, entonces la única sugerencia que tengo para usted es definir sus compilaciones de CI ejecutadas al momento del registro y no periódicamente.
Editar:
Otra opción es crear paquetes push prelanzamiento (por ejemplo, versión 1.0.0-alfa) para su servidor NuGet durante las compilaciones locales, de esta forma los desarrolladores pueden experimentar con el paquete antes de crear una versión de lanzamiento.