IT

CI 플랫폼 (Hudson)을 통해 C # 어셈블리 버전을 어떻게 자동으로 증가시킬 수 있습니까?

lottoking 2020. 8. 2. 17:11
반응형

CI 플랫폼 (Hudson)을 통해 C # 어셈블리 버전을 어떻게 자동으로 증가시킬 수 있습니까?


저와 제 그룹은 어셈블리 버전 번호를 증가시키는 데 끔찍한 일이며 종종 어셈블리를 1.0.0.0 버전으로 제공합니다. 분명히 이것은 많은 두통을 유발합니다.

우리는 CI 플랫폼을 통해 우리의 관행을 훨씬 더 잘 변경하고 assemblyinfo.cs파일 의 값을 자동으로 늘리 도록 어셈블리의 버전이 해당 어셈블리의 코드를 자동으로 업데이트하고 설정하고 싶습니다 .

이전에 ( 허드슨 을 발견하기 전에 ) 하나 msbuild또는 명령 줄을 통해 값을 증가시키는 방법을 설정 했지만 (기억 할 수 없음) 허드슨을 사용하면 SVN 저장소를 업데이트하고 다른 빌드를 트리거합니다. 허드슨이 매시간 SVN을 폴링에 따라 무한 루프가 느려질 수 있습니다.

Hudson이 버전 번호를 증가시키는 것은 나쁜 생각입니까? 다른 방법은 무엇입니까?

이상적으로 솔루션의 기준은 다음과 가변합니다.

  • 빌드 assemblyinfo.cs전에 빌드 번호를 개선합니다.
  • 변경된 어셈블리 빌드 번호를 개선합니다. Hudson은 빌드 할 때마다 프로젝트 폴더를 지우는 불가능할 수 있습니다.
  • 변경된 assemblyinfo.cs를 코드 저장소 (현재 VisualSVN )에 커밋
  • 다음 번에 변경 사항을 스캔 할 때 Hudson이 새 빌드를 트리거하지 마십시오.

머릿속에서 해결하면서 배치 파일 / 명령을 통해 대부분의 솔루션을 쉽게 얻을 수 있었지만 다음에 스캔 할 때 Hudson이 새로운 빌드를 트리거 할 아이디어를 만들었습니다. 나는 나를 위해 모든 것을 할 사람을 찾고 있지 않고 올바른 방향으로 나를 가리켜 허드슨이 특정 SVN 커밋을 무시하는 기술 등입니다.

지금까지 모든 것이 모든 것은 버전 번호를 자동으로 증가시키는 방법을 설명하는 기사 일 뿐이며 무한 루프로 회전 할 수있는 CI 플랫폼은 고려하지 않습니다.


간단한 대안은 C # 환경에서 버전 속성을 major.minor.*AssemblyInfo 파일 템플릿에 설명 된대로 설정하여 어셈블리 버전을 늘리도록하는 것 입니다.

그러나보다 많은 인 솔루션을 찾고 있습니다.

편집 (의견에 대한 질문에 답변) :

보낸 사람 AssemblyInfo.cs:

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]

AssemblyFileVersion 특성을 스탬프 처리하기 위해 수행 한 작업은 다음과 가변합니다.

AssemblyInfo.cs에서 AssemblyFileVersion을 제거했습니다.

AssemblyFileInfo.cs라는 비어있는 새 파일을 프로젝트에 추가하십시오.

허드슨 머신 또는 빌드 프로젝트 NuGet 종속성 으로 MSBuild에서 태스크 커뮤니티 도구 세트를 설치하십시오 .

프로젝트 (csproj) 파일을 편집하십시오. 이 단지 msbuild 파일이며 다음을 추가하십시오.

어딘가에 <PropertyGroup>버전 명시되어 있습니다. 예를 들어 읽도록 변경하십시오.

 <Major>1</Major>
 <Minor>0</Minor>
 <!--Hudson sets BUILD_NUMBER and SVN_REVISION -->
 <Build>$(BUILD_NUMBER)</Build>
 <Revision>$(SVN_REVISION)</Revision>

