Control de versiones automático en Visual Studio 2017 (.NET Core)

112

He pasado la mayor parte de algunas horas tratando de encontrar una manera de incrementar automáticamente las versiones en un .NETCoreApp 1.1 (Visual Studio 2017).

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

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

Si configuro el proyecto en un paquete, puedo configurar las versiones allí, pero parece que esto se usa para construir el archivo AssemblyInfo.cs.

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

Jason H
fuente
No sé qué tan lejos llegaste con esto, pero parece que hice casi la misma pregunta de una manera diferente ( stackoverflow.com/a/43280282/685341 ) - Tal vez la respuesta aceptada a esta pregunta te ayude; simplemente puede pasar la /p:bandera a dotnet msbuilden su script de compilación y configurar la versión, la empresa, los derechos de autor ... todas esas cosas buenas.
Jay
2
Gracias por la info. Eso abre opciones adicionales.
Jason H
Anteriormente * era compatible con AssemblyVersion, no con AssemblyFileVersion; consulte ¿Puedo incrementar automáticamente la versión de compilación del archivo al usar Visual Studio?
Michael Freidgeim
4
FWIW, el comodín en la versión de ensamblado no es compatible porque para estos nuevos proyectos, el modo "determinista" del compilador está activo por defecto. Dado que el incremento automático rompería el determinismo (misma entrada> misma salida), no está permitido en ese modo. Puede configurar <Deterministic>False</Deterministic>en el csproj para usarlo. (o use cualquier otra lógica de MSbuild para calcular <VersionPrefix>/ <Version>)
Martin Ullrich

Respuestas:

23

He estado buscando un incrementador 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 funcionó para el formato project.json pero luché por encontrar una solución para el formato .csproj. El escritor de dotnet bump en realidad ideó la solución para el formato .csproj y se llama MSBump.

Hay un proyecto en GitHub para ello en:

https://github.com/BalassaMarton/MSBump

donde puede ver el código y también está disponible en Nuget. Simplemente busque MSBump en Nuget.

ravetroll
fuente
1
Recomiendo usar la última versión 2.1.0 de MSBump, admite mejor el cambio de configuraciones y también establece la versión para la compilación actual, no la siguiente (como la versión anterior).
Márton Balassa
Veo que ahora también es compatible con MSBuild, mientras que antes requería Visual Studio.
ravetroll
2
Sí, y también es compatible con proyectos de orientación múltiple.
Márton Balassa
4
Considere usar GitVersioning. Puede ser adecuado para ejecutarse en su entorno de CI. github.com/AArnott/Nerdbank.GitVersioning
Henrique
1
MSBump incrementa la versión en cada compilación, incluso si no cambió nada, esto causa muchos problemas a largo plazo. Y, a veces, las versiones no están sincronizadas y una versión está detrás de la otra.
Konrad
68

Agregar <Deterministic>False</Deterministic> dentro de una <PropertyGroup>sección de .csproj

La solución para hacer que AssemblyVersion * funcione se describe en "Mensaje de error confuso para el comodín en [AssemblyVersion] en .Net Core # 22660"

Los comodines solo se permiten si la compilación no es determinista, que es el valor predeterminado para los proyectos .Net Core. Agregar  <Deterministic>False</Deterministic> a csproj soluciona el problema.

Las razones por las que los desarrolladores de .Net Core consideran beneficiosas las compilaciones deterministas se describen en http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html y los compiladores deben ser deterministas: las mismas entradas generan las mismas salidas # 372

Sin embargo, si está utilizando TeamCity, TFS u otra herramienta CI / CD, probablemente sea mejor mantener el número de versión controlado e incrementado por ellos y pasar a compilar 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   
Michael Freidgeim
fuente
¡Gracias! ¡Sabía que había una palanca oculta para abrir la sala del tesoro! Estoy migrando un proyecto antiguo al nuevo .NET SDK, y realmente quería hacerlo rápido, sin la molestia de encontrar soluciones automáticas de incremento de versiones. De hecho, cuanto más compatible con las viejas formas, mejor para mi caso.
Ivaylo Slavov
Esta es la mejor respuesta en mi opinión. Permite que las herramientas de construcción funcionen correctamente. Al menos puedo usar un mecanismo externo para introducir el número en la compilación ahora.
Michael Yanni
Amplíe su respuesta un poco más: la adición sugerida debe ir a la sección <PropertyGroup> de .csproj. Y gracias por esta gran respuesta, ¡por supuesto!
GerardV
1
@gerardv, listo, pero puede mejorar las ediciones usted mismo stackoverflow.com/help/editing
Michael Freidgeim
62

