Wymyśliłem rozwiązanie, które działało prawie tak samo, jak stary atrybut AssemblyVersion z gwiazdką (*) - AssemblyVersion („1.0. ”) *
Wartości dla AssemblyVersion i AssemblyFileVersion znajdują się w pliku .csproj projektu MSBuild (nie w AssemblyInfo.cs ) jako właściwość FileVersion (generuje AssemblyFileVersionAttribute ) i AssemblyVersion (generuje AssemblyVersionAttribute ). W procesie MSBuild używamy naszego niestandardowego zadania MSBuild do generowania numerów wersji, a następnie zastępujemy wartości tych właściwości FileVersion i AssemblyVersion nowymi wartościami z zadania.
Więc najpierw tworzymy nasze niestandardowe zadanie 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();
}
}
Zadanie klasa dziedziczy z Microsoft.Build.Utilities.Task klasy z Microsoft.Build.Utilities.Core pakietu Nuget. Pobiera właściwość BaseVersion (opcjonalna) na wejściu i zwraca wygenerowaną wersję we właściwości wyjściowej wersji. Logika uzyskiwania numerów wersji jest taka sama jak w przypadku automatycznego sprawdzania wersji .NET (numer kompilacji to liczba dni od 1 stycznia 2000 r., A wersja to pół sekundy od północy).
Aby zbudować to zadanie MSBuild, używamy typu projektu biblioteki klas .NET Standard 1.3 z tą klasą.
Plik .csproj może wyglądać następująco:
<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>
Ten projekt zadania jest również dostępny w moim holajan / DC.Build.Tasks w serwisie GitHub
Teraz konfigurujemy program MSBuild do korzystania z tego zadania i ustawiamy właściwości FileVersion i AssemblyVersion . W pliku .csproj wygląda to tak:
<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>
Ważne rzeczy tutaj:
- Wspomniany UsingTask importuje zadanie GetCurrentBuildVersion z DC.Build.Tasks.dll . Zakłada się, że ten plik dll znajduje się w katalogu nadrzędnym z pliku .csproj.
- Nasz obiekt Target BeforeBuildActionsProject1, który wywołuje zadanie, musi mieć unikalną nazwę na projekt w przypadku, gdy mamy więcej projektów w rozwiązaniu, które wywołuje zadanie GetCurrentBuildVersion.
Zaletą tego rozwiązania jest to, że działa nie tylko z kompilacji na serwerze kompilacji, ale także w kompilacjach ręcznych z kompilacji dotnet lub programu Visual Studio.
/p:
flagędotnet msbuild
w swoim skrypcie kompilacji i ustawić wersję, firmę, prawa autorskie ... wszystkie te dobre rzeczy.