Java 프로젝트용 빌드 및 버전 번호 부여(ant, cvs, hudson)
Java 프로젝트에서 체계적인 빌드 번호 부여 및 버전 번호 관리를 위한 현재 모범 사례는 무엇입니까?구체적으로는:
분산 개발 환경에서 빌드 번호를 체계적으로 관리하는 방법
소스 또는 런타임 응용 프로그램에서 사용 가능한 버전 번호를 유지하는 방법
소스 저장소와의 적절한 통합 방법
버전 번호와 저장소 태그를 보다 자동으로 관리하는 방법
지속적인 구축 인프라스트럭처와의 통합 방법
사용할 수 있는 툴은 매우 많은데, 개미(당사가 사용하는 빌드 시스템)는 빌드 번호를 유지하는 태스크를 가지고 있지만 CVS, svn 등을 사용하여 여러 개발자를 동시에 사용하여 이를 관리하는 방법은 명확하지 않습니다.
[편집]
아래에 몇 가지 유용한 부분적 또는 구체적인 답변이 나와 있으므로 그 중 몇 가지를 요약해 보겠습니다.여기에는 실제로 강력한 "베스트 프랙티스"가 없는 것처럼 들리고, 오히려 중복되는 아이디어의 집합체라고 할 수 있습니다.아래에서는 사람들이 후속 조치로 대답할 수 있는 제 요약과 그에 따른 질문을 찾아보세요.[스택오버플로우 신규...]제가 잘못하고 있다면 댓글을 달아주세요.]
SVN을 사용하는 경우 탑승 시 특정 체크아웃 버전이 제공됩니다.빌드 번호는 이를 이용하여 특정 체크아웃/리비전을 식별하는 고유한 빌드 번호를 생성할 수 있습니다.[기존의 이유로 사용되고 있는 CVS는 이 정도의 통찰력은 제공하지 않습니다.태그에 의한 수동 조작으로 실현됩니다.]
maven을 빌드시스템으로 사용하는 경우 SCM에서 버전 번호 생성과 릴리즈 자동 생성용 릴리스 모듈이 지원됩니다.[다양한 이유로 메이븐을 사용할 수 없지만 사용할 수 있는 사람에게 도움이 됩니다.[마셀로 모랄레스 덕분]
ant를 빌드 시스템으로 사용하는 경우 다음 작업 설명은 빌드 정보를 캡처하는 Java .properties 파일을 생성하는 데 도움이 될 수 있습니다. 이 파일은 여러 가지 방법으로 빌드에 접을 수 있습니다.[고맙게도 이 아이디어를 허드슨에서 파생된 정보를 포함하도록 확장했습니다.]
앤트와 메이븐(및 허드슨과 크루즈 컨트롤)은 빌드 번호를 .properties 파일 또는 .txt/.html 파일로 쉽게 가져올 수 있습니다.의도적 또는 우발적으로 조작되는 것을 막을 수 있을 정도로 안전한가?빌드 시 "버전" 클래스로 컴파일하는 것이 좋습니까?
어설션:빌드 번호는 허드슨과 같은 연속적인 통합 시스템에서 정의/실현해야 합니다.[marcelo-morales 덕분에]이 제안을 받아들였습니다만, 릴리스 엔지니어링에 관한 의문이 풀렸습니다.릴리스는 어떻게 이루어집니까?하나의 릴리스에 여러 빌드 번호가 있습니까?서로 다른 릴리스의 빌드 번호 사이에 의미 있는 관계가 있습니까?
질문:.빌드 번호의 목적은 무엇입니까?QA에 사용됩니까? 어떻게 사용합니까?개발자가 개발 중에 여러 빌드를 명확히 하기 위해 주로 사용합니까? 아니면 QA가 최종 사용자가 어떤 빌드를 얻었는지 결정하기 위해 더 많이 사용합니까?재현성이 목표인 경우, 이론적으로는 릴리스 버전 번호가 제공하는 것입니다.왜 안 되는가?(아래의 답변의 일부로서 답변해 주십시오.이것에 의해, 지금까지의 선택/제안한 내용이 밝혀집니다).
질문:.수동 빌드에는 빌드 번호를 사용할 수 있는 장소가 있습니까?모든 사람이 CI 솔루션을 사용해야 할 정도로 문제가 많은가요?
질문:.빌드 번호를 SCM에 체크인해야 합니까?특정 빌드를 확실하고 명확하게 특정하는 것이 목표인 경우, 크래시/재기동할 가능성이 있는 다양한 연속 빌드 또는 수동 빌드 시스템에 대처하는 방법...
질문:.빌드 번호가 짧고 단조로운(즉, 정수가 단조롭게 증가하는 등) 아카이브를 위해 파일 이름을 쉽게 사용하거나 통신에서 참조할 수 있도록 하는 경우또는 사용자 이름, 데이터 스탬프, 머신 이름 등으로 길고 꽉 차야 합니다.
질문: 빌드 번호 할당이 대규모 자동 릴리스 프로세스에 어떻게 적합한지 자세히 알려 주십시오.그래, 사랑하는 사람들, 우린 이미 끝난 일이라는 걸 알지만, 우리 모두가 아직 쿨에이드를 마셔본 건 아니야...
적어도 cvs/ant/hudson 설정의 구체적인 예에 대해서는 이 질문을 바탕으로 완전한 전략을 구축할 수 있도록 이 답변을 구체화하고 싶습니다.이 특정 케이스에 대한 자세한 설명을 할 수 있는 모든 사용자(cvs 태그 지정 방식, 관련 CI 구성 항목 및 빌드 번호를 프로그래밍 방식으로 액세스할 수 있도록 릴리스에 접는 릴리스 절차 포함)는 "The Answer"로 표시합니다.다른 설정(예를 들어 svn/maven/cruise control)에 대해 질문/답변을 원하는 경우 여기에서 질문으로 링크합니다. --JA
[편집 23일 09년 10월 23일]가장 많이 투표된 답변은 합리적인 해결책이라고 생각하기 때문에 받아들였습니다.다른 답변에는 좋은 아이디어가 포함되어 있습니다.마티 램과 합성하고 싶은 사람이 있다면 다른 것을 받아들이는 것을 검토해 보겠습니다.marty-lamb의 유일한 관심사는 신뢰성 있는 시리얼화된 빌드 번호가 생성되지 않는다는 것입니다.빌더 시스템의 로컬 클럭에 따라 명확한 빌드 번호가 제공되는데, 이는 그다지 좋은 일이 아닙니다.
[7월 10일 편집]
현재는 다음과 같은 클래스가 포함되어 있습니다.이를 통해 버전 번호를 최종 실행 파일로 컴파일할 수 있습니다.로그 데이터, 장기간 아카이브된 출력 제품에서는 다양한 형식의 버전 정보가 출력되며 출력 제품에 대한 분석을 특정 빌드로 추적하는 데 사용됩니다.
public final class AppVersion
{
// SVN should fill this out with the latest tag when it's checked out.
private static final String APP_SVNURL_RAW =
"$HeadURL: svn+ssh://user@host/svnroot/app/trunk/src/AppVersion.java $";
private static final String APP_SVN_REVISION_RAW = "$Revision: 325 $";
private static final Pattern SVNBRANCH_PAT =
Pattern.compile("(branches|trunk|releases)\\/([\\w\\.\\-]+)\\/.*");
private static final String APP_SVNTAIL =
APP_SVNURL_RAW.replaceFirst(".*\\/svnroot\\/app\\/", "");
private static final String APP_BRANCHTAG;
private static final String APP_BRANCHTAG_NAME;
private static final String APP_SVNREVISION =
APP_SVN_REVISION_RAW.replaceAll("\\$Revision:\\s*","").replaceAll("\\s*\\$", "");
static {
Matcher m = SVNBRANCH_PAT.matcher(APP_SVNTAIL);
if (!m.matches()) {
APP_BRANCHTAG = "[Broken SVN Info]";
APP_BRANCHTAG_NAME = "[Broken SVN Info]";
} else {
APP_BRANCHTAG = m.group(1);
if (APP_BRANCHTAG.equals("trunk")) {
// this isn't necessary in this SO example, but it
// is since we don't call it trunk in the real case
APP_BRANCHTAG_NAME = "trunk";
} else {
APP_BRANCHTAG_NAME = m.group(2);
}
}
}
public static String tagOrBranchName()
{ return APP_BRANCHTAG_NAME; }
/** Answers a formatter String descriptor for the app version.
* @return version string */
public static String longStringVersion()
{ return "app "+tagOrBranchName()+" ("+
tagOrBranchName()+", svn revision="+svnRevision()+")"; }
public static String shortStringVersion()
{ return tagOrBranchName(); }
public static String svnVersion()
{ return APP_SVNURL_RAW; }
public static String svnRevision()
{ return APP_SVNREVISION; }
public static String svnBranchId()
{ return APP_BRANCHTAG + "/" + APP_BRANCHTAG_NAME; }
public static final String banner()
{
StringBuilder sb = new StringBuilder();
sb.append("\n----------------------------------------------------------------");
sb.append("\nApplication -- ");
sb.append(longStringVersion());
sb.append("\n----------------------------------------------------------------\n");
return sb.toString();
}
}
이것이 위키 토론이 될 자격이 있다면 댓글을 남겨주세요.
프로젝트 중 몇 가지에서는 서브버전 리비전 번호, 시간, 빌드를 실행한 사용자 및 시스템 정보를 캡처하여 응용 프로그램 jar에 포함된 .properties 파일에 저장하고 실행 시 해당 jar를 읽습니다.
개미 코드는 다음과 같습니다.
<!-- software revision number -->
<property name="version" value="1.23"/>
<target name="buildinfo">
<tstamp>
<format property="builtat" pattern="MM/dd/yyyy hh:mm aa" timezone="America/New_York"/>
</tstamp>
<exec executable="svnversion" outputproperty="svnversion"/>
<exec executable="whoami" outputproperty="whoami"/>
<exec executable="uname" outputproperty="buildsystem"><arg value="-a"/></exec>
<propertyfile file="path/to/project.properties"
comment="This file is automatically generated - DO NOT EDIT">
<entry key="buildtime" value="${builtat}"/>
<entry key="build" value="${svnversion}"/>
<entry key="builder" value="${whoami}"/>
<entry key="version" value="${version}"/>
<entry key="system" value="${buildsystem}"/>
</propertyfile>
</target>
추가할 수 있는 모든 정보를 포함하도록 확장하면 됩니다.
사용자의 build.xml
...
<property name="version" value="1.0"/>
...
<target name="jar" depends="compile">
<buildnumber file="build.num"/>
<manifest file="MANIFEST.MF">
...
<attribute name="Main-Class" value="MyClass"/>
<attribute name="Implementation-Version" value="${version}.${build.number}"/>
...
</manifest>
</target>
...
자바 코드
String ver = MyClass.class.getPackage().getImplementationVersion();
- 빌드 번호는 허드슨 등의 연속적인 통합 서버에 관련지어야 합니다.지점/팀/배포마다 다른 작업을 사용합니다.
- 최종 빌드에서 버전 번호를 유지하려면 빌드 시스템에 maven만 사용하는 것이 좋습니다.그러면 마지막 .jar/.war/.war/.wall-ar에 아카이브된 .properties 파일이 생성됩니다.
META-INF/maven/<project group>/<project id>/pom.properties
됩니다.성질 - maven을 추천하기 때문에 릴리스 플러그인을 체크하여 소스 저장소에 릴리스를 준비하고 버전을 동기화해 둘 것을 권장합니다.
소프트웨어:
- SVN
- 개미.
- 허드슨, 지속적인 통합을 위해
- svntask, SVN 리비전을 검색하기 위한 Ant 태스크:http://code.google.com/p/svntask/
허드슨에는 세 가지 빌드/작업이 있습니다.Continuous, Nightly 및 Release.
연속/야간 빌드의 경우:빌드 번호는 SVN 리비전으로, svntask를 사용하여 검색됩니다.
릴리스 빌드/작업의 경우: 빌드 번호는 속성 파일에서 읽어낸 릴리스 번호입니다.또한 런타임에 빌드 번호를 표시하기 위해 릴리스와 함께 속성 파일을 배포할 수도 있습니다.
개미 빌드 스크립트는 빌드 중에 생성된 jar/war 파일의 매니페스트 파일에 빌드 번호를 넣습니다.모든 빌드에 적용됩니다.
릴리스 빌드에 대한 빌드 후 액션.Hudson 플러그인을 사용하여 쉽게 실행할 수 있습니다.SVN에 빌드 번호를 태그 붙입니다.
이점:
- 개발 버전의 jar/war의 경우 개발자는 jar/war에서 SVN 리비전을 찾아 SVN에서 해당 코드를 조회할 수 있습니다.
- 릴리스의 경우 SVN 리비전은 릴리스 번호가 있는 SVN 태그에 대응하는 리비전입니다.
이게 도움이 됐으면 좋겠다.
허드슨도 사용하고 있습니다만, 보다 간단한 시나리오입니다.
내 개미 스크립트에는 다음과 같은 타겟이 있습니다.
<target name="build-number">
<property environment="env" />
<echo append="false" file="${build.dir}/build-number.txt">Build: ${env.BUILD_TAG}, Id: ${env.BUILD_ID}, URL: ${env.HUDSON_URL}</echo>
</target>
허드슨은 내 일이 실행될 때마다 이런 환경변수를 설정해준다.
이 이고, 이 프로젝트에는 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 프로젝트, 이 세 가지가 되어 있습니다.build-number.txt
의 루트 - 누가.webapp은 - file file file file file file of of of of of of file file file file file - file file file file file file 。
빌드 성공 시 빌드 번호/타임 스탬프로 태그 지정하도록 허드슨 작업이 이미 설정되어 있기 때문에 이 작업이 완료될 때 소스 컨트롤에 태그를 붙이지 않습니다.
제 솔루션은 개발을 위한 증분 빌드 수만을 커버하고 있으며, 릴리즈 수를 커버하고 있는 프로젝트에서는 아직 충분한 성과를 거두지 못했습니다.
또한 http://code.google.com/p/codebistro/wiki/BuildNumber에 있는 하나의 jar에 있는 BuildNumber Maven 플러그인 및 Ant 태스크도 볼 수 있습니다.나는 그것을 단순하고 직설적으로 하려고 노력했다.설치된 명령줄 Subversion에만 의존하는 매우 작은 jar 파일입니다.
이렇게 해결했습니다.
- 소스가 빌드 디렉토리에 복사됩니다.
- anttask "versioninfo" 가 적용됩니다.
- 수정된 출처를 정리하다
다음은 버전 정보를 저장하는 Java 파일입니다.
public class Settings {
public static final String VERSION = "$VERSION$";
public static final String DATE = "$DATE$";
}
anttask "versioninfo"는 다음과 같습니다.
<!-- =================================
target: versioninfo
================================= -->
<target name="versioninfo"
depends="init"
description="gets version info from svn"
>
<!--
get svn info from the src folder
-->
<typedef resource="org/tigris/subversion/svnant/svnantlib.xml"
classpathref="ant.classpath"
/>
<svnSetting id="svn.setting"
javahl="false"
svnkit="true"
dateformatter="dd.MM.yyyy"
/>
<svn refid="svn.setting">
<info target="src" />
</svn>
<!--
if repository is a taged version use "v <tagname>"
else "rev <revisionnumber> (SVN)" as versionnumber
-->
<taskdef resource="net/sf/antcontrib/antcontrib.properties"
classpathref="ant.classpath"
/>
<propertyregex property="version"
input="${svn.info.url}"
regexp=".*/tags/(.*)/${ant.project.name}/src"
select="v \1"
defaultvalue="rev ${svn.info.lastRev} (SVN)"
override="true"
/>
<!--
replace date and version in the versionfile ()
-->
<replace file="build/${versionfile}">
<replacefilter token="$DATE$" value="${svn.info.lastDate}" />
<replacefilter token="$VERSION$" value="${version}" />
</replace>
</target>
여기 2센트 있습니다.
빌드 스크립트는 앱을 빌드할 때마다 빌드 번호(타임스탬프 포함!)를 생성합니다.이로 인해 너무 많은 수가 생성되지만 결코 너무 적은 수는 생성되지 않습니다.코드가 변경되면 빌드 번호가 한 번 이상 변경됩니다.
모든 릴리스에 따라 빌드 번호를 버전화합니다(단, 그 사이는 아님).프로젝트를 업데이트하고 새 빌드 번호를 받으면(다른 사용자가 릴리스를 했기 때문에), 로컬 버전을 덮어쓰고 다시 시작합니다.이로 인해 빌드 번호가 낮아질 수 있기 때문에 타임스탬프를 포함했습니다.
릴리스가 발생하면 빌드 번호는 "build 1547" 메시지와 함께 단일 커밋의 마지막 항목으로 커밋됩니다.그 후 정식 발매가 되면 트리 전체에 태그가 붙습니다.이렇게 하면 빌드 파일에는 항상 모든 태그가 있으며 태그와 빌드 번호 간에 간단한 1:1 매핑이 있습니다.
[편집] 프로젝트와 함께 version.html을 전개하고 스크레이퍼를 사용하여 어디에 설치되어 있는지 정확한 지도를 수집할 수 있습니다.Tomcat 등을 사용하는 경우 빌드 번호와 타임스탬프를description
web.xml 요소주의:컴퓨터가 대신 할 수 있는 일은 절대 외우지 마세요.
NAT은 크루즈컨트롤(여기에 마음에 드는 빌드 관리자 삽입)을 통해 빌드를 실행하고 기본 빌드 및 테스트를 수행합니다.
그런 다음 Ant와 BuildNumber를 사용하여 버전 번호를 증가시키고 이 정보와 빌드 날짜 및 기타 메타데이터가 포함된 속성 파일을 만듭니다.
이를 읽고 GUI/로그 등에 제공하는 전용 클래스가 있습니다.
그런 다음 이 모든 것을 패키징하고 빌드 번호와 해당 빌드를 연결하는 배포 가능 파일을 구축합니다.모든 서버가 시작 시 이 메타 정보를 버립니다.크루즈 컨트롤 로그로 돌아가서 빌드 번호를 날짜 및 체크인에 연결할 수 있습니다.
언급URL : https://stackoverflow.com/questions/690419/build-and-version-numbering-for-java-projects-ant-cvs-hudson
'programing' 카테고리의 다른 글
다른 웹 페이지로 리디렉션하려면 어떻게 해야 합니까? (0) | 2023.01.12 |
---|---|
내림차순으로 주문하시겠습니까? (0) | 2023.01.12 |
Django ModelAdmin의 list_display는 ForeignKey 필드의 속성을 표시할 수 있습니까? (0) | 2023.01.12 |
MySQL 대소문자를 구분하는 쿼리 (0) | 2023.01.12 |
자동 증가가 mysql에서 생성할 수 있는 가장 큰 ID 번호는 무엇입니까? (0) | 2023.01.12 |