domingo, 21 de abril de 2013

Automatizando Builds con GXserver y CruiseControl.NET

Imagen de 'Automatizando Builds con GXserver y CruiseControl.NET'Una de las ventajas de utilizar un repositorio de control de cambios, como es GeneXus Server para el desarrollo con GeneXus, es la posibilidad de automatizar el proceso de armado de un proyecto a partir de los cambios que van haciendo los desarrolladores.

Esta es una guía de cómo poner esto en práctica.


Para qué automatizar el armado del proyecto

Tener un proceso automático es uno de los componentes básicos de Integración Continua, una práctica en el desarrollo de software que consiste en integrar frecuentemente (varias veces por día), el trabajo de los diferentes desarrolladores con el objetivo de detectar lo más pronto posible los problemas de integración. Los ambientes de trabajo de los diferentes desarrolladores se integran por medio de los commits que estos hacen a un repositorio central, y la integración es verificada por un proceso automático de armado del proyecto, que también puede incluir otros tests.

Pero sea en el contexto de Integración Continua, o de integraciones menos frecuentes, el solo hecho automatizar el armado a partir de lo que está en el repositorio tiene ventajas en sí mismo.

El armado de un sistema suele ser un proceso complejo que involucra múltiples etapas, desde obtener los últimos cambios del repositorio, generar y compilar todo lo necesario, ejecutar reorganizaciones, hasta mover los programas al ambiente de ejecución, por nombrar sólo los más visibles.

Si a esto le agregamos los detalles del armado de múltiples versiones del proyecto (que toman cosas de diferentes lugares, necesitan componentes de diferentes versiones, que dejan los resultados en otro lugar, etc.), y diferentes variantes de armado (con o sin tests, armando o no ciertos módulos, produciendo o no un setup, etc.), la complejidad puede crecer significativamente.

Automatizar este proceso implica, entre otras cosas:
  • No tener que dedicar a una persona para ejecutar cada etapa, verificar los resultados, decidir el siguiente paso a ejecutar, etc.,
  • No depender del conocimiento de una persona para ejecutar estos pasos correctamente y en el orden adecuado. ¿Qué pasa cuando esta persona se enferma o se toma vacaciones?
  • No correr el riesgo de que esa persona se equivoque, cosa que frecuentemente ocurre en los momentos de mayor estrés, es decir, cuando puede producir más daño.
Pero además, el tener la posibilidad de ejecutar todo el proceso de armado en forma totalmente desatendida y con un solo comando, nos habilita la posibilidad de dar el siguiente gran paso, que es automatizar también el propio disparo del proceso. Por ejemplo, uno podría querer que cada cierto tiempo se verificara si hubo nuevos commits en el repositorio, y que en caso afirmativo se ejecutara automáticamente el armado del proyecto. Para algunos podría querer hacer esto varias veces por día, para otros sólo durante las noches e incluso algunos solo durante los fines de semana. Aquí es donde entran en escena los llamados servidores de integración continua, de los cuales CruiseControl.NET es un ejemplo.

Combinando GeneXus Server y CruiseControl.NET

Un servidor de integración continua es un servicio que se encarga de monitorear cierto repositorio de software para ver si se produjeron cambios, en cuyo caso puede disparar un proceso de armado del proyecto.

En nuestro caso, lo que vamos a utilizar como servidor de integración continua es CruiseControl.NET. Este software va a monitorear con la frecuencia que indiquemos bases de conocimiento administradas por un GeneXus Server, y en caso de que se hayan producido nuevos commits, se encargará de actualizar una copia de la KB, y ejecutar el proceso de armado. Tanto la actualización como el armado se ejecutarán a través de tareas MSBuild, de forma que no sea necesario levantar GeneXus para ello.

Guía de Configuración

Proceso general

En primer lugar se necesita una máquina en la que estén instalados GeneXus, y CruiseControl.NET. También será necesario poder acceder desde allí a un GXserver, que podrá estar instalado en la misma máquina o no.

