Phiên bản tự động trong Visual Studio 2017 (.NET Core)


112

Tôi đã dành phần tốt hơn trong vài giờ để cố gắng tìm cách tự động tăng phiên bản trong .NETCoreApp 1.1 (Visual Studio 2017).

Tôi biết AssemblyInfo.cs đang được tạo động trong thư mục: obj/Debug/netcoreapp1.1/

Nó không chấp nhận phương pháp cũ của: [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.*")]

Nếu tôi đặt dự án thành gói, tôi có thể đặt các phiên bản ở đó nhưng điều này dường như được sử dụng để xây dựng tệp AssemblyInfo.cs.

Câu hỏi của tôi là, có ai đã tìm ra cách kiểm soát phiên bản trong các dự án .NET Core (hoặc .NETStandard cho vấn đề đó) chưa.


Tôi không biết bạn đã làm được bao xa với điều này, nhưng có vẻ như tôi đã hỏi gần như cùng một câu hỏi theo một cách khác ( stackoverflow.com/a/43280282/685341 ) - Có thể câu trả lời được chấp nhận cho câu hỏi này sẽ giúp bạn; bạn chỉ có thể chuyển /p:cờ đến dotnet msbuildtrong tập lệnh xây dựng và thiết lập phiên bản, công ty, bản quyền ... tất cả những thứ tốt đó.
Jay

2
Cảm ơn bạn về thông tin. Điều đó chỉ mở ra các tùy chọn bổ sung.
Jason H

Trước đây * được hỗ trợ cho AssemblyVersion, không cho AssemblyFileVersion- hãy xem Tôi có thể tự động tăng phiên bản tạo tệp khi sử dụng Visual Studio không?
Michael Freidgeim

4
FWIW ký tự đại diện trong phiên bản lắp ráp không được hỗ trợ vì đối với các dự án mới này, chế độ "xác định" của trình biên dịch được kích hoạt theo mặc định. Vì tự động tăng sẽ phá vỡ tính xác định (cùng đầu vào> cùng đầu ra) nên nó không được phép trong chế độ đó. Bạn có thể đặt <Deterministic>False</Deterministic>trong csproj để sử dụng nó. (hoặc sử dụng bất kỳ logic MSBuild khác để tính toán <VersionPrefix>/ <Version>)
Martin Ullrich

Câu trả lời:


23

Tôi đã tìm kiếm bộ tăng phiên bản cho ứng dụng Net Core trong VS2017 bằng định dạng cấu hình csproj.

Tôi đã tìm thấy một dự án có tên là dotnet bướu hoạt động cho định dạng project.json nhưng phải vật lộn để tìm giải pháp cho định dạng .csproj. Người viết bài quảng cáo dotnet thực sự đã đưa ra giải pháp cho định dạng .csproj và nó được gọi là MSBump.

Có một dự án trên GitHub cho nó tại:

https://github.com/BalassaMarton/MSBump

nơi bạn có thể xem mã và nó cũng có sẵn trên Nuget. Chỉ cần tìm kiếm MSBump trên Nuget.


1
Tôi khuyên bạn nên sử dụng bản phát hành 2.1.0 mới nhất của MSBump, Nó hỗ trợ chuyển đổi cấu hình tốt hơn và cũng đặt phiên bản cho bản dựng hiện tại, không phải bản tiếp theo (như phiên bản trước).
Márton Balassa

Tôi thấy nó bây giờ cũng hỗ trợ MSBuild trong khi trước đây nó yêu cầu studio trực quan.
ravetroll

2
Có, và nó cũng hỗ trợ các dự án đa mục tiêu.
Márton Balassa

4
Cân nhắc sử dụng GitVersaction. Nó có thể phù hợp để chạy trên môi trường CI của bạn. github.com/AArnott/Nerdbank.GitVersinstall
Henrique

1
MSBump tăng phiên bản trên mọi bản dựng ngay cả khi bạn không thay đổi bất cứ điều gì, điều này gây ra rất nhiều vấn đề về lâu dài. Và đôi khi các phiên bản không đồng bộ và một phiên bản bị xếp sau phiên bản kia.
Konrad

68

Thêm vào <Deterministic>False</Deterministic> bên trong một <PropertyGroup>phần của .csproj

Giải pháp để làm cho AssemblyVersion * hoạt động được mô tả trong “Thông báo lỗi khó hiểu cho ký tự đại diện trong [AssemblyVersion] trên .Net Core # 22660”

Các ký tự đại diện chỉ được phép nếu bản dựng không mang tính xác định, là mặc định cho các dự án .Net Core. Thêm  <Deterministic>False</Deterministic> vào csproj sẽ khắc phục được sự cố.

Các lý do tại sao .Net Core Developers coi Công trình xác định có lợi được mô tả trong http://blog.paranoidcoding.com/2016/04/05/deterministic-builds-in-roslyn.htmlTrình biên dịch nên xác định: đầu vào giống nhau tạo ra đầu ra giống nhau # 372

Tuy nhiên, nếu bạn đang sử dụng TeamCity, TFS hoặc công cụ CI / CD khác, có lẽ tốt hơn nên giữ số phiên bản được kiểm soát và tăng dần bởi chúng và chuyển để xây dựng dưới dạng tham số (như nó đã được đề xuất trong các câu trả lời khác), ví dụ:

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

Số gói cho các gói NuGet

msbuild /t:pack /p:Version=YourVersionNumber   

Cảm ơn bạn! Tôi biết có một đòn bẩy ẩn để mở căn phòng kho báu! Tôi đang chuyển một dự án cũ sang .NET SDK mới và tôi thực sự muốn thực hiện việc này nhanh chóng mà không gặp rắc rối khi tìm các giải pháp gia tăng phiên bản tự động. Trong thực tế, càng tương thích với các cách cũ thì càng tốt cho trường hợp của tôi.
Ivaylo Slavov

Đây là câu trả lời tốt nhất IMO. Nó cho phép công cụ xây dựng hoạt động bình thường. Ít nhất tôi có thể sử dụng một cơ chế bên ngoài để đưa số vào bản dựng ngay bây giờ.
Michael Yanni

Vui lòng mở rộng câu trả lời của bạn thêm một chút: phần bổ sung được đề xuất cần phải đi vào phần <PropertyGroup> của .csproj. Và cảm ơn vì câu trả lời tuyệt vời này, tất nhiên!
GerardV

1
@gerardv, thực hiện, nhưng bạn có thể làm cải thiện chỉnh sửa một mình stackoverflow.com/help/editing
Michael Freidgeim

61

Nếu bạn đang sử dụng Visual Studio Team Services / TFS hoặc một số quy trình xây dựng CI khác để tích hợp sẵn phiên bản, bạn có thể sử dụng Conditionthuộc tính của msbuild , ví dụ:

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

Điều này sẽ yêu cầu trình biên dịch .NET Core sử dụng bất cứ thứ gì có trong BUILD_BUILDNUMBERbiến môi trường nếu nó hiện diện hoặc dự phòng 0.0.1-localnếu bạn đang xây dựng trên máy cục bộ của mình.


Tuyệt vời, tôi thích cách tiếp cận này vì các biến môi trường chỉ có thể được đặt tại máy chủ xây dựng trong khi các điều kiện này xác định tập hợp lắp ráp trong các tệp nhị phân.
jbooker

Có vẻ như không hoạt động trên TFS 2010, nhưng hy vọng chúng tôi sẽ sớm loại bỏ điều đó!
Mark Adamson

Không phải là một giải pháp tồi, mặc dù có thể có một chút hiệu quả nếu giải pháp có nhiều dự án.
tofutim

Giải pháp tốt. Tôi đã nhận được một ngoại lệ Xây dựng mặc dù. Tôi đã phải thay đổi cấu hình một chút để khắc phục nó. stackoverflow.com/a/59858009/106227
Stu Harper

Điều này hoạt động tốt với .NET Core 2.1.2 và TFS2017U3
Dave Johnson

15

Tôi đã đưa ra giải pháp hoạt động gần giống như thuộc tính AssemblyVersion cũ với dấu sao (*) - AssemblyVersion ("1.0. ") *

Giá trị cho AssemblyVersionAssemblyFileVersion nằm trong tệp .csproj của dự án MSBuild (không phải trong AssemblyInfo.cs ) dưới dạng thuộc tính FileVersion (tạo AssemblyFileVersionAttribute ) và AssemblyVersion (tạo AssemblyVersionAttribute ). Trong quy trình MSBuild, chúng tôi sử dụng tác vụ MSBuild tùy chỉnh của mình để tạo số phiên bản và sau đó chúng tôi ghi đè các giá trị của các thuộc tính FileVersionAssemblyVersion này bằng các giá trị mới từ tác vụ.

Vì vậy, trước tiên, chúng tôi tạo tác vụ MSBuild tùy chỉnh 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();
    }
}

