Versiones automáticas en Visual Studio 2017 (.NET Core)

He pasado la mayor parte de unas pocas horas tratando de encontrar una forma de autoincrementar las versiones en .NETCoreApp 1.1 (Visual Studio 2017).

Sé que el AssemblyInfo.cs se está creando dinámicamente en la carpeta: obj/Debug/netcoreapp1.1/

No acepta el método anterior de: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

Si configuro el proyecto en paquete, puedo establecer versiones allí, pero parece que esto se usa para comstackr el archivo AssemblyInfo.cs.

Mi pregunta es, ¿alguien ha descubierto cómo controlar la versión en .NET Core (o .NETStandard para el caso) proyectos.

He estado buscando un incremento de versión para una aplicación Net Core en VS2017 usando el formato de configuración csproj.

Encontré un proyecto llamado dotnet bump que funcionaba para el formato project.json pero me costó encontrar una solución para el formato .csproj. El escritor el dotnet bump en realidad se le ocurrió la solución para el formato .csproj y se llama MSBump.

Hay un proyecto en GitHub para él en:

https://github.com/BalassaMarton/MSBump

donde puedes ver el código y está disponible en Nuget también. Solo busca MSBump en Nuget.

Si está utilizando Visual Studio Team Services / TFS o algún otro proceso de comstackción CI para tener versiones incorporadas, puede utilizar el atributo de Condition de msbuild, por ejemplo:

   0.0.1-local $(BUILD_BUILDNUMBER) netcoreapp1.1           

Esto le indicará al comstackdor de .NET Core que use lo que esté en la variable de entorno BUILD_BUILDNUMBER si está presente, o recurrirá a 0.0.1-local si está haciendo una comstackción en su máquina local.

Añadir False a .csproj

La solución para hacer que AssemblyVersion * funcione se describe en “Confundir mensaje de error para comodín en [AssemblyVersion] en .Net Core # 22660”

Los comodines solo se permiten si la comstackción no es determinista, que es la predeterminada para los proyectos de .Net Core. Agregar False a csproj corrige el problema.

Las razones por las que los desarrolladores de .Net Core consideran beneficios determinísticos las descritas en http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html y los comstackdores deben ser determinísticos: las mismas entradas generan los mismos resultados # 372

Sin embargo, si usa TeamCity, TFS u otra herramienta de CI / CD, probablemente sea mejor mantener el número de versión controlado e incrementado por ellos y pasarlo a comstackr como parámetro (como se sugirió en otras respuestas), por ejemplo

 msbuild /t:build /p:Version=YourVersionNumber /p:AssemblyVersion=YourVersionNumber 

Número de paquete para paquetes NuGet

 msbuild /t:pack /p:Version=YourVersionNumber 

Se me ocurrió una solución que funcionaba casi igual que el antiguo atributo AssemblyVersion con star (*) – AssemblyVersion (“1.0. “) *

Los valores para AssemblyVersion y AssemblyFileVersion se encuentran en el archivo .csproj del proyecto MSBuild (no en AssemblyInfo.cs ) como propiedad FileVersion (genera AssemblyFileVersionAttribute ) y AssemblyVersion (genera AssemblyVersionAttribute ). En el proceso de MSBuild usamos nuestra tarea personalizada de MSBuild para generar números de versión y luego anulamos los valores de estas propiedades FileVersion y AssemblyVersion con nuevos valores de la tarea.

Así que primero creamos nuestra tarea personalizada de MSBuild GetCurrentBuildVersion :

 public class GetCurrentBuildVersion : Task {    [Output]    public string Version { get; set; }    public string BaseVersion { get; set; }    public override bool Execute()    {        var originalVersion = System.Version.Parse(this.BaseVersion ?? "1.0.0");        this.Version = GetCurrentBuildVersionString(originalVersion);        return true;    }    private static string GetCurrentBuildVersionString(Version baseVersion)    {        DateTime d = DateTime.Now;        return new Version(baseVersion.Major, baseVersion.Minor,            (DateTime.Today - new DateTime(2000, 1, 1)).Days,            ((int)new TimeSpan(d.Hour, d.Minute, d.Second).TotalSeconds) / 2).ToString();    } } 