Luego de instalar el software conviene obtener desde GXserver una copia de la KB y ejecutar el build de forma manual, para asegurarse de que todo funciona correctamente. Luego de eso se puede proceder a la automatización del build a través de Cruise Control.

Paso 1 - Seleccionar la máquina

El primer paso es elegir la máquina en la que se va a instalar el servidor de Builds. Esta máquina tiene que tener la capacidad de tener instalado tanto GeneXus como CruiseControl.NET.

Requerimientos de instalación de GeneXus
Requerimientos de instalación de CruiseControl.NET

Para poder utilizar la consola web de CruiseControl.NET (WebDashboard) es necesario también tener instalado IIS con ASP.NET habilitado.

En caso de que el GXserver a utilizar no esté en la misma máquina, será necesario tener conectividad HTTPS con la máquina en la que esté instalado GXserver, ya sea a través de intranet o internet.

Paso 2 - Descargar e instalar GeneXus

Es necesario instalar GeneXus versión X Evolution 1 U7 en adelante.

Descargar GeneXus X Evolution 2
Manual de instalación de GeneXus

El programa instalación de GeneXus guarda la ruta del directorio de instalación en la variable de entorno GX_PROGRAM_DIR. Verificar el contenido de esta variable, y ajustarlo en caso de que fuera necesario.

Copiar los siguientes archivos en el directorio de instalación de GeneXus:

Artech.Samples.GXserverExtraTasks.dll
Artech.Samples.GXserverExtraTasks.targets

Paso 3 - Descargar e instalar el cliente de GXserver por línea de comando

Instalar los siguientes archivos en algún directorio local, por ejemplo C:\GXserverClient. En adelante nos referiremos a este directorio como [GXserverClient].

TeamDev.exe
TeamDev.exe.config
TeamDev.msbuild

Paso 4 - Descargar e instalar CruiseControl.NET.

Descargar CruiseControl.NET
Documentación de CruiseControl.NET

El setup presenta tres componentes para instalar. Es necesario como mínimo el CruiseControl.NET Server y se recomienda también instalar el Web Dashboard.



También se recomienda dejar marcadas las opciones de "Install CC.Net server as Windows service" y "Create virtual directory in IIS for Web Dashboard".



Como es usual, se puede elegir también el directorio de instalación, que por defecto es algo similar a C:\Program Files\CruiseControl.Net. En adelante, nos referiremos a este directorio de instalación como [CruiseControl]

Paso 5 - Agregar add-in de GXserver a Cruise Control

CruiseControl reconoce en su configuración por defecto varios sistemas de repositorio (SVN, CVS, etc.). Con este add-in, CruiseControl puede reconocer también a GXserver como un repositorio válido e interactuar con él.

Copiar CCNet.GXserver.Plugin.dll al directorio [CruiseControl]\server.

Paso 6 - Iniciar servidor de CruiseControl.NET

CruiseControl.NET puede ser ejecutado de dos maneras: como un servicio de Windows o como una aplicación de consola. Para el funcionamiento normal, lo recomendado es utilizar el servicio, pero en las primeras etapas de configuración, puede ser útil la aplicación de consola, ya que brinda información inmediata con mensajes en la consola y puede ser más fácil de detener y volver a ejecutar. Una vez que se ha estabilizado la configuración se puede pasar a utilizar el servicio.

Ambas aplicaciones se encuentran en el directorio [CruiseControl]\server, y se llaman ccservice.exe (el servicio) y ccnet.exe (la aplicación de consola), y cuentan con sus respectivos archivos de configuración ccservice.exe.config y ccnet.exe.config. En estos archivos se pueden configurar aspectos específicos a una u otra forma de ejecutar, y cada uno de ellos utiliza un tercer archivo de configuración (ccnet.config), usualmente compartido, donde en particular se establecen cuáles son los diferentes proyectos de armado (build projects).

Cada proyecto de armado indica un cierto repositorio de fuentes, qué cosas obtener de él, cada cuánto hay que consultarlo para saber si hubo cambios, dónde mantener una copia local de los fuentes, y qué ejecutar para realizar el build.