Si está utilizando Visual Studio Team Services / TFS o algún otro proceso de compilación de CI para tener control de versiones integrado, puede utilizar el Conditionatributo de msbuild , por ejemplo:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">0.0.1-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(BUILD_BUILDNUMBER)</Version>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
  </ItemGroup>

</Project>

Esto le indicará al compilador de .NET Core que use lo que sea que esté en la BUILD_BUILDNUMBERvariable de entorno si está presente, o un respaldo 0.0.1-localsi está haciendo una compilación en su máquina local.

joelsand
fuente
Bien, me gusta este enfoque porque las variables de entorno se pueden configurar en el servidor de compilación, mientras que estos condicionales eliminan el conjunto de ensamblado en los binarios.
jbooker
No parece funcionar en TFS 2010, ¡pero es de esperar que lo abandonemos pronto!
Mark Adamson
No es una mala solución, aunque podría ser un poco complicado si la solución tiene muchos proyectos.
tofutim
Buena solución. Sin embargo, obtuve una excepción de compilación. Tuve que cambiar la configuración ligeramente para solucionarlo. stackoverflow.com/a/59858009/106227
Stu Harper
Esto funciona muy bien con .NET Core 2.1.2 y TFS2017U3
Dave Johnson
16

Se me ocurrió una solución que funcionó casi igual que el antiguo atributo AssemblyVersion con estrella (*) - AssemblyVersion ("1.0. ") *

Los valores para AssemblyVersion y AssemblyFileVersion están 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 utilizamos 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.

Entonces, 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();
    }
}

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

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

El archivo .csproj puede tener este aspecto:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard1.3</TargetFramework>
    <AssemblyName>DC.Build.Tasks</AssemblyName>
    <RootNamespace>DC.Build.Tasks</RootNamespace>
    <PackageId>DC.Build.Tasks</PackageId>
    <AssemblyTitle>DC.Build.Tasks</AssemblyTitle>
  </PropertyGroup>
 
  <ItemGroup>
    <PackageReference Include="Microsoft.Build.Framework" Version="15.1.1012" />
    <PackageReference Include="Microsoft.Build.Utilities.Core" Version="15.1.1012" />
  </ItemGroup>
</Project>

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

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

<Project Sdk="Microsoft.NET.Sdk">
  <UsingTask TaskName="GetCurrentBuildVersion" AssemblyFile="$(MSBuildThisFileFullPath)\..\..\DC.Build.Tasks.dll" />
 
  <PropertyGroup>
    ...
    <AssemblyVersion>1.0.0.0</AssemblyVersion>
    <FileVersion>1.0.0.0</FileVersion>
  </PropertyGroup>
 
  ...
 
  <Target Name="BeforeBuildActionsProject1" BeforeTargets="BeforeBuild">
    <GetCurrentBuildVersion BaseVersion="$(FileVersion)">
      <Output TaskParameter="Version" PropertyName="FileVersion" />
    </GetCurrentBuildVersion>
    <PropertyGroup>
      <AssemblyVersion>$(FileVersion)</AssemblyVersion>
    </PropertyGroup>
  </Target>
 
</Project>

Cosas importantes aquí:

  • El uso mencionado de UsingTask importa la tarea GetCurrentBuildVersion de DC.Build.Tasks.dll . Se asume que este archivo dll se encuentra en el directorio principal de su archivo .csproj.
  • Nuestro objetivo 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 compilaciones en el servidor de compilación, sino también en compilaciones manuales de dotnet build o Visual Studio.

