어셈블리 버전 번호를 유지하기위한 모범 사례 / 지침


154

.NET 어셈블리에 대한 세 가지 어셈블리 버전 번호를 관리하는 방법에 대한 포인터, 제안 및 지시 사항을 찾고 있습니다. 일반적으로 비즈니스에서 지시하는 것처럼 제품 버전이 가장 단순합니다. 그런 다음 파일 버전은 배포 간 버전 관리를위한 것으로 보이며, 실제 어셈블리 버전은 배송시에만 사용됩니다.

지금은 어셈블리의 테스트 및 유지 보수 릴리스에 레이블을 지정하는 간단한 방법을 찾고 있으므로 파일 버전에서 빌드 및 개정 번호를 자동 증가시키고 최종 릴리스를 위해 현재 버전을 복사합니다. 조립품 버전에 파일 버전. 이 제품은 프로덕션 환경에서 사용 중이지만 여전히 소규모 기업 중 하나이며 변경 제어 인프라 상황이없는 개발 중입니다.


1
이것을 확인하십시오 ... codinghorror.com/blog/2007/02/…
Rahul Soni

답변:


211

버전 관리는 매우 열정적이며 사용하기 쉬운 버전 관리 시스템을 고안하는 데 오랜 시간을 소비 한 것입니다. 귀하의 질문에서 이미 말한 바에 따르면 한 가지 중요한 점을 이해 했으므로 어셈블리 버전 번호는 제품 버전과 동의어가 아닙니다. 하나는 기술적으로 주도되고 다른 하나는 비즈니스에 의해 주도됩니다.

다음은 어떤 형태의 소스 제어 및 빌드 서버를 사용한다고 가정합니다. 맥락에서 우리는 TeamCity 와 Subversion / Git을 사용합니다. TeamCity는 적은 수의 프로젝트에 대해 무료이며 매우 훌륭한 빌드 서버이지만 일부는 완전히 무료입니다.

버전 번호의 의미

한 사람에게 어떤 버전이 의미하는 것은 다른 사람과 다른 것을 의미 할 수 있습니다. 일반적인 구조는 주, 사소, 거시, 미시입니다. 내가 버전 번호를 보는 방법은 두 부분으로 나누는 것입니다. 전반부는 주 버전 (주요)과 주요 업데이트 (부)를 설명합니다. 후반은 언제 빌드되었으며 소스 코드 버전은 무엇인지 나타냅니다. 버전 번호는 컨텍스트에 따라 다른 의미를 가지며 API, 웹 앱 등입니다.

Major. Minor. Build.Revision

  • Revision 이것은 실제로 만들어진 것을 식별하기 위해 소스 컨트롤에서 가져온 숫자입니다.
  • Build빌드 서버에서 특정 빌드를 찾는 데 사용할 수있는 숫자가 계속 증가하고 있습니다. 빌드 서버가 다른 매개 변수 세트로 동일한 소스를 두 번 빌드했을 수 있으므로 중요한 수입니다. 소스 번호와 함께 빌드 번호를 사용하면 빌드 된 내용과 방법을 식별 할 수 있습니다.
  • Minor공용 인터페이스가 크게 변경된 경우에만 변경해야합니다. 예를 들어 API 인 경우 소비 코드가 여전히 컴파일 될 수 있습니까? 주 번호가 변경되면이 숫자를 0으로 재설정해야합니다.
  • Major사용중인 제품의 버전을 나타냅니다. 예를 들어 모든 VisualStudio 2008 어셈블리의 Major는 9이고 VisualStudio 2010은 10입니다.

규칙의 예외

규칙에는 항상 예외가 있으며 규칙에 따라 적응해야합니다. 내 원래 접근 방식은 subversion을 사용하는 것이었지만 최근에는 Git으로 옮겼습니다. 중앙 저장소를 사용하는 서브 버전 및 소스 세이프와 같은 소스 제어에는 지정된 시간에서 특정 소스 세트를 식별하는 데 사용할 수있는 번호가 있습니다. Git과 같은 분산 소스 제어의 경우에는 해당되지 않습니다. Git은 각 개발 시스템에있는 분산 리포지토리를 사용하기 때문에 사용할 수있는 자동 증분 번호가 없으므로 체크인 횟수를 사용하는 해킹이 있지만 추악합니다. 이 때문에 접근 방식을 발전시켜야했습니다.

Major. Minor. Macro.Build

수정본 번호가 사라지고 빌드가 수정본 위치로 이동했으며 매크로가 삽입되었습니다. 당신은 당신이 맞는 것처럼 보이는 매크로를 사용할 수 있지만 대부분 혼자 남겨 둡니다. TeamCity를 사용하기 때문에 개정 번호에서 잃어버린 정보를 빌드에서 찾을 수 있습니다. 이는 2 단계 프로세스가 있지만 아무 것도 잃지 않았으며 수용 가능한 타협입니다.