Hudson은 프로젝트가 hudson을 기반으로 빌드 될 때 볼 수있는 환경 변수를 제공합니다 (subversion에서 다양한 가정).

프로젝트 파일의 맨 아래에

 <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')" />
  <Target Name="BeforeBuild" Condition="Exists('$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets')">
    <Message Text="Version: $(Major).$(Minor).$(Build).$(Revision)" />
    <AssemblyInfo CodeLanguage="CS" OutputFile="AssemblyFileInfo.cs" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyConfiguration="$(Configuration)" Condition="$(Revision) != '' " />
  </Target>

MSBuildCommunityTasks를 사용하여 프로젝트가 빌드되기 전에 AssemblyFileVersion 특성을 포함 할 AssemblyFileVersion.cs를 생성합니다. 원하는 경우 모든 버전 속성에 대해이 작업을 수행 할 수 있습니다.

결과적으로 hudson 빌드를 때마다 결과 어셈블리는 AssemblyFileVersion 1.0.HUDSON_BUILD_NR.SVN_REVISION (예 : 1.0.6.2632)을 얻습니다. 이것은 hudson의 6 번째 빌드 #을 서브 버전 개정판 3232에서 buit 함을 의미합니다.


다음은 새 프로젝트를 추가 할 때 약간의 작업이 필요하지만 프로세스를 매우 쉽게 처리하는 우아한 솔루션입니다.

각 프로젝트는 어셈블리 버전 정보 만 포함 된 솔루션 파일에 연결됩니다. 따라서 빌드 프로세스는 단일 파일 만 업데이트되고 모든 어셈블리 버전은시 하나의 파일에서 가져옵니다.

단계 :

  1. 솔루션 파일 * .cs 파일에 클래스를 추가하십시오. 이름은 min SharedAssemblyProperties.cs입니다.
  2. 새 파일에서 모든 CSS 정보를 제거하십시오.
  3. AssemblyInfo 파일에서 어셈블리 정보를 잘라냅니다. [어셈블리 : AssemblyVersion ( "1.0.0.0")] [어셈블리 : AssemblyFileVersion ( "1.0.0.0")]
  4. "System.Reflection; 사용"문을 추가하십시오 파일에 넣은 다음 새 cs 파일 (예 : SharedAssemblyProperties.cs)에 데이터를 넣습니다.
  5. 기존 항목을 프로젝트에 추가하십시오 (기다리십시오 ... 파일을 추가하기 전에 계속 진행하십시오).
  6. 파일을 선택하고 추가를 클릭하기 전에 추가 버튼 옆에있는 드롭 다운을 클릭하고 "링크로 추가"를 선택하십시오.
  7. 솔루션의 모든 기존 및 새 프로젝트에 대해 5 단계와 6 단계를 반복하십시오.

파일을 링크로 추가하면 파일에 데이터가 저장되고 프로젝트시 파일에서 어셈블리 버전 정보를 가져옵니다.

소스 제어에서 SharedAssemblyProperties.cs 파일을 증분하는 bat 파일 또는 펼쳐 파일을 추가하면 모든 프로젝트가 해당 파일에서 어셈블리 정보를 업데이트합니다.


Hudson은 특정 경로 및 파일에 대한 변경 사항을 무시하여 새 빌드를 요구하지 않도록 구성 할 수 있습니다.

구성 페이지의 작업 소스 코드 관리 아래 에서 고급 단추를 클릭하십시오 . 에서 제외 된 지역이 상자는 경기를 제외 하나 이상의 정규 배열을 입력합니다.

예를 들어 version.properties 파일의 변경 사항을 무시 하면 다음을 사용할 수 있습니다.

/MyProject/trunk/version.properties

이것은 C # 이외의 언어에서 작동하며 하위 버전 버전 정보를 사용할 수 있습니다.


