martes, 3 de marzo de 2015

Creación de paquetes Nuget con .nuspec

Además de ser consumidor de paquetes Nuget (como cualquier otro desarrollador .NET), ahora estoy inmerso en el rol de creador.

image

Por ahora tengo 4 paquetes, pero veo que esto crecerá con el tiempo, me está gustando!

Mi primera incursión fue de la mano de Nuget Package Explorer, una herramienta GUI que permite de forma visual crear y publicar un paquete. A este respecto ya escribió un post mi compañero MookieFumi, Crear un paquete Nuget.

Sin embargo, a medida que el ritmo de publicación ha ido creciendo, el crear los paquetes de forma manual ha resultado una operativa poco eficiente. Como en todo, automatizar es un proceso que facilita nuestro trabajo.

Siguiendo la guía oficial de creación y publicación de paquetes, el proceso por el que he optado consta de los siguientes pasos:

Descargar Nuget.exe o utilizar la versión que encontramos en la carpeta .nuget cuando habilitamos la restauración de paquetes en Visual Studio.

Crear un fichero .nuspec con la información del paquete. Lo más sencillo es ejecutar
Nuget.exe spec en la misma carpeta donde se encuentre el proyecto (el fichero .csproj) a partir del cual queremos crear el paquete.

Al ejecutar el anterior comando se generará un fichero <Proyecto>.nuspec con el contenido:

<?xml version="1.0"?>

<package >

  <metadata>

    <id>$id$</id>

    <version>$version$</version>

    <title>$title$</title>

    <authors>$author$</authors>

    <owners>$author$</owners>

    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>

    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>

    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>

    <requireLicenseAcceptance>false</requireLicenseAcceptance>

    <description>$description$</description>

    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>

    <copyright>Copyright 2015</copyright>

    <tags>Tag1 Tag2</tags>

  </metadata>

</package>

Lo más importante son las variables:

  • $id$. Nombre del ensamblado
  • $version$. Versión según AssemblyVersionAttribute
  • $title$. Título según AssemblyTitle
  • $author$. Autor según AssemblyCompanyAttribute
  • $description$. Descripción según AssemblyDescriptionAttribute

El valor de todas ellas se pueden establecer desde las propiedades del proyecto (Properties > Application > Assembly Information).

En relación al resto, personalmente prescindo de licenseUrl, iconUrl y releaseNotes, y actualizo el valor de projectUrl (con la url del repositorio de github) y tags (para su posterior búsqueda desde el registro de Nuget).

Después de editarlo, deberemos incluir el fichero .nuspec a nuestro VCS favorito.

A partir de aquí (y teniendo la precaución de ir incrementado la versión del ensamblado cada vez que queramos publicar una nueva versión del paquete), podemos utilizar el siguiente comando para generar el fichero .nupkg

Nuget.exe pack <Proyecto>.csproj -Prop Configuration=Release -Build -OutputDirectory .\bin\Release

  • -Prop Configuration=Relase indica que queremos empaquetar en esa configuración (por defecto lo hace en Debug, aunque editando el fichero .csproj se podría cambiar… todo esto está explicado en la guía).
  • -Build indica que queremos compilar antes de empaquetar
  • -OutputDirectory indica donde se creará el fichero .nupkg

El fichero .nupkg tendrá el nombre $id$<version>.nupkg

Aunque ahora podríamos también publicar a través de línea de comandos con Nuget.exe, aquí yo prefiero publicar manualmente con Nuget Package Explorer.

Lógicamente, el fichero .nupkg no se sube al VCS de turno, cualquier .gitignore que se precie lo tendrá excluido.

Si extraemos con Nuget Package Explorer los metadatos del paquete que acabamos de crear veremos algo así:

<?xml version="1.0" encoding="utf-8"?>

<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">

    <metadata>

        <id>MongoDBTempData</id>

        <version>1.0.0.0</version>

        <title>MongoDBTempData</title>

        <authors>panicoenlaxbox</authors>

        <owners>panicoenlaxbox</owners>

        <projectUrl>https://github.com/panicoenlaxbox/MongoDBTempData</projectUrl>

        <requireLicenseAcceptance>false</requireLicenseAcceptance>

        <description>ASP.NET MVC TempData MongoDB provider</description>

        <copyright>Copyright 2015</copyright>

        <tags>ASP.NET MVC TempData MongoDB</tags>

        <dependencies>

            <dependency id="Microsoft.AspNet.Mvc" version="5.2.3" />

            <dependency id="mongocsharpdriver" version="1.10.0" />

            <dependency id="Newtonsoft.Json" version="6.0.8" />

        </dependencies>

    </metadata>

    <files>

        <file src="lib\net45\MongoDBTempData.dll" target="lib\net45\MongoDBTempData.dll" />

    </files>

</package>

Como podemos ver, las variables han sido reemplazadas y además se han incluido como dependencias las propias dependencias Nuget que tuviera el proyecto (esto podría gustarte o no, eso lo dejo a tu elección).

Dando un pasito más allá (y ahora sí entrando en los dominios de la automatización), para la creación automática del paquete he utilizado un evento post-compilación. Cierto es que podría haber optado por un fichero MSBUILD, pero no me importa que cada vez que compilo en Release se genere un nuevo paquete, sobre todo porque la publicación (como he dicho antes) la haré de forma manual.

El código MSBUILD a incluir en el evento post-build es:

if $(ConfigurationName) == Release $(SolutionDir)\.nuget\NuGet.exe pack "$(ProjectPath)" -Prop Configuration=Release

De este modo, mi flujo de creación y publicación de paquetes Nuget queda así:

  • Crear fichero .nuspec con Nuget.exe, editarlo y subirlo al VCS.
  • Agregar código MSBUILD en el evento post-build para que se genere automáticamente el fichero .nupkg si compilo en Release.
  • Publicar manualmente el paquete cuando proceda.

Un saludo!

1 comentario:

  1. buen día, de antemano agradezco por este blog tan bueno, pero recomiendo la suscripción por correo electrónico con la herramienta: FeedBurner

    ResponderEliminar