무엇을 설정

가장 먼저 이해해야 할 것은 어셈블리 버전, 파일 버전 및 제품 버전이 일치하지 않아도된다는 것입니다. 다른 숫자 세트를 사용하는 것을 옹호하지는 않지만 종속 어셈블리를 다시 컴파일하지 않아도되는 공용 인터페이스에 영향을 미치지 않는 어셈블리를 약간 변경하면 인생을 훨씬 쉽게 만듭니다. 이 문제를 해결하는 방법은 어셈블리 버전에서 메이저 및 마이너 번호 만 설정하고 파일 버전에서 모든 값을 설정하는 것입니다. 예를 들면 다음과 같습니다.

  • 1.2.0.0 (어셈블리 버전)
  • 1.2.3.4 (파일 버전)

이렇게하면 어셈블리 버전이 일치하지 않지만 파일 버전 번호를보고 어셈블리의 개정 / 빌드를 볼 수 있으므로 기존 코드를 위반하지 않는 핫픽스를 롤아웃 할 수 있습니다. 이것은 일반적인 접근 방식이며 어셈블리 세부 사항을 볼 때 일부 오픈 소스 어셈블리에서 볼 수 있습니다.

팀 리더로서 중요한 변경이 필요할 때 부수를 늘릴 책임이 있습니다. 인터페이스에 필요한 변경을 롤아웃하지만 이전 코드를 위반하지 않는 한 가지 솔루션은 현재 코드를 사용하지 않는 것으로 표시하고 새 인터페이스를 작성하는 것입니다. 즉, 기존 코드에는 메소드가 더 이상 사용되지 않으며 언제든지 제거 할 수 있지만 모든 것을 즉시 중단 할 필요는 없다는 경고가 표시됩니다. 그런 다음 모든 것이 마이그레이션되었을 때 사용되지 않는 방법을 제거 할 수 있습니다.

함께 배선하는 방법

위의 모든 작업을 수동으로 수행 할 수 있지만 시간이 많이 걸리므로 다음은 프로세스를 자동화하는 방법입니다. 각 단계는 실행 가능합니다.

  • 모든 프로젝트 AssemblyInfo.cs 파일에서 AssemblyVersionAssemblyFileVersion속성을 제거하십시오 .
  • 공통 어셈블리 정보 파일 (VersionInfo.cs)을 만들어 모든 프로젝트에 링크 된 항목으로 추가하십시오.
  • 추가 AssemblyVersionAssemblyFileVersion"0.0.0.0"의 값으로 버전 속성.
  • 솔루션 파일을 빌드하는 MsBuild 프로젝트를 작성하십시오.
  • VersionInfo.cs를 업데이트하는 빌드 전에 작업을 추가하십시오. 버전 번호를 설정할 수있는 AssemblyInfo 태스크를 포함하는 다수의 오픈 소스 MsBuild 라이브러리가 있습니다. 임의의 숫자로 설정하고 테스트하십시오.
  • 빌드 번호의 각 세그먼트에 대한 특성을 포함하는 특성 그룹을 추가하십시오. 이곳에서 전공과 부전공을 설정합니다. 빌드 및 개정 번호는 인수로 전달해야합니다.

Subversion으로 :

<PropertyGroup>
    <Version-Major>0</Version-Major>
    <Version-Minor>0</Version-Minor>
    <Version-Build Condition=" '$(build_number)' == '' ">0</Version-Build>
    <Version-Build Condition=" '$(build_number)' != '' ">$(build_number)</Version-Build>
    <Version-Revision Condition=" '$(revision_number)' == '' ">0</Version-Revision>
    <Version-Revision Condition=" '$(revision_number)' != '' ">$(revision_number)</Version-Revision>
</PropertyGroup>

잘만되면 나는 분명했다. 그러나 많은 관련이있다. 질문하십시오. 더 간단한 블로그 게시물을 작성하기 위해 피드백을 사용하겠습니다.


GitHub의 버전 태그 사용을 고려 했습니까? 나는 그것이 퍼즐에 어떻게 맞는지 궁금하다.
raRaRa

1
@raRaRa-이것은 꽤 오래된 게시물입니다. 그것의 대부분은 여전히 ​​대기하지만 내가 다르게 할 것들이 있습니다. NuGet 버전 관리는 작업 방식을 변경했으며 성공적인 빌드를 위해 Git 태그를 사용하지만 하루가 끝나면 어셈블리의 버전 번호는 빌드 서버의 빌드 버전과 소스 제어의 태그 버전과 다시 연결되어야합니다.
Bronumski

57

