Search
  • en
  • es
  • es
    Search
    Open menu Open menu

    Configurar Source Link en proyectos .NET y cómo utilizarlo en Visual Studio

    Como miembro encargado de mantener algunos proyectos de código abierto en Xabaril y que mucha gente utiliza, creo que es crucial ayudar a los desarrolladores a que puedan depurar el código fuente de nuestras librerías con el fin de facilitarles la vida a la hora de solucionar problemas y poder entender mejor su funcionamiento. Por este motivo, en Xabaril hemos decidido habilitar el soporte Source Link en nuestros proyectos.

    Antes de continuar, quiero agradecer a Unai Zorrilla por mostrarme las bondades de Source Link y ayudarme a configurarlo en Balea.

    Entorno de los ejemplos
    Esta guía utiliza .NET Core 3.1 y Visual Studio 2019.

    Source Link es una tecnología que permite a los desarrolladores depurar el código fuente de los paquetes NuGet. Herramientas como Visual Studio pueden aprovechar esta característica para depurar su código fuente como si se tratase de un proyecto local más y facilitar la solución de problemas al utilizar proyectos de código abierto.

    Centralizar las dependencias

    El archivo dependencies.props permite definir las versiones de los paquetes NuGet en un solo lugar. Así evitamos problemas de consolidación de versiones entre los proyectos de una solución, mientras cada proyecto declara las dependencias que necesita.

    dependencies.props
    <PropertyGroup Label="Package Dependencies">
    <AspNetCoreVersion>3.1.3</AspNetCoreVersion>
    <EntityFrameworkVersion>3.1.3</EntityFrameworkVersion>
    </PropertyGroup>

    En tu csproj tienes que definir qué dependencias vas a usar:

    Proyecto .csproj
    <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="$(AspNetCoreVersion)" />
      </ItemGroup>

    De este modo, si el equipo de ASP.NET Core lanza una nueva versión, ya no es necesario pasar por todos los proyectos uno por uno actualizándola. Solo tendrás que actualizar la versión en dependencies.props y los proyectos que la referencien utilizarán esa versión.

    Compartir los metadatos de la solución

    Otro archivo con el que deberías estar familiarizado es Directory.Build.props, que facilita compartir metadatos comunes en toda la solución.

    Directory.Build.props
    <Project>
      <Import Project="build/dependencies.props" />
      <PropertyGroup Label="Package information">
        <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
        <PackageProjectUrl>http://github.com/xabaril/Balea</PackageProjectUrl>
        <RepositoryUrl>https://github.com/xabaril/Balea</RepositoryUrl>
        <Authors>Xabaril Contributors</Authors>
        <Company>Xabaril</Company>
      </PropertyGroup>
    </Project>

    En la primera línea importamos el archivo dependencies.props y añadimos metadatos comunes para todos los proyectos, como la información de la licencia o la URL del proyecto.

    Habilitar Source Link

    Para habilitar Source Link en el proyecto, añade estas líneas a tu Directory.Build.props:

    Directory.Build.props
    <!-- Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) -->
    <PublishRepositoryUrl>true</PublishRepositoryUrl>
    
    <!-- Embed source files that are not tracked by the source control manager in the PDB -->
    <EmbedUntrackedSources>true</EmbedUntrackedSources>
    
    <!-- Build symbol package (.snupkg) to distribute the PDB containing Source Link -->
    <IncludeSymbols>true</IncludeSymbols>
    <SymbolPackageFormat>snupkg</SymbolPackageFormat>

    Para los proyectos alojados en GitHub necesitarás referenciar el paquete de Source Link:

    Directory.Build.props
    <ItemGroup>
      <SourceRoot Include="$(MSBuildThisFileDirectory)/"/>
      <PackageReference Include="Microsoft.SourceLink.GitHub" Version="$(MicrosoftSourceLinkGithub)">
        <PrivateAssets>all</PrivateAssets>
        <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
      </PackageReference>
    </ItemGroup>

    Activar las compilaciones deterministas

    A continuación, tendrás que habilitar las compilaciones deterministas (deterministic builds). En este repositorio, Claire Novotny explica cómo funcionan y por qué son importantes.

    Las compilaciones deterministas permiten verificar que el binario resultante se construyó a partir del código fuente especificado y aportan trazabilidad.

    Añade lo siguiente a Directory.Build.props si estás usando GitHub Actions:

    Directory.Build.props
    <PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
        <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
    </PropertyGroup>

    Aplicar el ajuste para SDK anteriores a 3.1.300

    Existe un problema conocido con el atributo EmbedUntrackedSources en SDK anteriores a 3.1.300. El artículo original se escribió utilizando el SDK 3.1.201.

    Para ese entorno, añade un archivo Directory.Build.targets en el nivel de la solución con este contenido:

    Directory.Build.targets
    <Project>
    <PropertyGroup>
        <TargetFrameworkMonikerAssemblyAttributesPath>$([System.IO.Path]::Combine('$(IntermediateOutputPath)','$(TargetFrameworkMoniker).AssemblyAttributes$(DefaultLanguageSourceExtension)'))</TargetFrameworkMonikerAssemblyAttributesPath>
      </PropertyGroup>
      <ItemGroup>
        <!-- https://github.com/dotnet/sourcelink/issues/572 -->
        <EmbeddedFiles Include="$(GeneratedAssemblyInfoFile)"/>
      </ItemGroup>
    </Project>

    Comprobar el paquete NuGet

    Probar el paquete en local

    Si quieres probar tus paquetes en una máquina local antes de publicarlos en el feed de NuGet, elimina temporalmente la condición de MSBuild para GitHub Actions:

    Directory.Build.props — prueba local
    <PropertyGroup>
        <ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
    </PropertyGroup>

    Ejecuta el siguiente comando para empaquetar tu proyecto:

    Terminal
    dotnet pack <yoor_project>.csproj -c Release -o .\artifacts --include-symbols
    Paquete NuGet generado después de ejecutar dotnet pack.
    Paquete NuGet generado después de ejecutar dotnet pack.

    Abre NuGet Package Explorer y selecciona Open a local package.

    Abrir un paquete local en NuGet Package Explorer.
    Abrir un paquete local en NuGet Package Explorer.

    Localiza el paquete NuGet que acabas de generar.

    Selección del paquete NuGet generado en local.
    Selección del paquete NuGet generado en local.

    Deberías ver Source Link y la compilación determinista ya verificados.

    Verificación de Source Link y de la compilación determinista.
    Verificación de Source Link y de la compilación determinista.

    Validar el paquete publicado

    Antes de subir los cambios al repositorio, vuelve a añadir la condición para GitHub Actions que eliminaste durante la prueba local. Necesitarás una GitHub Action para publicar tus paquetes en el feed de NuGet.

    Una vez publicado el paquete, abre de nuevo NuGet Package Explorer y selecciona Open a package from online feed.

    Abrir un paquete desde un feed de NuGet.
    Abrir un paquete desde un feed de NuGet.

    Busca tu paquete de NuGet.

    Búsqueda del paquete publicado en NuGet.
    Búsqueda del paquete publicado en NuGet.

    Si has seguido los pasos correctamente, el paquete debería ser válido y reflejar el último cambio de tu repositorio.

    Comprobación del paquete publicado y de su código fuente asociado.
    Comprobación del paquete publicado y de su código fuente asociado.

    Configurar Visual Studio 2019 para Source Link

    Activar el servidor de símbolos de NuGet

    Por defecto, el servidor de símbolos de NuGet está desactivado. Visual Studio 2019 necesita descargar esos símbolos para trabajar con Source Link. Para activarlo, ve a Tools → Options → Debugging → Symbols.

    Activación del servidor de símbolos de NuGet en Visual Studio 2019.
    Activación del servidor de símbolos de NuGet en Visual Studio 2019.

    Desactivar Just My Code

    Ve a Tools → Options → Debugging → General y desmarca Enable Just My Code.

    Configuración de Enable Just My Code en las opciones de depuración.
    Configuración de Enable Just My Code en las opciones de depuración.

    Revisar las opciones de Source Link

    Source Link está habilitado por defecto en Visual Studio 2019, pero el soporte para Source Server no lo está.

    Opciones de Source Link y Source Server en Visual Studio 2019.
    Opciones de Source Link y Source Server en Visual Studio 2019.

    La opción Fallback to Git Credential Manager permite a las herramientas que utilizan Git Credential Manager usar Source Link con repositorios privados.

    Depurar el código de una librería

    En este ejemplo he creado una aplicación Web API sencilla y he añadido los paquetes de Balea.

    Aplicación Web API de ejemplo con los paquetes de Balea.
    Aplicación Web API de ejemplo con los paquetes de Balea.

    Ejecuta la aplicación web y pulsa F11 para entrar en el código de la librería.

    Entrada en el código de la librería durante la depuración.
    Entrada en el código de la librería durante la depuración.

    La primera vez aparecerá una ventana que informa de que Source Link va a descargar el código de Internet, si no lo ha descargado previamente.

    Confirmación de la descarga del código fuente mediante Source Link.
    Confirmación de la descarga del código fuente mediante Source Link.

    Una vez descargado el código fuente, ya podemos depurarlo desde Visual Studio.

    Depuración del código fuente de la librería descargado por Source Link.
    Depuración del código fuente de la librería descargado por Source Link.

    En esta guía hemos visto cómo configurar Source Link en proyectos .NET y aprovechar esta característica desde Visual Studio. Para consultar un ejemplo completo, puedes revisar el repositorio de Balea.

    Artículo original de referencia: Using Source Link in .NET projects and how to configure Visual Studio to use it.

    Elena Canorea

    Communications Lead