La ubicación por defecto del archivo ccnet.config es también en el directorio [CruiseControl]\server, aunque se puede especificar otra ubicación agregando una entrada como la siguiente en la sección <appSettings> de ccservice.exe.config y ccnet.exe.config:

<appSettings>
   <!-- Without this appSetting ccservice will look for ccnet.config
        in its own directory.
-->
   <add key="ccnet.config" value="c:\some\path\to\ccnet.config"/>
   ...
</appSettings>
A su vez, el contenido inicial del archivo ccnet.config es el siguiente:

<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
  <!-- This is your CruiseControl.NET Server Configuration file. Add
       your projects below!
-->

  <project name="MyFirstProject"
           description="demoproject showing a small config">
    <triggers>
      <!-- check the source control every X time for changes,
       and run the tasks if changes are found -->
     <intervalTrigger name="continuous"
                      seconds="30"
                      buildCondition="IfModificationExists"
                      initialSeconds="5"/>
    </triggers>

   <sourcecontrol type="nullSourceControl"
                  alwaysModified="true" />

    <tasks>
      <exec>
        <!-- if you want the task to fail,
             ping an unknown server
-->
       <executable>ping.exe</executable>
       <buildArgs>localhost</buildArgs>
       <buildTimeoutSeconds>15</buildTimeoutSeconds>
       <description>Pinging a server</description>
      </exec>
    </tasks>

    <publishers>
     <xmllogger />
     <artifactcleanup cleanUpMethod="KeepLastXBuilds"
                      cleanUpValue="50" />
    </publishers>

  </project>

</cruisecontrol>


Como se ejemplifica allí, en cada </project> declarado en el archivo ccnet.config, se pueden establecer una serie de elementos:
  • <triggers> - disparadores de la consulta por cambios en los fuentes. En el ejemplo, el disparo es simplemente por tiempo, y se consultará al repositorio si hay nuevos cambios cada 30 segundos, y se ejecutará el build si hay modificaciones.
  • <sourcecontrol> - el repositorio desde el cual se obtienen los fuentes. El tipo de repositorio puede ser alguno de los repositorios estándar ("svn", "cvs", etc.) o bien, como veremos más adelante, gracias al plugin que instalamos en el paso 4, también "gxserver". En el ejemplo se utiliza un tipo especial "nullSourceControl", que tiene una respuesta fija como que siempre hay nuevos cambios.
  • <tasks> - las tareas a ejecutar cuando se encuentran cambios en los fuentes. Usualmente aquí se utiliza una tarea que ejecute el proceso de build, y en el ejemplo esto es simulado con un comando ping, simplemente para que ejecute algo.
  • <publishers> - son tareas a ejecutar luego de finalizado el build y generalmente se utiliza para recolectar y publicar los resultados.
Esta configuración inicial no realiza el armado de ningún fuente, pero es útil para ejecutar el CruiseControl.NET y verificar si funciona hasta este punto. Una vez en funcionamiento, cualquier cambio en el archivo de configuración será detectado automáticamente.

