Controllo automatico delle versioni in Visual Studio 2017 (.NET Core)


112

Ho passato la maggior parte delle ore a cercare un modo per incrementare automaticamente le versioni in .NETCoreApp 1.1 (Visual Studio 2017).

So che AssemblyInfo.cs viene creato dinamicamente nella cartella: obj/Debug/netcoreapp1.1/

Non accetta il vecchio metodo di: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

Se imposto il progetto sul pacchetto posso impostare le versioni lì, ma questo sembra essere utilizzato per creare il file AssemblyInfo.cs.

La mia domanda è: qualcuno ha capito come controllare la versione nei progetti .NET Core (o .NETStandard per quella materia).


Non so fino a che punto sei arrivato con questo, ma sembra che ho chiesto quasi la stessa domanda in un modo diverso ( stackoverflow.com/a/43280282/685341 ) - Forse la risposta accettata a questa domanda ti aiuterà; puoi semplicemente passare il /p:flag al dotnet msbuildtuo script di build e impostare versione, azienda, copyright ... tutte quelle cose buone.
Jay

2
Grazie per le informazioni. Questo apre solo opzioni aggiuntive.
Jason H

In precedenza * era supportato per AssemblyVersion, non per AssemblyFileVersion. Vedere Posso incrementare automaticamente la versione di compilazione del file quando si utilizza Visual Studio?
Michael Freidgeim,

4
FWIW il carattere jolly nella versione assembly non è supportato perché per questi nuovi progetti, la modalità "deterministica" del compilatore è attiva per impostazione predefinita. Poiché l'incremento automatico interrompe il determinismo (stesso input> stesso output), non è consentito in quella modalità. Puoi impostare <Deterministic>False</Deterministic>in csproj per usarlo. (o utilizzare qualsiasi altra logica di MSbuild per calcolare <VersionPrefix>/ <Version>)
Martin Ullrich

Risposte:


23

Stavo cercando un incrementatore di versione per un'app Net Core in VS2017 utilizzando il formato di configurazione csproj.

Ho trovato un progetto chiamato dotnet bump che funzionava per il formato project.json ma faticato a trovare una soluzione per il formato .csproj. L'autore del dotnet bump ha effettivamente escogitato la soluzione per il formato .csproj e si chiama MSBump.

C'è un progetto su GitHub per questo a:

https://github.com/BalassaMarton/MSBump

dove puoi vedere il codice ed è disponibile anche su Nuget. Basta cercare MSBump su Nuget.


1
Consiglio di utilizzare l'ultima versione 2.1.0 di MSBump, supporta meglio il cambio di configurazione e imposta anche la versione per la build corrente, non quella successiva (come la versione precedente).
Márton Balassa

Vedo che ora supporta anche MSBuild mentre prima richiedeva uno studio visivo.
ravetroll

2
Sì, e supporta anche progetti multitargeting.
Márton Balassa

4
Prendi in considerazione l'utilizzo di GitVersioning. Potrebbe essere adatto per l'esecuzione nell'ambiente CI. github.com/AArnott/Nerdbank.GitVersioning
Henrique

1
MSBump incrementa la versione su ogni build anche se non hai cambiato nulla, questo causa molti problemi a lungo termine. E a volte le versioni non sono sincronizzate e una versione è dietro l'altra.
Konrad

68

Aggiungi <Deterministic>False</Deterministic> all'interno di una <PropertyGroup>sezione di .csproj

La soluzione alternativa per far funzionare AssemblyVersion * è descritta in "Confondere il messaggio di errore per il carattere jolly in [AssemblyVersion] su .Net Core # 22660"

I caratteri jolly sono consentiti solo se la build non è deterministica, che è l'impostazione predefinita per i progetti .Net Core. L'aggiunta  <Deterministic>False</Deterministic> a csproj risolve il problema.

I motivi per cui gli sviluppatori .Net Core considerano le build deterministiche vantaggiose descritte in http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.html e i compilatori dovrebbero essere deterministici: gli stessi input generano gli stessi output # 372

Tuttavia, se stai utilizzando TeamCity, TFS o altri strumenti CI / CD, probabilmente è meglio mantenere il numero di versione controllato e incrementato da loro e passare alla build come parametro (come suggerito in altre risposte), ad es.

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

Numero del pacchetto per i pacchetti NuGet

msbuild /t:pack /p:Version=YourVersionNumber   

