Hacer una Build en TFS 2010 para SharePoint Server 2010

Habrá casos en que dispongamos de un TFS 2010 como repositorio del código que estamos desarrollando. En estos casos, podemos sacarle partido a las Build automáticas, para preparar paquetes que estén listos para desplegar en cualquier momento.
De forma estandar, TFS nos va a dejar compilar la solución o los proyectos que la forman, incluso generando la salida de los paquetes WSP, pero cuando tengamos por ejemplo ficheros de script, ya sean Bat o PowerShell, tendremos que modificar el workflow de la plantilla de la Build, con el fin de poder volcar en una carpeta únicamente los ficheros necesarios para el despliegue de la solución, que en caso de ejemplo serán los paquetes WSP junto con sus script de PowerShell.
La idea es la siguiente: Teniendo una solución con n proyectos de SharePoint 2010, vamos a modificar la plantilla genérica de Build para añadir un proceso que se encargue de crear una carpeta llamada Deploy en la que vamos a dejar únicamente los paquetes WSP y los scripts de PowerShell. Veamos cómo sería el proceso:
Lo primero sería tener una estructura de proyecto en la que tengamos localizados nuestros scripts. Para el ejemplo usaremos la siguiente:
image_thumb1
Ahora vamos a hacer una copia de la plantilla por defecto, que es DefaultTemplate, para ello, localizamos la carpeta donde están las plantillas y hacemos una copia de ella:
image_thumb72
La renombramos para tenerla bien localizada, por ejemplo SPTemplate, y la añadimos al control de código, y posteriormente protegemos todos los cambios (check in):
image_thumb73
Ahora creamos una nueva definición de build, que use nuestra plantilla, desde la ventana del Team Explorer:
image_thumb14
En la pestaña de Process, en el apartado de Build process template vamos a añadir la plantilla que acabamos de copiar. Para ello, hacemos clic en el botón “New” y seleccionamos la plantilla existente:
image_thumb5
A continuación seleccionamos la solución que vamos a compilar en el proceso de build:
image_thumb74
En el apartado de Advanced es muy importante indicar como argumento del MSBuild Arguments la generación de paquete a true. De esta forma en la salida se generarán los WSP pertinentes:
image_thumb75
Hasta aquí la generación de la build, sin la modificación del Workflow. Podemos generar una para ver cómo queda la salida:
image_thumb76
El paquete WSP se ha generado, pero de los scripts ni rastro. Sin modificar aún el Workflow, existe la posibilidad de indicar que queremos que un script aparezca en la salida de la build, desde las propiedades del elemento:
image_thumb15
A mi esta solución no me gusta, porque en la salida va a generar la misma estructura que la que hay en el proyecto, y cuando se trata de proyectos complejos con muchos elementos y una estructura de árbol más compleja, la salida de la build no es muy limpia. Lo ideal es tener una carpeta adicional en la salida, que llamaremos Deploy, y en ella forzaremos al proceso de build a que deje en ella tanto los paquetes como los scripts.
Para ello, vamos a modificar la plantilla que anteriormente copiamos, la SPTemplate. Desde la ventana de Souce Control Explorer abrimos la plantilla haciendo doble clic sobre ella. Se abrirá el Workflow, que es bastante grande, así que lo siguiente será contraer todos los procesos para que quede de la siguiente manera:
image_thumb17
A continuación vamos a entrar en el proceso de “Run On Agent”, que es donde vamos a crear nuestra “ampliación“ del workflow, al final del todo:
image_thumb19
Para ello, desde la Toolbox, vamos a añadir un control de Secuencia, justo al final y lo llamaremos Deploy Package:
image_thumb21
Ahora entramos en el proceso que hemos creado. El proceso lo vamos a dividir en tres partes, una parte en la que vamos a crear la carpeta en donde vamos a dejar los ficheros necesarios para un despliegue (WSP y PowerShell), otra parte en la que vamos a copiar a esa carpeta los ficheros WSP que se generan en la salida, y otra parte en la que vamos a copiar en esa carpeta los scripts de PowerShell. Crearíamos por lo tanto otras tres secuencias dentro de nuestro nuevo proceso:
image_thumb23
Vamos a empezar por el primero, el Create Folder, así que hacemos doble clic sobre él, y a continuación vamos a crear una Variable que va a servir para almacenar la ruta a la carpeta que vamos a crear después:
image_thumb25
image_thumb77
En la expresión introducimos lo siguiente:

String.Format("{0}\{1}", BuildDetail.DropLocation, "Deploy")


image_thumb78

Y en el ámbito (Scope) de la variable, indicamos “Run On Agent”, para poder usarla posteriormente en otra secuencia:

image_thumb79

Ahora metemos un proceso de creación de directorio:

image_thumb80

Y en sus propiedades indicamos que el directorio a crear es nuestra variable:

image_thumb81

Siempre podréis ir haciendo check in a los cambios para ir validando que el funcionamiento es el esperado.

Ahora vamos con el siguiente proceso, el que copia los paquetes WSP. Para ello, lo que haremos será hacer una búsqueda de los WSP que la build a generado, y copiarlos a nuestra carpeta de Deploy. Lo primero será crear una variable para almacenar los WSP que el proceso de búsqueda encuentre:

image_thumb82

Y ahora vamos a crear un proceso para buscar esos ficheros, usando el control de FindMatchingFiles:

image_thumb39

image_thumb83


En la propiedad Result indicamos la variable que acabamos de crear, y en la propiedad MatchPattern, introducimos lo siguiente:



String.Format("{0}\*.wsp", BuildDetail.DropLocation)


Eso hará que el proceso busque todos los ficheros WSP que hay en la salida de la build. Ahora con un control foreach, vamos a copiar cada paquete que ha encontrado (en este caso sólo habrá uno) a la carpeta de Deploy, que tenemos guardada en otra variable ya creada:

image_thumb45

Y las propiedades de este foreach serían las siguientes:

image_thumb47

Si ahora entramos en el proceso foreach, haciendo doble clic sobre él, veremos que tenemos una parte “body” vacía. Ahí vamos a meter un control de InvokeProcess, en donde vamos a invocar al programa xcopy para que realice la copia del fichero, que lo recogemos en la variable “item”:

image_thumb50

image_thumb52

Quedaría así:

image_thumb55

Y en las propiedades del proceso, en Arguments introducimos lo siguiente:



String.Format("""{0}"" ""{1}""", item, FolderPath)







y en FileName: “xcopy.exe”. El resto lo dejamos como está:

image_thumb57

Recordad que en este punto podéis probar la build haciendo check in de la plantilla, para ver si el paquete ha sido copiado a la carpeta deseada.

Por último, vamos a copiar los scripts de PowerShell.El proceso es similar al anterior, con la diferencia de que aquí vamos a indicar la ruta donde se encuentran los scripts. Para ello, ahora vamos a entrar en el proceso de Copia de ficheros de script, y como en el caso anterior, primero vamos a crear una variable donde se guarden los ficheros que vamos a copiar:

image_thumb84

Lo siguiente es insertar un control de FindMatchingFiles, para buscar los scripts en la ubicación que indiquemos, y en las propiedades MatchPattern indicar la ruta de los scripts de la siguiente forma:





String.Format
("{0}\Main\src\SPBuildTest\SPProjectOne\Deploy\Scripts\*.ps1",
 SourcesDirectory)


y en Result indicamos la variable PSFiles que acabamos de crear:

image_thumb85

Igual que con los paquetes WSP, ahora habrá que crear un proceso foreach para copiar cada script que ha encontrado:

image_thumb86

Y dentro del body del foreach, el InvokeProcess que se encargará de realizar la copia. En este caso, el proceso de copia es exactamente igual que el anterior:

image_thumb87

Hacemos Check in a los cambios, y generamos una nueva build para comprobar el resultado obtenido:

image_thumb88

Podemos ver que se ha generado tal y como deseábamos, un paquete de solución de SharePoint y los scripts necesarios para su despliegue.

Este caso es el más simple, pero la idea se puede aplicar a proyectos que generan más paquetes en su salida o que tienen más scripts, distinguiendo entre scripts de producción y desarrollo por ejemplo.

0 comentarios:

Publicar un comentario

SharePoint Between Racks © 2012
. Con la tecnología de Blogger.

¡Compártelo!


Estoy en LinkedIn!


Ve mi perfil en LinkedIn!