Nhiệm vụ lớp kế thừa từ Microsoft.Build.Utilities.Task lớp từ Microsoft.Build.Utilities.Core gói NuGet. Nó có thuộc tính BaseVersion (tùy chọn) trên đầu vào và trả về phiên bản đã tạo trong thuộc tính đầu ra Phiên bản. Logic để lấy số phiên bản cũng giống như lập phiên bản tự động .NET (Số bản dựng là số ngày kể từ ngày 1/1/2000 và Bản sửa đổi là nửa giây kể từ nửa đêm).

Để xây dựng tác vụ MSBuild này, chúng tôi sử dụng kiểu dự án thư viện lớp .NET Standard 1.3 với lớp này.

.csproj tệp có thể trông giống như sau:

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

Dự án nhiệm vụ này cũng có sẵn trong GitHub holajan / DC.Build.Tasks của tôi

Bây giờ chúng ta thiết lập MSBuild để sử dụng tác vụ này và đặt thuộc tính FileVersionAssemblyVersion . Trong tệp .csproj, nó trông giống như sau:

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

Những điều quan trọng ở đây:

  • Đã đề cập đến usingTask nhập tác vụ GetCurrentBuildVersion từ DC.Build.Tasks.dll . Nó giả định rằng tệp dll này nằm trên thư mục mẹ từ tệp .csproj của bạn.
  • Mục tiêu BeforeBuildActionsProject1 của chúng tôi gọi nhiệm vụ phải có tên duy nhất cho mỗi dự án trong trường hợp chúng tôi có nhiều dự án hơn trong giải pháp gọi tác vụ GetCurrentBuildVersion.