Grazie! Sapevo che c'era una leva nascosta per aprire la stanza del tesoro! Sto migrando un vecchio progetto al nuovo .NET SDK e volevo farlo velocemente, senza il fastidio di trovare soluzioni automatizzate per l'incremento della versione. In effetti, più è compatibile con i vecchi metodi, meglio è per il mio caso.
Ivaylo Slavov

Questa è la migliore risposta IMO. Consente agli strumenti di costruzione di funzionare correttamente. Almeno posso usare un meccanismo esterno per inserire il numero nella build ora.
Michael Yanni

Espandi la tua risposta ancora un po ': l'aggiunta suggerita deve andare nella sezione <PropertyGroup> di .csproj. E grazie per questa ottima risposta, ovviamente!
GerardV

1
@gerardv, fatto, ma puoi migliorare le modifiche da solo stackoverflow.com/help/editing
Michael Freidgeim

62

Se utilizzi Visual Studio Team Services / TFS o un altro processo di compilazione di elementi della configurazione per avere il controllo delle versioni integrato, puoi utilizzare l' Conditionattributo di msbuild , ad esempio:

<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>

Questo indicherà al compilatore .NET Core di usare tutto ciò che è nella BUILD_BUILDNUMBERvariabile di ambiente se è presente, o di eseguire il fallback 0.0.1-localse stai facendo una compilazione sul tuo computer locale.


Bello, mi piace questo approccio perché le variabili di ambiente possono essere impostate solo sul server di compilazione mentre queste condizioni determinano l'assembly impostato nei binari.
jbooker

Non sembra funzionare su TFS 2010, ma si spera che presto ce ne andremo!
Mark Adamson

Non è una cattiva soluzione, anche se potrebbe essere un po 'di lavoro se la soluzione ha molti progetti.
tofutim

Buona soluzione. Tuttavia, ho ricevuto un'eccezione Build. Ho dovuto modificare leggermente la configurazione per risolverlo. stackoverflow.com/a/59858009/106227
Stu Harper

Funziona alla grande con .NET Core 2.1.2 e TFS2017U3
Dave Johnson

16

Ho trovato una soluzione che funzionava quasi come il vecchio attributo AssemblyVersion con star (*) - AssemblyVersion ("1.0. ") *

I valori per AssemblyVersion e AssemblyFileVersion si trovano nel file .csproj del progetto MSBuild (non in AssemblyInfo.cs ) come proprietà FileVersion (genera AssemblyFileVersionAttribute ) e AssemblyVersion (genera AssemblyVersionAttribute ). Nel processo di MSBuild utilizziamo la nostra attività MSBuild personalizzata per generare i numeri di versione e quindi sovrascriviamo i valori di questi FileVersion e proprietà AssemblyVersion con nuovi valori dall'attività.

Quindi per prima cosa creiamo la nostra attività MSBuild personalizzata 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 classe di attività eredita dalla classe Microsoft.Build.Utilities.Task da Microsoft.Build.Utilities.Core package NuGet. Accetta la proprietà BaseVersion (opzionale) sull'input e restituisce la versione generata nella proprietà Version output. La logica per ottenere i numeri di versione è la stessa del controllo automatico delle versioni .NET (il numero di build è il conteggio dei giorni dall'1 / 1/2000 e la revisione è mezzo secondo dalla mezzanotte).

Per creare questa attività di MSBuild, utilizziamo la libreria di classi .NET Standard 1.3 tipo di progetto della con questa classe.

Il file .csproj può avere questo aspetto:

<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>

Questo progetto di attività è disponibile anche nel mio GitHub holajan / DC.Build.Tasks

Ora configuriamo MSBuild per usare questa attività e impostare le proprietà FileVersion e AssemblyVersion . Nel file .csproj assomiglia a questo:

<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>

Cose importanti qui:

  • Menzionato UsingTask importa l'attività GetCurrentBuildVersion da DC.Build.Tasks.dll . Si presume che questo file dll si trovi nella directory principale del file .csproj.
  • La nostra destinazione BeforeBuildActionsProject1 che chiama l'attività deve avere un nome univoco per progetto nel caso in cui abbiamo più progetti nella soluzione che chiama l'attività GetCurrentBuildVersion.

Il vantaggio di questa soluzione è che funziona non solo da build su build server, ma anche in build manuali da dotnet build o Visual Studio.


4
Consiglierei di utilizzare al DateTime.UtcNowposto del DateTime.Nowmetodo GetCurrentBuildVersionString()in particolare se il codice viene eseguito su macchine di compilazione automatizzate. Possono essere eseguiti alle 2 o alle 3 del mattino quando il computer passa all'ora legale. In DateTime.Nowquesto scenario potresti tornare indietro in termini di versione. Certo, questo è un caso d'angolo e ammetto anche di essere pignolo. :-) Inoltre, il problema scompare anche se si configura lo stesso fuso orario su tutte le macchine compilate e non si adegua l'ora legale.
Manfred