La clase de tarea hereda de la clase Microsoft.Build.Utilities.Task del paquete Microsoft.Build.Utilities.Core NuGet. Toma la propiedad BaseVersion (opcional) en la entrada y devuelve la versión generada en la propiedad de salida de la Versión. La lógica para obtener los números de versión es la misma que la versión automática de .NET (el número de comstackción es el recuento de días desde el 1/1/2000 y la revisión es de medio segundo desde la medianoche).

Para construir esta tarea MSBuild, usamos el tipo de proyecto de biblioteca de clase .NET Standard 1.3 con esta clase.

El archivo .csproj puede verse así:

       netstandard1.3    DC.Build.Tasks    DC.Build.Tasks    DC.Build.Tasks    DC.Build.Tasks                

Este proyecto de tarea también está disponible en mi GitHub holajan / DC.Build.Tasks

Ahora configuramos MSBuild para usar esta tarea y establecer las propiedades FileVersion y AssemblyVersion . En el archivo .csproj se ve así:

         ...    1.0.0.0    1.0.0.0    ...                          $(FileVersion)        

Importantes cosas aquí:

  • Mencionó UsingTask importa la tarea GetCurrentBuildVersion de DC.Build.Tasks.dll . Supone que este archivo dll se encuentra en el directorio principal de su archivo .csproj.
  • Nuestro objective BeforeBuildActionsProject1 que llama a la tarea debe tener un nombre único por proyecto en caso de que tengamos más proyectos en la solución que llama a la tarea GetCurrentBuildVersion.

La ventaja de esta solución es que funciona no solo a partir de comstackciones en el servidor de comstackción, sino también en comstackciones manuales a partir de la creación de dotnet o Visual Studio.

Estos valores ahora se establecen en el archivo .csproj :

  netcoreapp1.1 1.0.6.0 1.0.6.0 1.0.1  

Estos son los mismos valores que ve si va en la pestaña Paquete en la configuración del proyecto. Si bien no creo que pueda usar * para autoincrementar la versión, lo que puede hacer es introducir un paso posterior al procesamiento que reemplace las versiones (por ejemplo, como parte de su integración continua).

dotnet build /p:AssemblyVersion=1.2.3.4

A lo que respondí: “¿Alguien ha descubierto cómo controlar la versión en proyectos .NET Core (o .NETStandard para ese asunto)”. Encontré esta pregunta tratando de resolver este problema en el contexto de una comstackción de CI. Quería establecer la versión de ensamblaje al número de comstackción CI.

Hice una herramienta CLI simple para establecer cadenas de versiones .csproj .NET Core aquí . Puede combinarlo con herramientas como GitVersion para obtener versiones automáticas durante las comstackciones de CI, si eso es lo que está buscando.

Acepté la respuesta anterior porque @Gigi es correcta (a partir de ahora) pero me molestó y se me ocurrieron los siguientes scripts de PowerShell.

Primero tengo el script en mi carpeta de solución (UpdateBuildVersion.ps1):

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Revision $avBuild = [Convert]::ToInt32($avBuild,10)+1 $fvBuild = [Convert]::ToInt32($fvBuild,10)+1 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

Agregué esto al archivo csproj:

   0.0.1 0.0.1 powershell.exe –NonInteractive –ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"   

Incluso a través de su conjunto para ser un PreBuildEvent, el hecho es que los números de la versión no se actualizan hasta DESPUÉS de que el archivo se haya cargado en la memoria para que el número de versión no se refleje hasta la próxima comstackción. De hecho, podrías cambiarlo a un PostBuildEvent y tendría el mismo efecto.