Ưu điểm của giải pháp này là nó hoạt động không chỉ từ các bản dựng trên máy chủ xây dựng, mà còn trong các bản dựng thủ công từ bản dựng dotnet hoặc Visual Studio.


4
Tôi khuyên bạn nên sử dụng DateTime.UtcNowthay vì DateTime.Nowtrong phương thức GetCurrentBuildVersionString()cụ thể nếu mã được thực thi trên các máy xây dựng tự động. Chúng có thể chạy lúc 2 giờ sáng hoặc 3 giờ sáng khi máy tính của bạn chuyển sang / từ giờ tiết kiệm ánh sáng ban ngày. Với DateTime.Nowkịch bản đó, bạn có thể bị thụt lùi về phiên bản. Phải thừa nhận rằng đây là một trường hợp góc cạnh và tôi cũng thừa nhận rằng tôi rất kén chọn. :-) Ngoài ra, vấn đề cũng sẽ biến mất nếu bạn định cấu hình múi giờ giống nhau trên tất cả các máy xây dựng và không điều chỉnh theo thời gian tiết kiệm ánh sáng ban ngày.
Manfred

Có gói NuGet cho việc này chưa?
Jonathan Allen

@Jonathan Allen Không, tôi không có kế hoạch cho gói nuget, vì tên khác nhau trong mỗi dự án. Bạn có thể tải xuống tập hợp tác vụ xây dựng đã biên dịch trong thư mục github.com/holajan/DC.Build.Tasks/tree/master/dist
HolaJan 21/1217

Chúng tôi đã sử dụng một ứng dụng bảng điều khiển tùy chỉnh để kéo phiên bản của chúng tôi từ máy chủ và tạo tệp AssemblyInfo.cs trước khi xây dựng. Cách tiếp cận của ông ấy là hoàn hảo cho những gì chúng tôi làm. Bạn đã có thể sử dụng phương pháp này để đẩy phiên bản trong "Phiên bản" của tính năng gói của các dự án mới chưa? Điều đó thật tuyệt, nhưng tôi đoán chúng ta có thể quay lại sử dụng nuget.exe để đóng gói vì chúng ta cũng sẽ cần nó để xuất bản.
David Ritchie

15

Bạn có thể sử dụng chức năng thuộc tính MSBuild để đặt hậu tố phiên bản dựa trên ngày hiện tại:

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

Điều này sẽ xuất ra một gói có tên như: PackageName.1.0.0-pre20180807-1711.nupkg .

Thêm chi tiết về các chức năng thuộc tính MSBuild: https://docs.microsoft.com/en-us/visualstudio/msbuild/property-functions

Dấu Versionđược hình thành từ sự kết hợp của VersionPrefixVersionSuffix, hoặc nếu để VersionSuffixtrống, VersionPrefixchỉ.

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

Điều này thực sự tiện dụng
Jerry Nixon

11