.NET이이 작업을 수행합니다. AssemblyInfo.cs 파일에서 어셈블리 버전을 major.minor. * (예 : 1.0. *)로 설정합니다.

프로젝트를 빌드하면 버전이 자동으로 생성됩니다.

빌드 및 개정 번호는 유닉스 시대를 사용하여 날짜를 기반으로 생성됩니다. 빌드는 현재 날짜를 기반으로하고 개정은 자정 이후의 초 수를 기반으로합니다.


1.0. * 기능이 VS2005 또는 VS2008에서 작동하는 것을 실제로 본 적이 없습니다. 값을 증가시키기 위해 VS를 설정하기 위해 수행해야 할 작업이 있습니까?

AssemblyInfo.cs가 1.0. *로 하드 코딩 된 경우 실제 빌드 / 수정은 어디에 저장됩니까?

1.0. *를 AssemblyInfo에 넣은 후 ProductVersion에 잘못된 값이 있으므로 다음 문을 사용할 수 없습니다. VS에서 할당 한 값이 아닌 1.0. *를 사용하고 있습니다.

Version version = new Version(Application.ProductVersion);

한숨-이것은 모두가 물어 보는 것들 중 하나 인 것 같지만 어떻게 든 확실한 대답은 없습니다. 몇 년 전에 수정 번호를 생성하고 빌드 후 프로세스의 일부로 AssemblyInfo에 저장하는 솔루션을 보았습니다. VS2008에는 이런 종류의 춤이 필요하지 않기를 바랐습니다. 어쩌면 VS2010?


아래 AssemblyVersion.tt와 같은 환경에서 문제의 어셈블리 특성을 즉석에서 만드는 텍스트 템플릿 을 사용 하여이 작업을 수행 할 수도 있다고 가정 합니다.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("SVN_REVISION");
revision = revision == null ? "0" : int.Parse(revision).ToString();    
#>
using System.Reflection;
[assembly: AssemblyVersion("1.0.<#=build#>.<#=revision#>")]
[assembly: AssemblyFileVersion("1.0.<#=build#>.<#=revision#>")]

MikeS의 답변의 연속으로 VS + Visual Studio Visualization and Modeling SDK가 작동하려면 설치해야하며 프로젝트 파일도 수정해야한다고 추가하고 싶습니다. 또한 언급해야 할 점은 버전 모듈이있는 Windows 2008 R2 서버 상자에서 실행되는 빌드 서버로 Jenkins를 사용하며 여기서 BUILD_NUMBER를 얻습니다.

내 텍스트 템플릿 파일 version.tt는 다음과 같습니다.

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ output extension=".cs" #>
<#
var build = Environment.GetEnvironmentVariable("BUILD_NUMBER");
build = build == null ? "0" : int.Parse(build).ToString();
var revision = Environment.GetEnvironmentVariable("_BuildVersion");
revision = revision == null ? "5.0.0.0" : revision;    
#>
using System.Reflection;
[assembly: AssemblyVersion("<#=revision#>")]
[assembly: AssemblyFileVersion("<#=revision#>")]

속성 그룹에 다음이 있습니다.

<PropertyGroup>
    <TransformOnBuild>true</TransformOnBuild>
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

Microsoft.CSharp.targets를 가져온 후이 기능이 있습니다 (VS를 설치 한 위치에 따라 다름).

<Import Project="C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\TextTemplating\v10.0\Microsoft.TextTemplating.targets" />

내 빌드 서버에서 다음 스크립트를 사용하여 실제 빌드 전에 텍스트 변환을 실행하여 TFS에서 마지막 변경 집합 번호를 얻습니다.

set _Path="C:\Build_Source\foo"

pushd %_Path% 
"%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\IDE\tf.exe" history . /r /noprompt /stopafter:1 /Version:W > bar
FOR /f "tokens=1" %%foo in ('findstr /R "^[0-9][0-9]*" bar') do set _BuildVersion=5.0.%BUILD_NUMBER%.%%foo
del bar
popd