[AssemblyVersion]은 .NET에서 매우 중요합니다. Microsoft가 권장하는 한 가지 철학 은 어셈블리에 의존하는 모든 프로젝트를 다시 컴파일해야한다는 점을 자동 증분 시키는 것입니다. 빌드 서버를 사용하면 정상적으로 작동합니다. 결코 잘못 할 수 있지만 칼을 들고 사람을 조심하는 것.

실제 의미와 더 밀접하게 관련된 다른 하나는이 숫자가 어셈블리의 공용 인터페이스 버전을 나타내는 것입니다. 즉, 공용 인터페이스 또는 클래스를 변경할 때만 변경합니다. 이러한 변경만으로도 어셈블리 클라이언트를 다시 컴파일해야합니다. 이 작업은 수동으로 수행해야하지만 빌드 시스템은 그러한 변경을 자동 감지하기에 충분하지 않습니다.

접근 할 수없는 시스템에 어셈블리를 배치 할 때만 버전을 증가시켜이 접근 방식을 추가로 확장 할 수 있습니다. 이것은 Microsoft가 사용하는 접근 방식이며 .NET 어셈블리 버전 번호는 거의 변경되지 않습니다. 대부분 고객에게 큰 고통이 있기 때문입니다.

따라서 Microsoft가 설교하는 것은 그것이 실천하는 것이 아닙니다. 그러나 빌드 프로세스 및 버전 관리는 독보적이며 프로세스를 모니터링하는 전용 소프트웨어 엔지니어도 있습니다. 잘 해결되지 않은 WaitHandle.WaitOne (int) 과부하는 특히 상당한 고통을 유발했습니다 . 매우 다른 접근 방식으로 .NET 4.0에서 수정되었지만 범위를 약간 벗어났습니다.

빌드 프로세스와 릴리스주기를 얼마나 잘 제어하여 자신이 선택할 수 있는지에 대한 확신은 전적으로 귀하와 귀하의 신뢰입니다. 그 외에는 [AssemblyFileVersion]을 자동으로 자동 증분하는 것이 매우 적합합니다. 그러나 이것이 지원 되지 않는 불편 함이 있습니다.


11

자동 증가를 위해 버전 번호의 빌드 부분을 사용할 수 있습니다.

[assembly: AssemblyVersion("1.0.*")]

사용자 환경에서 테스트 버전은 빌드 버전이! = 0 인 버전입니다. 릴리스시 마이너 파트를 증가시키고 빌드 파트를 0으로 설정하면 릴리스 된 어셈블리를 식별 할 수 있습니다.

GAC에 어셈블리를 설치하면 GAC에 시간이 지남에 따라 많은 다른 버전이 넘치므로 명심하십시오. 그러나 dll을 로컬에서만 사용하는 경우 이것이 좋은 습관이라고 생각합니다.


릴리스 버전의 빌드 번호 0이 마음에 듭니다.
ProfK

1
물론 이것은 어셈블리의 강력한 이름이 원하는 경우에 관계없이 각 빌드마다 변경됨을 의미합니다.
Richard

9

에 추가 Bronumskis 응답 , I은 시맨틱 버전 2.0 표준 후에 지적 할 semver.org , Major.Minor.Build.Revision인해 수를 증가 후, 오른쪽에있는 모든 일반 값이 0으로 재설정을해야한다고 규칙에 불법 것입니다.

표준을 따르는 더 좋은 방법은을 사용하는 것 Major.Minor+Build.Revision입니다. 이것은에 사용하기위한 AssemblyVersionAttribute것이 아니지만 사용자 정의 속성 또는 정적 클래스를 대신 사용할 수 있습니다.

TeamCity의 Semver는 Meta-runner Power Pack을 사용하여 사용할 수 있어야합니다. git-flow (특히 .NET 세계)가있는 git의 경우 GitVersion 이 도움이되는 것으로 나타 났습니다 .


2
흥미 롭습니다. 확인해 보겠습니다. 언급 한 버전 번호 형식은 AssemblyInformationalVersion 속성에 사용될 수 있습니다.
Bronumski

1

버전 관리 어셈블리에 관해서는 단단하고 빠른 규칙이 없으므로 어느 쪽이든 효과가있는 것을 자유롭게 사용해보십시오. 그러나 변경하려는 경우 유연성을 가지므로 4 가지 부품 접근 방식을 사용하는 것이 좋습니다. 앞으로.

... 예 : 1.0.0. *

예약 됨-나중에 변경하려는 경우 유연성을 추가합니다. 그러나 기본값으로 0으로 유지하십시오.

또한 강력한 키로 어셈블리에 서명하는 것을 고려하십시오. 이렇게하면 GAC에 여러 버전의 어셈블리가 등록 된 경우 어셈블리 충돌 문제가 해결됩니다. MSDN 링크

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.