Tôi chấp nhận câu trả lời ở trên vì @Gigi là đúng (tính đến thời điểm hiện tại) nhưng tôi đã khó chịu và đã nghĩ ra Tập lệnh PowerShell sau.

Đầu tiên, tôi có tập lệnh trong thư mục giải pháp của mình (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)

Tôi đã thêm cái này vào tệp 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>

Ngay cả khi nó được thiết lập là PreBuildEvent, thực tế là số phiên bản không được cập nhật cho đến SAU KHI tệp đã được tải vào bộ nhớ, vì vậy số phiên bản sẽ không phản ánh cho đến lần xây dựng tiếp theo. Trên thực tế, bạn có thể thay đổi nó thành PostBuildEvent và nó sẽ có tác dụng tương tự.

Tôi cũng đã tạo hai tập lệnh sau: (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

Tôi đã trả lời: "có ai đã tìm ra cách kiểm soát phiên bản trong các dự án .NET Core (hoặc .NETStandard cho vấn đề đó) không." Tôi tìm thấy câu hỏi này đang cố gắng giải quyết vấn đề này trong bối cảnh xây dựng CI. Tôi muốn đặt phiên bản lắp ráp thành số bản dựng CI.


1
Tiêu đề cho biết "Phiên bản tự động trong Visual Studio 2017 (.NET Core)". Chính xác thì việc xây dựng nó theo cách thủ công tuân theo "Visual Studio 2017" ở đâu?
JCKödel

4
Tôi đã trả lời: "có ai đã tìm ra cách kiểm soát phiên bản trong các dự án .NET Core (hoặc .NETStandard cho vấn đề đó) không." Tôi tìm thấy câu hỏi này đang cố gắng giải quyết vấn đề này trong bối cảnh xây dựng CI. Tôi muốn đặt phiên bản lắp ráp thành số bản dựng CI. Tôi xin lỗi nếu bạn cảm thấy điều này không liên quan đến câu hỏi hiện tại.
Chris McKenzie

Đó là một thành phần hữu ích cho tôi cảm ơn. Tôi sẽ sử dụng điều này như một phần của một giải pháp CI
Đánh dấu Adamson

1
@ChrisMcKenzie: Cảm nhận của bạn nên được bao gồm trong câu trả lời của bạn để làm rõ ý định của bạn
Michael Freidgeim

** này không làm việc cho tôi vào các dự án netstandard khi AssemblyInfo.cs không được xác định và phiên bản đang trong csproj ...
tofutim

9

Các giá trị này hiện đã được đặt trong .csprojtệp:

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

Đây là những giá trị tương tự mà bạn thấy nếu bạn chuyển đến tab Gói trong cài đặt dự án. Mặc dù tôi không nghĩ rằng bạn có thể sử dụng *để tự động thay đổi phiên bản, nhưng những gì bạn có thể làm là giới thiệu một bước xử lý sau thay thế các phiên bản cho bạn (ví dụ như một phần của tích hợp liên tục của bạn).


6
Tôi sợ đây sẽ là câu trả lời. Tôi sẽ xem liệu tôi có thể thực hiện một bước xây dựng trước để tăng nó hay không.
Jason H

3
Như đã chỉ ra trong một chủ đề khác, định dạng csproj mới cho phép bạn tắt tính năng tự động tạo tệp assemblyinfo và để bạn chỉ định tệp của riêng bạn. Tôi đã làm theo lời khuyên về câu trả lời của natemcmaster tại đây và sử dụng tệp AssemblyInfo.cs tiêu chuẩn: stackoverflow.com/questions/42138418/…
James Eby

5
Tại sao họ lại loại bỏ tự động tăng? Nó hoạt động thực sự tốt và rất đơn giản đối với tôi trong nhiều năm. Tôi đẩy bản chính, các bản dựng CI và phần tăng thêm, sau đó phiên bản được đọc trực tiếp từ DLL được xây dựng bằng cách sử dụng một số tập lệnh PS, sau đó sử dụng phiên bản đó làm đối số khi đẩy sang NuGet. Quá đơn giản. Giờ đã hỏng.
Luke Puplett,

1
@LukePuplett tương tự ở đây. rất bực bội!
Shimmy Weitzhandler

@LukePuplett: Xem [“Thông báo lỗi khó hiểu cho ký tự đại diện trong AssemblyVersion trên .Net Core # 22660”] ( github.com/dotnet/roslyn/issues/22660 ), Các lý do tại sao họ coi Công trình xác định có lợi được mô tả trong blog.paranoidcoding.com / 2016/04/05 / ... và Trình biên dịch sẽ xác định: cùng một đầu vào tạo ra cùng một kết quả đầu ra # 372 < github.com/dotnet/roslyn/issues/372 >
Michael Freidgeim

5

Tôi đã tạo một công cụ CLI đơn giản để đặt các chuỗi phiên bản .csproj .NET Core tại đây . Bạn có thể kết hợp nó với các công cụ như GitVersion để hỗ trợ phiên bản tự động trong quá trình xây dựng CI, nếu đó là những gì bạn đang muốn.


@JasonH Cảm ơn, hãy cho tôi biết nếu bạn có bất kỳ vấn đề nào với nó.
Tagc

thiên tài chết tiệt. yêu nó!
pms1969, 13/07/17

4

Để bật phiên bản .Net Core / .Net Dù dự án dựa trên thiết lập GIT của bạn, sử dụng các thẻ / chức năng mô tả của GIT.

Tôi đã sử dụng tệp Prebuild.targets.xml nằm trong thư mục gốc của dự án và được bao gồm trong tệp csproj như:

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

Sử dụng thẻ "GenerateAssembyInfo" để tắt tính năng tạo thông tin lắp ráp tự động.

Sau đó, Prebuild.targets.xml sẽ tạo tệp CommonAssemblyInfo.cs nơi bạn có thể bao gồm các thẻ phiên bản bạn muốn dựa trên phiên bản GIT của bạn

LƯU Ý: Tôi đã tìm thấy Prebuilds.targets.xml ở một nơi khác, vì vậy không phiền khi dọn dẹp nó.)

Tệp 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>

CHỈNH SỬA: Nếu bạn đang xây dựng bằng MSBUILD,

 $(SolutionDir)

Có thể gây rắc rối cho bạn, sử dụng

 $(ProjectDir)

thay thế


Đẹp! VersionSuffix có được thiết lập hoặc sử dụng không? Có vẻ như không phải
Mark Adamson

4

Bạn có thể làm như dưới đây, trong tệp csproj. Tôi đã không tìm ra phép toán. Tôi đã tìm thấy điều đó ở một nơi khác trên stackoverflow. Nhưng điều này hoạt động và sẽ cung cấp cho bạn một cái gì đó tương tự như phiên bản 1.0. *.

<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

Tiện ích mở rộng Phiên bản Tự động cho Visual Studio hiện hỗ trợ .Net Core và .Net Standard tự động bổ sung trong giao diện người dùng đơn giản.

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


1
Tôi đã thực hiện một bài kiểm tra nhanh với giải pháp demo (ứng dụng windows) và nó hoạt động, cũng với dự án tiêu chuẩn .net. Đó là một bài kiểm tra nhanh nên phải đi sâu hơn để kiểm tra xem có tất cả những gì chúng ta muốn không. Nhưng bạn chắc chắn có thể thử cái này.
ArieKanarie

2

Chúng tôi có thể sử dụng tham số đặc biệt cho dotnet publish -- version-suffix 1.2.3

Đối với phiên bản tệp:

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

Đối với phiên bả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.

2

Cảm ơn @joelsand đã chỉ cho tôi đi đúng hướng.

Tôi đã phải thay đổi câu trả lời của anh ấy một chút vì khi Bản dựng DevOps chạy, tôi có ngoại lệ sau

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

Tôi đã phải thêm $ (BUILD_BUILDNUMBER) vào cuối phần major.minor.build. Để loại bỏ trùng lặp phiên bản thực, tôi cũng sử dụng tiền tố phiên bản:

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

Tôi đã có cùng một vấn đề chính xác và câu trả lời của bạn đã sửa nó. Cảm ơn bạn.
cuộc họp

1

Tôi nghĩ Câu trả lời này từ @joelsand là câu trả lời chính xác cho việc đặt số phiên bản cho lõi dotnet chạy trên VSTS

Để thêm thông tin cho câu trả lời này,

BUILD_BUILDNUMBERthực sự là một biến được xác định trước .

Hóa ra có 2 phiên bản của biến được xác định trước.

Một là build.xxxx, còn lại là BUILD_XXXX.

Bạn chỉ có thể sử dụng Environment Variable Nametrong cproj.


Không build.xxxxđược sử dụng trên giao diện người dùng để tham chiếu trong một đường ống và BUILD_XXXXcó cùng giá trị nhưng với cú pháp sửa đổi một chút được yêu cầu để tham chiếu biến trong PS?
dst3p
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.