echo %BUILD_NUMBER%
echo %_BuildVersion%
cd C:\Program Files (x86)\Jenkins\jobs\MyJob\workspace\MyProject
MSBuild MyProject.csproj /t:TransformAll 
...
<rest of bld script>

이렇게하면 빌드 및 변경 집합을 추적 할 수 있으므로 마지막 빌드 이후에 아무것도 확인하지 않은 경우 마지막 숫자는 변경되지 않아야하지만 빌드 프로세스를 변경했을 수 있으므로 두 번째 마지막 숫자가 필요합니다. . 물론 빌드 전에 여러 번 체크인하면 마지막 변경 사항 만 버전에 반영됩니다. 나는 당신이 그것을 연결할 수 있다고 생각합니다.

나는 당신이 더 멋진 일을 할 수 있고 tt 템플릿 내에서 직접 TFS를 호출 할 수 있다고 확신하지만 이것은 나를 위해 작동합니다.

그런 다음 런타임에 내 버전을 다음과 같이 가져올 수 있습니다.

Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
return fvi.FileVersion;

내 솔루션에는 외부 도구 나 스크립팅 언어를 추가 할 필요가 없습니다. 빌드 머신에서 작동하는 것이 거의 보장됩니다. 이 문제를 여러 부분으로 해결합니다. 먼저 Jenkins BUILD_NUMBER 매개 변수를 환경 변수로 변환하는 BUILD.BAT 파일을 만들었습니다. Jenkins의 "Execute Windows batch command"기능을 사용하여 Jenkins 빌드에 대해 다음 정보를 입력하여 빌드 배치 파일을 실행합니다.

     ./build.bat --build_id %BUILD_ID% -build_number %BUILD_NUMBER%

빌드 환경에서 다음과 같이 시작하는 build.bat 파일이 있습니다.

     rem build.bat
     set BUILD_ID=Unknown
     set BUILD_NUMBER=0
     :parse_command_line
     IF NOT "%1"=="" (
         IF "%1"=="-build_id" (
             SET BUILD_ID=%2
             SHIFT
             )
         IF "%1"=="-build_number" (
             SET BUILD_NUMBER=%2
             SHIFT
         )
         SHIFT
         GOTO :parse_command_line
     )
     REM your build continues with the environmental variables set
     MSBUILD.EXE YourProject.sln

그런 다음 Visual Studio의 솔루션 탐색기 창에서 빌드 할 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택하고 빌드 이벤트를 선택한 다음 .cs 파일을 자동으로 생성하는 빌드 전 이벤트 명령 줄에 다음 정보를 입력했습니다. 현재 환경 변수 설정을 기반으로 빌드 번호 정보 포함 :

     set VERSION_FILE=$(ProjectDir)\Properties\VersionInfo.cs
     if !%BUILD_NUMBER%==! goto no_buildnumber_set
     goto buildnumber_set
     :no_buildnumber_set
     set BUILD_NUMBER=0
     :buildnumber_set
     if not exist %VERSION_FILE% goto no_version_file
     del /q %VERSION_FILE%
     :no_version_file
     echo using System.Reflection; >> %VERSION_FILE%
     echo using System.Runtime.CompilerServices; >> %VERSION_FILE%
     echo using System.Runtime.InteropServices; >> %VERSION_FILE%
     echo [assembly: AssemblyVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%
     echo [assembly: AssemblyFileVersion("0.0.%BUILD_NUMBER%.1")] >> %VERSION_FILE%

빌드 취향에 맞게 조정해야 할 수도 있습니다. 주 프로젝트의 Properties 디렉터리에 초기 Version.cs 파일을 생성하기 위해 프로젝트를 수동으로 한 번 빌드합니다. 마지막으로 Version.cs 파일을 해당 프로젝트의 속성 탭 아래에있는 솔루션 탐색기 창으로 끌어 Visual Studio 솔루션에 수동으로 포함합니다. 이후 빌드에서 Visual Studio는 Jenkins 빌드 시간에 해당 .cs 파일을 읽고 올바른 빌드 번호 정보를 가져옵니다.


따라서 버전 번호가 다른 어셈블리가있는 여러 프로젝트가 포함 된 하나의 솔루션이있는 프로젝트가 있습니다.

위의 몇 가지 방법을 조사한 후 AssemblyInfo.cs 파일에서 찾기 및 바꾸기를 수행하는 Powershell 스크립트를 실행하는 빌드 단계를 구현했습니다. 나는 여전히 소스 제어에서 1.0. * 버전 번호를 사용하고 Jenkins는 msbuild가 실행되기 전에 버전 번호를 수동으로 업데이트합니다.

dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }
dir **/Properties/AssemblyInfo.cs | %{ (cat $_) | %{$_ -replace '^(\s*)\[assembly: AssemblyFileVersion\("(.*)\.\*"\)', "`$1[assembly: AssemblyFileVersion(`"`$2.$build`")"} | Out-File $_ -Encoding "UTF8" }