HolaJan
fuente
4
Recomendaría usar en DateTime.UtcNowlugar de un DateTime.Nowmétodo GetCurrentBuildVersionString()en particular si el código se ejecuta en máquinas de compilación automatizadas. Pueden funcionar a las 2 a. M. O a las 3 a. M. De la mañana cuando su computadora cambia a / desde el horario de verano. En DateTime.Nowese escenario, es posible que esté retrocediendo en términos de versión. Es cierto que este es un caso de esquina y también admito que soy exigente. :-) Además, el problema también desaparece si configura la misma zona horaria en todas las máquinas de compilación y no se ajusta al horario de verano.
Manfred
¿Existe todavía un paquete NuGet para esto?
Jonathan Allen
@Jonathan Allen No, no tengo ningún plan para el paquete nuget, debido al nombre diferente en cada proyecto. Puede descargar la tarea de compilación compilada en github.com/holajan/DC.Build.Tasks/tree/master/dist carpeta
HolaJan
Hemos estado usando una aplicación de consola personalizada para extraer nuestra versión de un servidor y generar el archivo AssemblyInfo.cs antes de las compilaciones. Este enfoque es perfecto para lo que hacemos. ¿Ha podido utilizar este método para enviar la versión en "Versión" de la función de paquete de los nuevos proyectos? Sería bueno, pero supongo que también podemos recurrir a nuget.exe para empaquetar, ya que también lo necesitaremos para publicar.
David Ritchie
15

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

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
  <VersionSuffix>pre$([System.DateTime]::UtcNow.ToString(yyyyMMdd-HHmm))</VersionSuffix>
</PropertyGroup>

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

Se Versionforma a partir de la combinación de VersionPrefixy VersionSuffix, o si VersionSuffixestá en blanco, VersionPrefixúnicamente.

<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
</PropertyGroup>
Fabricio Godoy
fuente
Esto es realmente útil
Jerry Nixon
12

Acepté la respuesta anterior porque @Gigi es correcta (a partir de ahora) pero estaba molesto 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:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <AssemblyVersion>0.0.1</AssemblyVersion>
    <FileVersion>0.0.1</FileVersion>
    <PreBuildEvent>powershell.exe NonInteractive ExecutionPolicy Unrestricted -command "& {$(SolutionDir)UpdateBuildVersion.ps1}"</PreBuildEvent>
  </PropertyGroup>
</Project>

Incluso a pesar de que está configurado para ser un PreBuildEvent, el hecho es que los números de versión no se actualizan hasta DESPUÉS de que el archivo se haya cargado en la memoria, por lo que el número de versión no se reflejará hasta la próxima compilación. De hecho, podría cambiarlo a 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)
Jason H
fuente
10

dotnet build /p:AssemblyVersion=1.2.3.4

Estaba respondiendo a: "¿alguien ha descubierto cómo controlar la versión en proyectos .NET Core (o .NETStandard para el caso)?" Encontré esta pregunta tratando de resolver este problema en el contexto de una compilación de CI. Quería establecer la versión de ensamblaje en el número de compilación de CI.

Chris McKenzie
fuente
1
El título dice "Control de versiones automático en Visual Studio 2017 (.NET Core)". ¿Dónde exactamente la construcción manual cumple con "Visual Studio 2017"?
JCKödel
4
Estaba respondiendo a: "¿alguien ha descubierto cómo controlar la versión en proyectos .NET Core (o .NETStandard para el caso)?" Encontré esta pregunta tratando de resolver este problema en el contexto de una compilación de CI. Quería establecer la versión de ensamblaje en el número de compilación de CI. Lamento si cree que esto no es relevante para la pregunta en cuestión.
Chris McKenzie
Es un componente útil para mí, gracias. Usaré esto como parte de una solución de CI
Mark Adamson
1
@ChrisMcKenzie: su comentario debe incluirse en su respuesta para dejar clara su intención
Michael Freidgeim
** esto no me funciona en proyectos netstandard cuando no se especifica assemblyinfo.cs y la versión está en el csproj ...
tofutim
9

Estos valores ahora se establecen en el .csprojarchivo:

<PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
    <AssemblyVersion>1.0.6.0</AssemblyVersion>
    <FileVersion>1.0.6.0</FileVersion>
    <Version>1.0.1</Version>
</PropertyGroup>

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

Gigi
fuente
6
Temía que esta fuera la respuesta. Veré si puedo hacer un paso previo a la construcción para incrementarlo.
Jason H
3
Como se señaló en otro hilo, el nuevo formato csproj le permite desactivar la generación automática del archivo assemblyinfo y especificar el suyo. Seguí el consejo de la respuesta de natemcmaster aquí y usé un archivo AssemblyInfo.cs estándar: stackoverflow.com/questions/42138418/…
James Eby
5
¿Por qué eliminaron el incremento automático? Me funcionó muy bien y de manera muy sencilla durante años. Presiono master, CI compila e incrementa, luego la versión se lee directamente desde la DLL construida usando algún script PS, luego uso esa versión como un argumento al presionar a NuGet. Tan sencillo. Ahora roto.
Luke Puplett
1
@LukePuplett lo mismo aquí. ¡muy frustrante!
Shimmy Weitzhandler
@LukePuplett: Consulte ["Mensaje de error confuso para comodines en AssemblyVersion en .Net Core # 22660"] ( github.com/dotnet/roslyn/issues/22660 ), Las razones por las que consideran beneficiosas las compilaciones deterministas descritas en blog.paranoidcoding.com / 2016/04/05 /… y los compiladores deben ser deterministas: las mismas entradas generan las mismas salidas # 372 < github.com/dotnet/roslyn/issues/372 >
Michael Freidgeim
5