Esiste ancora un pacchetto NuGet per questo?
Jonathan Allen

@ Jonathan Allen No, non ho alcun piano per il pacchetto nuget, a causa del nome diverso in ogni progetto. Puoi scaricare l'
assembly delle

Abbiamo utilizzato un'app console personalizzata per estrarre la nostra versione da un server e generare il file AssemblyInfo.cs prima delle build. Questo approccio è perfetto per quello che facciamo. Sei stato in grado di utilizzare questo metodo per spingere la versione in "Versione" della funzionalità pack dei nuovi progetti? Sarebbe bello, ma immagino che possiamo ripiegare sull'utilizzo di nuget.exe anche per il pacchetto poiché avremo bisogno anche di pubblicarlo.
David Ritchie

15

È possibile utilizzare una funzione di proprietà di MSBuild per impostare il suffisso della versione in base alla data corrente:

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

Questo produrrà un pacchetto con un nome come: PackageName.1.0.0-pre20180807-1711.nupkg .

Ulteriori dettagli sulle funzioni delle proprietà di MSBuild: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions

Il Versionè formato dalla combinazione di VersionPrefixe VersionSuffix, o se VersionSuffixè vuoto, VersionPrefixsolo.

<PropertyGroup>
  <VersionPrefix>1.0.0</VersionPrefix>
</PropertyGroup>

Questo è davvero utile
Jerry Nixon

12

Ho accettato la risposta di cui sopra perché @Gigi è corretto (per ora) ma ero infastidito e ho creato i seguenti script di PowerShell.

Per prima cosa ho lo script nella mia cartella della soluzione (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)

L'ho aggiunto al file 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>

Anche se è impostato come PreBuildEvent, il fatto è che i numeri di versione non vengono aggiornati fino a DOPO che il file è stato caricato in memoria, quindi il numero di versione non si rifletterà fino alla build successiva. In effetti, potresti cambiarlo in un PostBuildEvent e avrebbe lo stesso effetto.

Ho anche creato i seguenti due script: (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)

10

dotnet build /p:AssemblyVersion=1.2.3.4

Stavo rispondendo a: "qualcuno ha capito come controllare la versione nei progetti .NET Core (o .NETStandard)". Ho trovato questa domanda cercando di risolvere questo problema nel contesto di una build CI. Volevo impostare la versione dell'assembly sul numero di build dell'elemento della configurazione.


1
Il titolo dice "Controllo automatico delle versioni in Visual Studio 2017 (.NET Core)". Dove esattamente costruirlo manualmente è conforme a "Visual Studio 2017"?
JCKödel

4
Stavo rispondendo a: "qualcuno ha capito come controllare la versione nei progetti .NET Core (o .NETStandard)". Ho trovato questa domanda cercando di risolvere questo problema nel contesto di una build CI. Volevo impostare la versione dell'assembly sul numero di build dell'elemento della configurazione. Mi dispiace se ritieni che questo non fosse rilevante per la domanda in questione.
Chris McKenzie

È una componente utile per me, grazie. Lo userò come parte di una soluzione CI
Mark Adamson

1
@ChrisMcKenzie: il tuo commento dovrebbe essere incluso nella tua risposta per rendere chiaro il tuo intento
Michael Freidgeim,

** questo non funziona per me su progetti netstandard quando assemblyinfo.cs non è specificato e la versione è in csproj ...
tofutim

9

Questi valori sono ora impostati nel .csprojfile:

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

Questi sono gli stessi valori che vedi se vai nella scheda Pacchetto nelle impostazioni del progetto. Anche se non penso che tu possa usare *per aumentare automaticamente la versione, quello che puoi fare è introdurre una fase di post-elaborazione che sostituisce le versioni per te (ad esempio come parte della tua integrazione continua).


6
Temevo che questa sarebbe stata la risposta. Vedrò se posso fare un passaggio di pre-compilazione per incrementarlo.
Jason H

3
Come sottolineato in un altro thread, il nuovo formato csproj consente di disattivare la generazione automatica del file assemblyinfo e di specificare il proprio. Ho seguito il consiglio della risposta di natemcmaster qui e ho utilizzato un file AssemblyInfo.cs standard: stackoverflow.com/questions/42138418/…
James Eby