Para iniciar el servidor, vamos a ejecutar el ccnet.exe desde una ventana de comandos (alternativamente podemos ejecutar la opción CruiseControl.NET en el menú de inicio de Windows.

Luego de iniciar el servidor, para verificar que todo está funcionando bien, se puede acceder a la URL del servidor: [http://localhost/ccnet], en donde aparecerá la consola (Web Dashboard) de CruiseControl.NET:

Paso 7 - Crear la copia de trabajo de la KB

En cada item de armado en CruiseControl.NET, a los cuales se les llama proyectos (projects) se va a especificar cuál es la KB en GXserver de que se trata, qué versión (si hay más de una), qué environment, etc.. Para cada uno de esos proyectos, se va a especificar también la ubicación de una KB local, que se utilizará como copia de trabajo para actualizar con lo que haya en GXserver y realizar el proceso de build.

Se recomienda centralizar todas las copias de trabajo que vayan a ser utilizadas con CruiseControl.NET en una misma estructura de directorios, de forma tal que para cada proyecto exista un directorio, dentro del cual esté como hijo el directorio de la KB de trabajo propiamente dicha.

Por ejemplo, si se va a automatizar el proceso de Build de dos KBs, una KB llamada Bobsville (en su versión principal y en otra llamada "Version 1.0"), y otra KB llamada Sunflower Valley (en su versión principal y en otra llamada "Versión 2.2"), el árbol de directorios podría ser el siguiente:

CruiseControlData
  |
   --- Bobsville
  |      |
  |       --- Principal
  |      |      |
  |      |       --- WorkingCopy
  |      |
  |       --- Version1.0
  |             |
  |              --- WorkingCopy
  |
   --- Sunflower Valley
  |      |
  |       --- Principal
  |      |      |
  |      |       --- WorkingCopy
  |      |
  |       --- Version2.2
  |             |
  |              --- WorkingCopy
  |
  .
  .
  .
Los proyectos que corresponden a una misma KB del server (Bobsville y Sunflower Valley en este caso) aparecen allí agrupados bajo un mismo directorio, aunque esto no es estrictamente necesario. Lo que sí es importante, por razones que se verán más adelante, es que para cada proyecto de armado, exista un directorio específico al proyecto, dentro del cual esté a su vez el directorio de la KB de trabajo.

A los efectos de continuar con el proceso de configuracíón de la integración continua, vamos a considerar que automatizaremos en primer lugar el armado de la versión principal de la KB Bobsville, para lo cual crearemos la copia de trabajo en el directorio C:\CruiseControlData\Bobsville\Principal\WorkingCopy. La KB Bobsville se puede obtener del GXserver de Sandbox de la Evolution 2, es decir en la URL http://sandbox.genexusserver.com/xev2. A continuación se puede ver el contenido de la ventana de Create Knowledge Base from GeneXus Server al momento de crear esta copia de trabajo.

Paso 8 - Primer update y build manual

Luego de crear la copia de trabajo es necesario hacer un Update y un Build, lo cual a su vez requiere definir (o crear) la base de datos operativa, especificar y generar todo por primera vez. Este proceso podría evitarse si se parte de una KB de trabajo existente que ya esté armada, y se copia para aquí con todos sus archivos ya generados.

En cualquier caso, lo importante es verificar que es posible hacer un Update y un Build en forma manual, resolviendo cualquier problema que pudiera surgir, para estar seguros de que está todo bien configurado con respecto a GeneXus y GXserver, y que a partir de este punto solo es necesario proceder a la automatización.

Paso 9 - Configurar el proyecto de armado

Para configurar un proyecto de armado es necesario editar el archivo ccnet.config, para agregar en el XML un nuevo elemento de tipo <project>.

En primer lugar, vamos a declarar algunas variables, cuyo valor depende de cada instalación, y que se van a referenciar después desde la declaración de los datos del proyecto. De esta forma, esas variables pueden ser compartidas para varios proyectos y es más sencillo actualizarlas. Copiar lo siguiente inmediatamente después del elemento raíz del XML (<cruisecontrol xmlns:cb="urn:ccnet.config.builder">):

<!-- GeneXus installations -->
<cb:define GxXEv1U8Dir="C:\Program Files\Artech\GeneXus\GeneXusXEv1U8" />
<cb:define GxXEv2U2="C:\Program Files\Artech\GeneXus\GeneXusXEv2U2" />
<cb:define GxDefault="$(GxXEv2U2)" />

<!-- GXserver credentials -->
<cb:define GXserverUser="GXtechnical\user" />
<cb:define GXserverPassword="**********" />

<!-- MSBuild executable -->
<cb:define MSBuildExe="C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe" />

<!-- CruiseControl configuration -->
<cb:define CruiseControlServerDir="C:\Program Files\CruiseControl.NET\server" />
<
cb:define CruiseControlDataDir="C:\CruiseControlData" />
<cb:define GXserverClientDir="C:\GXserverClient" />
<cb:define TeamDevExePath="$(GXserverClientDir)\TeamDev.exe" />
Naturalmente que es necesario modificar algunos de los valores de estas variables (aquellos resaltados con fondo amarillo) con lo que corresponda en cada caso. Luego, a continuación de estas declaraciones de variables, hay que agregar lo siguiente que es la declaración del proyecto de armado:

<project name="Bobsville Principal">
  <sourcecontrol type="gxserver">
    <serverUrl>http://sandbox.genexusserver.com/xev2</serverUrl>
    <serverUsername>$(GXserverUser)</serverUsername>
    <serverPassword>$(GXserverPassword)</serverPassword>
    <serverKbAlias>Bobsville</serverKbAlias>
    <serverKbVersion>Bobsville</serverKbVersion>
    <getAllKbVersions>false</getAllKbVersions>
    <workingDirectory>$(CruiseControlDataDir)\Bobsville\Principal\WorkingCopy</workingDirectory>
    <workingVersion></workingVersion>
    <workingEnvironment></workingEnvironment>
    <localSettings>$(CruiseControlDataDir)\Bobsville\Principal\settings.local</localSettings >
    <dbaseServerInstance></dbaseServerInstance>
    <createDbInKbFolder>true</createDbInKbFolder>
    <dbaseUseIntegratedSecurity>true</dbaseUseIntegratedSecurity>
    <dbaseServerUsername></dbaseServerUsername>
    <dbaseServerPassword></dbaseServerPassword>
    <dbaseName></dbaseName>
    <executable>$(TeamDevExePath)</executable>
    <teamDevTasks>"$(GXserverClientDir)\TeamDev.msbuild"</teamDevTasks>
    <msbuildExecutable>$(MSBuildExe)</msbuildExecutable>
    <autoGetSource>true</autoGetSource>
    <cleanCopy>false</cleanCopy>
    <tagOnSuccess>false</tagOnSuccess>
  </sourcecontrol>
  <triggers>
    <intervalTrigger seconds="600"/>
  </triggers>
  <tasks>
    <msbuild>
      <executable>$(MSBuildExe)</executable>
      <projectFile>$(GXserverClientDir)\TeamDev.msbuild</projectFile>
      <buildArgs>
        /v:Normal
        /t:Build
        /p:WorkingDirectory="$(CruiseControlDataDir)\Bobsville\Principal\WorkingCopy"
        /p:ServerUsername=$(GXserverUser)
        /p:ServerPassword=$(GXserverPassword)
        /p:GX_PROGRAM_DIR="$(GxDefault)"
        /p:MSBuildExtensionsPath="c:\Program Files\MSBuild"
      </buildArgs>
      <logger>$(CruiseControlServerDir)\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
      <timeout>18000</timeout>
    </msbuild>
  </tasks>
  <publishers>
    <xmllogger />
    <artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="50" />
    <modificationHistory />
  </publishers>
</project>
Al salvar el contenido del archivo ccnet.config, el cambio será detectado por CruiseControl.NET y si volvemos a la consola (Web Dashboard), veremos ahora nuestro nuevo proyecto. A partir de ahora, cada vez que CruiseControl.NET detecte que hay un nuevo commit (va a estar consultando a GXserver cada 10 minutos, según lo que pusimos en <intervalTrigger>) ejecutará el build de la KB, y podremos ver los resultados desde la propia consola.

¿Todavía por aquí?

Si llegaron hasta este punto, habiendo seguido todos los pasos de arriba, me interesa saber cómo les fue. ¿Problemas, errores, sugerencias?

¿Funcionó todo bien? Si es así, los invito a firmar en el Libro de Visitas. Busquen en la KB Bobsville un objeto con ese nombre, anótense allí y hagan commit para que todos nos enteremos.

Por supuesto, siéntanse libres también de colaborar en el desarrollo de la KB Bobsville. ♦

Imagen: Assembly line robots, publicada por Annette Davis, bajo licencia CC BY-NC-ND 3.0.

21 comentarios:

genexus dijo...

Gracias José,

Voy a intentarlo y te cuento como
me fue.

Saludos,
gab

Unknown dijo...

Buenísimo, Gabriel. Cualquier problema avisá. Saludos,

Nicolas Pogulanik dijo...

Hola Jose. Te comento que probamos el Cruise Control siguiendo tu paso a paso y funciona de diez. Hay un pequeño gran detalle. Detectamos que el status que se muestra en el dashboard corresponde a la salida del msbuild, es decir si fue exitoso se pone en verde, de lo contrario en rojo. Lo que no podemos hacer es mostrar en rojo para los casos en donde falla el compilador Java, dado que esto se hace en una etapa posterior al msbuild y aparentemente no se esta parseando el resultado de esta operación para mostrarlo en el dashboard. Se que en general es raro comitear algo que rompe el build dado que genexus hace controles al guardar un objeto, pero a drede logramos comitear algo que no compila para ver como se comporta el Cruise Control. Te dejo la inquietud y desde ya muchas gracias por el aporte :D

Unknown dijo...

Hola, Nicolás

Tenes razón. Es un error en la tarea del BuildAll que vamos a tener corregido para el U4 de Evo2.

Estoy tratando de encontrar una solución que puedan usar con las versiones actuales.

Unknown dijo...

Nicolás:

Creo que encontré una forma de hacer que funcione bien, sin que tengan que esperar al arreglo que comentaba antes.

Ya actualicé el post con los cambios, pero para ustedes (y para cualquiera que hubiera seguido los pasos como estaban antes), lo nuevo está en el Paso 2, que hay que copiar 2 archivos más a la instalación de GeneXus, y en el paso 3, que hay que volver a descargar el archivo TeamDev.msbuild que va en el directorio [GXserverClient].

Avisame por favor si esto te funciona bien.

Nota: la Artech.Samples.GXserverExtraTasks.dll que se usa para esta solución la compilé y probé sólo en Evo2 U3, pero debería funcionar bien en cualquier otra versión Evo2 o Evo1. Si alguien tiene algún problema con esto y me avisa, la puedo recompilar para otras versiones.

Saludos,

Nicolas Pogulanik dijo...

Jose, funcionó perfectamente con los nuevos archivos. Muchísimas gracias y te mantengo informado si surge algo.

Sandrix dijo...
Este comentario ha sido eliminado por el autor.
Sandrix dijo...

José.

Muito bom o artigo. Será de grande ajuda!

Eu tive que alterar o arquivo teamdev.msbuild

e substituir as linhas:

<Import Project="C:\Program Files (x86)\Artech\GeneXus\GeneXusXEv2\GeneXus.Tasks.targets"/>
<Import Project="C:\Program Files (x86)\Artech\GeneXus\GeneXusXEv2\Genexus.Server.Tasks.targets"/>
<Import Project="C:\Program Files (x86)\Artech\GeneXus\GeneXusXEv2\Artech.Samples.GXserverExtraTasks.targets"/>




Pois estava aparecendo um erro no CruiseControl:

ThoughtWorks.CruiseControl.Core.CruiseControlException: Source control operation failed: . Process command: C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe "D:\GXserverClient\TeamDev.msbuild" -t:Update -p:WorkingDirectory=D:\CruiseControlData\PortalServicos\Principal\PortalServicosWorkingCopy -p:ServerUsername=Local\GxServer -p:ServerPassword=gxserver -v:detailed

Analisando com calma percebi que a tarefa Build (-t:Build) implicitamente fazia um Update (conforme comando acima) e esse update não estava configurando o caminho do genexus.

Unknown dijo...

Hola, Sandro

Revisa la variable de entorno GX_PROGRAM_DIR. Si la tienes configurada, no sería necesario modificar el teamdev.msbuild

Saludos,

AJ - FRIGOBYTE dijo...

Pra mim da esse erro:
"No connection could be made because the target machine actively refused it 127.0.0.1:21234"

No Windows 2008 server e no Windows 2012 server.

AJ - FRIGOBYTE dijo...

É compativel com o GX Tilo ?

José dijo...

Hola, AJ

¿Te sigue dando ese error? ¿En qué momento? Mira en log del build para tener más contexto de en qué momento se produce el error y qué operación es la que está fallando.

Con respecto a GX Tilo, entiendo que sí, que todo esto es compatible también.

AJ - FRIGOBYTE dijo...

Olá. Obrigado pela resposta.

O erro dá no painel de controle web do CCNET.

Tanto na maquina onde segui todos os passos do seu post, quanto nas maquinas onde apenas instalei o CCNET.

Saudações

Fabian Baptista dijo...

Gracias José por este post. Realmente muy útil. Una pregunta, están los fuentes de CCNet.GXserver.Plugin.GXserverSourceControl disponibles???
porque tengo un error de 'Caracteres no válidos en la ruta de acceso.' al momento de integrar cuando verifica si hay modificaciones pero no lo puedo resolver, así lo puedo debuggear. saludos!

Unknown dijo...

Hola, Fabián

Sí, esta disponible desde hace un tiempo, en el proyecto de GeneXus Tools:
https://www.assembla.com/spaces/genexus-misc-tools/wiki

El url SVN general es https://www.assembla.com/code/genexus-misc-tools/subversion/nodes/21/trunk y dentro de eso hay una carpeta ContinuousIntegration.

Abrazo,

Unknown dijo...

José, muy bueno. Con esto lo pude solucionar en seguida, gracias!!!

Tengo una duda: ¿cómo hago para que el Build de la Working copy se haga igual (por más que no hayan cambios en el server)?

Mirando los parámetros que se le pasan al MSbuild de TeamDev, se le pasa /t:Build, y eso llama a BuildAllCheckErrors. Si bien hay un parámetro para hacer "force Rebuild" pero no le encontré la vuelta para que haga build siempre (haya o no updates)

algun pique?

Unknown dijo...

Por nada, Fabián :)

Con respecto a lo que preguntás, fijate que en el ccnet.config estamos poniendo

  <triggers>
    <intervalTrigger seconds="600"/>
  </triggers>

Ese bloque especifica el tipo de disparador del build (por intervalo) y cada cuanto chequear. Un parámetro opcional del disparador es en qué condiciones disparar el build. El valor default de ese parámetro es "IfModificationExists". Lo que buscás te debería funcionar si usás el valor "ForceBuild". En otras palabras, probá cambiar el trigger a

  <triggers>
    <intervalTrigger seconds="600" buildCondition="ForceBuild"/>
  </triggers>

En http://www.cruisecontrolnet.org/projects/ccnet/wiki/Interval_Trigger tenés la info completa del intervalTrigger, y por si acaso, en http://www.cruisecontrolnet.org/projects/ccnet/wiki/Trigger_Blocks tenés disparadores alternativos.

Espero que te sirva.

Unknown dijo...

Fabián puedes decirme como arrelaste el problema de caracteres invalidos. saludos

Gustavo Vitale dijo...

José muy bueno el blog. Estoy intentando automatizar algunas cosas con el msbuild y tengo un problema. Cuando ejecuto un updatefromserver, se genera un archivo temporal que corresponde a un xpz con los objetos a actualizar. Necesito tomar ese xpz para importarlo en otra KB pero cuando termina el update, borra dicho archivo. ¿Hay alguna forma de evitar que se borre?. Si realizo el update desde genexus, el archivo no se borra. Desde ya muchas gracias.

Gustavo Vitale dijo...

Por si alguien visita el blog, si copian el contenido de ccnet.config directamente de la página web, eliminen los espacios de las lineas como:


$(CruiseControlServerDir)\Rodemeyer.MsBuildToCCNet.dll


Debe quedar:

$(CruiseControlServerDir)\Rodemeyer.MsBuildToCCNet.dll

De otro forma da errores.
Esto sucede con otras lineas similares.

Espero que les evite dolores de cabeza tratando de encontrar el problema.

Gustavo Vitale dijo...

Perdón, la página me eliminó los tags...

::NOMBRE_TAG::
$(CruiseControlServerDir)\Rodemeyer.MsBuildToCCNet.dll
::NOMBRE_TAG_FIN::

Debe quedar:

::NOMBRE_TAG::$(CruiseControlServerDir)\Rodemeyer.MsBuildToCCNet.dll::NOMBRE_TAG_FIN::

Sin espacios ni saltos de línea.