Hice una herramienta CLI simple para configurar cadenas de versión .csproj .NET Core aquí . Puede combinarlo con herramientas como GitVersion para el cambio automático de versiones durante las compilaciones de CI, si eso es lo que busca.

Tagc
fuente
@JasonH Gracias, avíseme si tiene algún problema con él.
Tagc
maldito genio. ¡quiéralo!
pms1969
4

Para habilitar el control de versiones de su .Net Core / .Net Cualquier proyecto basado en su configuración de GIT, use las etiquetas / describe 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:

<Project Sdk="Microsoft.NET.Sdk">
  <Import Project="PreBuild.targets.xml" />
  ...
  <PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>

Utilice 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 puede incluir las etiquetas de versión que desee según su versión de GIT

NOTA: He encontrado Prebuilds.targets.xml en otro lugar, así que no me he molestado en limpiarlo).

El archivo Prebuild.targets.xml:

    <?xml version="1.0" encoding="utf-8" ?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

      <UsingTask
        TaskName="GetVersion"
        TaskFactory="CodeTaskFactory"
        AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
        <ParameterGroup>
          <VersionString ParameterType="System.String" Required="true" />
          <Version ParameterType="System.String" Output="true" />
          <Commit ParameterType="System.String" Output="true" />
          <VersionSuffix ParameterType="System.String" Output="true" />
        </ParameterGroup>
        <Task>
          <!--<Reference Include="" />-->
          <Using Namespace="System"/>
          <Using Namespace="System.IO"/>
          <Using Namespace="System.Text.RegularExpressions" />
          <Code Type="Fragment" Language="cs">
            <![CDATA[
              var match = Regex.Match(VersionString, @"^(?<major>\d+)\.(?<minor>\d+)(\.?(?<patch>\d+))?-(?<revision>\d+)-(?<commit>[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;
            ]]>
          </Code>
        </Task>
      </UsingTask>

      <UsingTask
        TaskName="GitExistsInPath"
        TaskFactory="CodeTaskFactory"
        AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
        <ParameterGroup>
          <Exists ParameterType="System.Boolean" Output="true" />
        </ParameterGroup>
        <Task>
          <!--<Reference Include="" />-->
          <Using Namespace="System"/>
          <Using Namespace="System.IO"/>
          <Using Namespace="System.Text.RegularExpressions" />
          <Code Type="Fragment" Language="cs">
            <![CDATA[
            var values = Environment.GetEnvironmentVariable("PATH");
            foreach (var path in values.Split(';')) {
                var exeFullPath = Path.Combine(path, "git.exe");
                if (File.Exists(exeFullPath)) {
                    Exists = true;
                    return true;
                }
                var cmdFullPath = Path.Combine(path, "git.cmd");
                if (File.Exists(cmdFullPath)) {
                    Exists = true;
                    return true;
            }
            }
            Exists = false;
            ]]>
          </Code>
        </Task>
      </UsingTask>

      <Target Name="CreateCommonVersionInfo" BeforeTargets="CoreCompile">
        <Message Importance="high" Text="CreateCommonVersionInfo" />

        <GitExistsInPath>
          <Output TaskParameter="Exists" PropertyName="GitExists"/>
        </GitExistsInPath>
        <Message Importance="High" Text="git not found!" Condition="!$(GitExists)"/>

        <Exec Command="git describe --tags --long --dirty > $(ProjectDir)version.txt" Outputs="$(ProjectDir)version.txt" WorkingDirectory="$(SolutionDir)" IgnoreExitCode="true" Condition="$(GitExists)">
          <Output TaskParameter="ExitCode" PropertyName="ExitCode" />
        </Exec>
        <Message Importance="high" Text="Calling git failed with exit code $(ExitCode)" Condition="$(GitExists) And '$(ExitCode)'!='0'" />

        <ReadLinesFromFile File="$(ProjectDir)version.txt" Condition="$(GitExists) And '$(ExitCode)'=='0'">
          <Output TaskParameter="Lines" ItemName="OutputLines"/>
        </ReadLinesFromFile>
        <Message Importance="High" Text="Tags: @(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'"/>

        <Delete Condition="Exists('$(ProjectDir)version.txt')" Files="$(ProjectDir)version.txt"/>

        <GetVersion VersionString="@(OutputLines)" Condition="$(GitExists) And '$(ExitCode)'=='0'">
          <Output TaskParameter="Version" PropertyName="VersionString"/>
          <Output TaskParameter="Commit" PropertyName="Commit"/>
        </GetVersion>

        <PropertyGroup>
          <VersionString Condition="'$(VersionString)'==''">0.0.0.0</VersionString>
        </PropertyGroup>

        <Message Importance="High" Text="Creating CommonVersionInfo.cs with version $(VersionString) $(Commit)" />

        <WriteLinesToFile Overwrite="true" File="$(ProjectDir)CommonAssemblyInfo.cs" Encoding="UTF-8" Lines='using System.Reflection%3B

    // full version: $(VersionString)-$(Commit)

    [assembly: AssemblyVersion("$(VersionString)")]
    [assembly: AssemblyInformationalVersion("$(VersionString)")] 
    [assembly: AssemblyFileVersion("$(VersionString)")]' />

      </Target>
    </Project>

EDITAR: Si está construyendo usando MSBUILD el

 $(SolutionDir)

Podría causarle problemas, use

 $(ProjectDir)

en lugar

Mar Skeltved
fuente
¡Agradable! ¿VersionSuffix termina siendo configurado o usado? No parece serlo
Mark Adamson
4

Puede hacer lo siguiente, dentro del archivo csproj. No descubrí las matemáticas. Encontré eso en otro lugar de stackoverflow. Pero esto funciona y le dará algo similar a 1.0. * Para la versión.

<PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <FileVersion>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays).$([System.Math]::Floor($([MSBuild]::Divide($([System.DateTime]::UtcNow.TimeOfDay.TotalSeconds), 1.32))))</FileVersion>
    <Version>1.0.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2000-01-01"))).TotalDays)</Version>