También creé los siguientes dos scripts: (UpdateMinorVersion.ps1)

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Minor Version - Will reset all sub nodes $avMinor = [Convert]::ToInt32($avMinor,10)+1 $fvMinor = [Convert]::ToInt32($fvMinor,10)+1 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

(UpdateMajorVersion.ps1)

 #Get Path to csproj $path = "$PSScriptRoot\src\ProjectFolder\ProjectName.csproj" #Read csproj (XML) $xml = [xml](Get-Content $path) #Retrieve Version Nodes $assemblyVersion = $xml.Project.PropertyGroup.AssemblyVersion $fileVersion = $xml.Project.PropertyGroup.FileVersion #Split the Version Numbers $avMajor, $avMinor, $avBuild = $assemblyVersion.Split(".") $fvMajor, $fvMinor, $fvBuild = $fileVersion.Split(".") #Increment Major Version - Will reset all sub nodes $avMajor = [Convert]::ToInt32($avMajor,10)+1 $fvMajor = [Convert]::ToInt32($fvMajor,10)+1 $avMinor = 0 $fvMinor = 0 $avBuild = 0 $fvBuild = 0 #Put new version back into csproj (XML) $xml.Project.PropertyGroup.AssemblyVersion = "$avMajor.$avMinor.$avBuild" $xml.Project.PropertyGroup.FileVersion = "$fvMajor.$fvMinor.$fvBuild" #Save csproj (XML) $xml.Save($path) 

Para habilitar el control de versiones de .Net Core / .Net Cualquier proyecto basado en su configuración de GIT, usando las tags / describir la funcionalidad de GIT.

He estado usando un archivo Prebuild.targets.xml que se encuentra en la carpeta raíz del proyecto y se incluye en el archivo csproj como:

   ...  false 

Use la etiqueta “GenerateAssembyInfo” para deshabilitar la generación automática de información de ensamblaje.

Luego, Prebuild.targets.xml generará un archivo CommonAssemblyInfo.cs donde podrá incluir las tags de versión que desee según su versión de GIT

NOTA: Encontré el Prebuilds.targets.xml en otro lugar, así que no me molesté en limpiarlo.)

El archivo Prebuild.targets.xml:

                 \d+)\.(?\d+)(\.?(?\d+))?-(?\d+)-(?[a-z0-9-]+)$"); int major, minor, patch, revision; Int32.TryParse(match.Groups["major"].Value, out major); Int32.TryParse(match.Groups["minor"].Value, out minor); Int32.TryParse(match.Groups["patch"].Value, out patch); Int32.TryParse(match.Groups["revision"].Value, out revision); _Version = new Version(major, minor, patch, revision).ToString(); _Commit = match.Groups["commit"].Value; ]]>                                      0.0.0.0      

EDITAR: Si está construyendo usando MSBUILD,

  $(SolutionDir) 

Podría causarte problemas, usa

  $(ProjectDir) 

en lugar

La extensión Versiones automáticas para Visual Studio ahora admite .Net Core y .NET Standard autoincrementing en una interfaz de usuario simple.

https://marketplace.visualstudio.com/items?itemName=PrecisionInfinity.AutomaticVersions

Puede usar una función de propiedad MSBuild para establecer el sufijo de versión según la fecha actual:

  pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))  

Esto generará un paquete con un nombre como: PackageName.1.0.0-pre20180807-1711.nupkg .

Más detalles sobre las funciones de propiedad de MSBuild: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions

Creo que esta respuesta de @ joelsand es la respuesta correcta para configurar el número de versión para ejecutar dotnet core en VSTS

Para agregar más información para esta respuesta,

BUILD_BUILDNUMBER es en realidad una variable predefinida .

Resulta que hay 2 versiones de variable predefinida.

Uno es build.xxxx, el otro es BUILD_XXXX.

Solo puede usar el Environment Variable Name en cproj.