-Encoding "UTF8"옵션을 추가했습니다. git이 .cs 파일을 그렇지 않은 경우 바이너리 파일로 취급하기 시작했기 때문입니다. 물론, 실제로 결과를 커밋하지 않았기 때문에 이것은 중요하지 않았습니다. 내가 테스트하는 동안 나왔다.

우리의 CI 환경에는 이미 Jenkins 빌드를 특정 git 커밋과 연결하는 기능이 있으므로 (Stash 플러그인에 감사드립니다!) 버전 번호가 첨부 된 git 커밋이 없어도 걱정하지 않습니다.


이것은 더 간단한 메커니즘입니다. MSBuild 단계 이전에 Windows Batch 명령 작업 빌드 단계를 추가하고 FART (단순 찾기 및 바꾸기 프로그램)를 사용하면됩니다.

배치 단계

fart --svn -r AssemblyInfo.cs "[assembly: AssemblyVersion(\"1.0.0.0\")]" "[assembly: AssemblyVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
fart --svn -r AssemblyInfo.cs "[assembly: AssemblyFileVersion(\"1.0.0.0\")]" "[assembly: AssemblyFileVersion(\"1.0.%BUILD_NUMBER%.%SVN_REVISION%\")]"
if %ERRORLEVEL%==0 exit /b 1
exit /b 0

svn 이외의 소스 제어를 사용하는 경우 scm 환경에 적합한 옵션으로 --svn 옵션을 변경하십시오.

방귀 다운로드


Prebuild Powershell 스크립트 ( https://gist.github.com/bradjolicoeur/e77c508089aea6614af3 ) 를 사용하여 두 가지 방법을 사용하여 Global.asax에서 각 성공적인 빌드를 증가 시키기로 결정했습니다 .

  // We are using debug configuration, so increment our builds.
  if (System.Diagnostics.Debugger.IsAttached)
  {
      string version = System.Reflection.Assembly.GetExecutingAssembly()
                                                       .GetName()
                                                       .Version
                                                       .ToString();

      var psi = new ProcessStartInfo(@"svn", "commit -m \"Version: " + version + "\n \"");
      psi.WorkingDirectory = @"C:\CI\Projects\myproject";
      Process.Start(psi); 
  }

나는 여전히 전체 프로세스가 너무 복잡하다고 생각하며 동일한 결과를 달성하는 더 효율적인 방법을 조사 할 것입니다. 나는 주로 버전을 SVN으로 전달한 다음 너무 많은 추가 도구없이 Jenkin에 전달하기 위해 이것을 원했습니다.

참고 URL : https://stackoverflow.com/questions/1126880/how-can-i-auto-increment-the-c-sharp-assembly-version-via-our-ci-platform-hudso

반응형