5
Perché hanno rimosso l'incremento automatico? Ha funzionato molto bene e molto semplicemente per me per anni. Inserisco master, build CI e incrementi, quindi la versione viene letta direttamente dalla DLL compilata utilizzando alcuni script PS, quindi uso quella versione come argomento quando si invia a NuGet. Così semplice. Ora rotto.
Luke Puplett il

1
@LukePuplett stesso qui. così frustrante!
Shimmy Weitzhandler

@LukePuplett: Vedi ["Confondere messaggio di errore per caratteri jolly in AssemblyVersion su .Net Core # 22660"] ( github.com/dotnet/roslyn/issues/22660 ), I motivi per cui considerano le build deterministiche vantaggiose descritte in blog.paranoidcoding.com /
2016/04/05

5

Ho creato un semplice strumento CLI per impostare le stringhe della versione .NET Core di .csproj qui . Puoi combinarlo con strumenti come GitVersion per il bumping automatico della versione durante le build CI, se è quello che stai cercando.


@ JasonH Grazie, fammi sapere se hai problemi con esso.
Tagc

dannato genio. lo adoro!
pms1969

4

Per abilitare il controllo delle versioni del tuo .Net Core / .Net Qualunque sia il progetto basato sulla tua configurazione GIT, utilizza i tag / descrivi la funzionalità di GIT.

Ho utilizzato un file Prebuild.targets.xml che si trova nella cartella principale del progetto e incluso nel file csproj come:

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

Utilizzare il tag "GenerateAssembyInfo" per disabilitare la generazione automatica delle informazioni sull'assembly.

Quindi Prebuild.targets.xml genererà un file CommonAssemblyInfo.cs in cui puoi includere i tag di versione che desideri in base alla tua versione GIT

NOTA: ho trovato Prebuilds.targets.xml da qualche altra parte, quindi non mi sono preoccupato di pulirlo.)

Il file 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>

EDIT: se stai costruendo usando MSBUILD il file

 $(SolutionDir)

Potrebbe causare problemi, usa

 $(ProjectDir)

anziché


Bello! VersionSuffix finisce per essere impostato o utilizzato? Non sembra essere
Mark Adamson

4

Puoi fare quanto segue, all'interno del file csproj. Non ho capito la matematica. L'ho scoperto da qualche altra parte su StackOverflow. Ma questo funziona e ti darà qualcosa di simile alla 1.0. * Per la versione.

<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>

3

L'estensione Versioni automatiche per Visual Studio ora supporta l'incremento automatico .Net Core e .Net Standard in una semplice interfaccia utente.

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


1
Ho fatto un rapido test con la soluzione demo (app Windows) e funziona, anche con il progetto standard .net. È stato un test rapido, quindi dobbiamo immergerci più a fondo per verificare se fa tutto ciò che vogliamo. Ma potresti sicuramente provare questo.
ArieKanarie

3

Grazie a @joelsand per avermi indicato nella giusta direzione.

Ho dovuto modificare leggermente la sua risposta poiché quando è stata eseguita la build DevOps, ho ottenuto la seguente eccezione

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

Ho dovuto aggiungere $ (BUILD_BUILDNUMBER) alla fine della sezione major.minor.build. Per deduplicare la versione effettiva, utilizzo anche un prefisso di versione:

<PropertyGroup>
    <VersionPrefix>1.0.3</VersionPrefix>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' == '' ">$(VersionPrefix)-local</Version>
    <Version Condition=" '$(BUILD_BUILDNUMBER)' != '' ">$(VersionPrefix)-$(BUILD_BUILDNUMBER)</Version>
</PropertyGroup>

Ho avuto lo stesso identico problema e la tua risposta lo ha risolto. Grazie.
Partecipante alla riunione il

2

Possiamo usare un parametro speciale per dotnet publish -- version-suffix 1.2.3

Per la versione del file:

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

Per la versione:

<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.

1

Penso che questa risposta da @joelsand sia la risposta corretta per l'impostazione del numero di versione per dotnet core in esecuzione su VSTS

Per aggiungere ulteriori informazioni per questa risposta,

BUILD_BUILDNUMBERè in realtà una variabile predefinita .

Si scopre che ci sono 2 versioni di variabile predefinita.

Uno è build.xxxx, l'altro è BUILD_XXXX.

Puoi usare solo Environment Variable Namein cproj.


Non viene build.xxxxutilizzato sul front-end per fare riferimento all'interno di una pipeline ed BUILD_XXXXè lo stesso valore ma con una sintassi leggermente modificata richiesta per fare riferimento alla variabile in PS?
dst3p
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.