</PropertyGroup>
Clarke76
fuente
3

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

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

señoramision
fuente
1
Hice una prueba rápida con la solución de demostración (aplicación de Windows) y funciona, también con el proyecto estándar .net. Fue una prueba rápida, así que tenemos que profundizar más para comprobar si hace todo lo que queremos. Pero seguro que podrías probar este.
ArieKanarie
3

Gracias a @joelsand por señalarme en la dirección correcta.

Tuve que cambiar su respuesta ligeramente, ya que cuando se ejecutó DevOps Build, obtuve la siguiente excepción

The specified version string does not conform to the recommended format - major.minor.build.revision

Tuve que agregar $ (BUILD_BUILDNUMBER) al final de la sección major.minor.build. Para eliminar la duplicación de la versión real, también utilizo un prefijo de versión:

<PropertyGroup>
    <VersionPrefix>1.0.3</VersionPrefix>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">$(VersionPrefix)-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(VersionPrefix)-$(BUILD_BUILDNUMBER)</Version>
</PropertyGroup>
Stu Harper
fuente
Tuve exactamente el mismo problema y tu respuesta lo solucionó. Gracias.
Asistente de reunión
2

Podemos usar un parámetro especial para dotnet publish -- version-suffix 1.2.3

Para la versión del archivo:

<AssemblyVersion Condition=" '$(VersionSuffix)' == '' ">0.0.1.0</AssemblyVersion>
<AssemblyVersion Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>

Para la versión:

<Version Condition=" '$(VersionSuffix)' == '' ">0.0.1</Version>
<Version Condition=" '$(VersionSuffix)' != '' ">$(VersionSuffix)</Version>

https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish?tabs=netcore21

--version-suffix <VERSION_SUFFIX>     Defines the value for the $(VersionSuffix) property in the project.
Anatoli Klamer
fuente
1

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

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

BUILD_BUILDNUMBERes 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 Environment Variable Nameen cproj.

maxisam
fuente
¿No se build.xxxxusa en el front-end para hacer referencia dentro de una tubería y BUILD_XXXXes el mismo valor pero con una sintaxis ligeramente modificada requerida para hacer referencia a la variable en PS?
dst3p