μΉ΄ν…Œκ³ λ¦¬ 보관물: Java

Java

Java ν”„λ‘œμ νŠΈ (ant, cvs, hudson)의 λΉŒλ“œ 및 버전 번호 λ§€κΈ°κΈ° λͺ©ν‘œλΌλ©΄ 이둠적으둜 이것은 릴리슀 버전 λ²ˆν˜Έκ°€ μ œκ³΅ν•΄μ•Όν•˜λŠ”

Java ν”„λ‘œμ νŠΈμ—μ„œ 체계적인 λΉŒλ“œ 번호 λ§€κΈ°κΈ° 및 버전 번호 관리에 λŒ€ν•œ ν˜„μž¬ λͺ¨λ²” μ‚¬λ‘€λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? ꡬ체적으둜 νŠΉλ³„νžˆ:

  • λΆ„μ‚° 개발 ν™˜κ²½μ—μ„œ λΉŒλ“œ 번호λ₯Ό μ²΄κ³„μ μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” 방법

  • μ†ŒμŠ€μ—μ„œ 버전 번호λ₯Ό μœ μ§€ λ³΄μˆ˜ν•˜λŠ” 방법 / λŸ°νƒ€μž„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ‚¬μš© κ°€λŠ₯ν•œ 방법

  • μ†ŒμŠ€ 리포지토리와 μ˜¬λ°”λ₯΄κ²Œ ν†΅ν•©ν•˜λŠ” 방법

  • 버전 λ²ˆν˜Έμ™€ μ €μž₯μ†Œ νƒœκ·Έλ₯Όλ³΄λ‹€ μžλ™μœΌλ‘œ κ΄€λ¦¬ν•˜λŠ” 방법

  • 지속적인 λΉŒλ“œ 인프라와 ν†΅ν•©ν•˜λŠ” 방법

μ‚¬μš© κ°€λŠ₯ν•œ λ§Žμ€ 도ꡬ가 있으며 개미 (μš°λ¦¬κ°€ μ‚¬μš©ν•˜λŠ” λΉŒλ“œ μ‹œμŠ€ν…œ)μ—λŠ” λΉŒλ“œ 번호λ₯Ό μœ μ§€ κ΄€λ¦¬ν•˜λŠ” μž‘μ—…μ΄ μžˆμ§€λ§Œ CVS, svn λ˜λŠ” 이와 μœ μ‚¬ν•œ 것을 μ‚¬μš©ν•˜μ—¬ μ—¬λŸ¬ λͺ…μ˜ λ™μ‹œ κ°œλ°œμžμ™€ ν•¨κ»˜ κ΄€λ¦¬ν•˜λŠ” 방법은 λͺ…ν™•ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .

[νŽΈμ§‘ν•˜λ‹€]

λͺ‡ κ°€μ§€ μ’‹κ³  μœ μš©ν•œ λΆ€λΆ„ λ˜λŠ” ꡬ체적인 닡변이 μ•„λž˜μ— λ‚˜μ™€ μžˆμœΌλ―€λ‘œ κ·Έ 쀑 일뢀λ₯Ό μš”μ•½ν•˜κ² μŠ΅λ‹ˆλ‹€. 이것에 λŒ€ν•œ κ°•λ ₯ν•œ β€œλͺ¨λ²” 사둀”가 μ•„λ‹ˆλΌ μ€‘λ³΅λ˜λŠ” 아이디어 λͺ¨μŒμ΄μžˆλŠ” κ²ƒμ²˜λŸΌ λ“€λ¦½λ‹ˆλ‹€. μ•„λž˜μ—μ„œ λ‚΄ μš”μ•½κ³Ό μ‚¬λžŒλ“€μ΄ 후속 쑰치둜 닡변을 μ‹œλ„ ν•  μˆ˜μžˆλŠ” λͺ‡ κ°€μ§€ 결과적인 μ§ˆλ¬Έμ„ μ°ΎμœΌμ‹­μ‹œμ˜€. [μŠ€νƒ μ˜€λ²„ν”Œλ‘œκ°€ μ²˜μŒμž…λ‹ˆλ‹€ …이 μž‘μ—…μ„ 잘λͺ»ν•˜λ©΄ μ˜κ²¬μ„ λ³΄λ‚΄μ£Όμ‹­μ‹œμ˜€.]

  • SVN을 μ‚¬μš©ν•˜λŠ” 경우 νŠΉμ • 체크 μ•„μ›ƒμ˜ 버전 관리가 μ œκ³΅λ©λ‹ˆλ‹€. λΉŒλ“œ 번호 λ§€κΈ°κΈ°λŠ”μ΄λ₯Ό μ΄μš©ν•˜μ—¬ νŠΉμ • 체크 아웃 / μˆ˜μ •μ„ μ‹λ³„ν•˜λŠ” 고유 ν•œ λΉŒλ“œ 번호λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€. [μš°λ¦¬κ°€ λ ˆκ±°μ‹œ 이유둜 μ‚¬μš©ν•˜κ³ μžˆλŠ” CVSλŠ” μ΄λŸ¬ν•œ μˆ˜μ€€μ˜ 톡찰λ ₯을 μ œκ³΅ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. νƒœκ·Έλ₯Ό μ‚¬μš©ν•˜μ—¬ μˆ˜λ™μœΌλ‘œ κ°œμž…ν•˜λ©΄ λ„μ›€μ΄λ©λ‹ˆλ‹€.]

  • maven을 λΉŒλ“œ μ‹œμŠ€ν…œμœΌλ‘œ μ‚¬μš©ν•˜λŠ” 경우 SCMμ—μ„œ 버전 번호λ₯Ό μƒμ„±ν•˜κ³  릴리슀λ₯Ό μžλ™μœΌλ‘œ μƒμ„±ν•˜κΈ°μœ„ν•œ 릴리슀 λͺ¨λ“ˆμ΄ μ§€μ›λ©λ‹ˆλ‹€. [μš°λ¦¬λŠ” μ—¬λŸ¬ κ°€μ§€ 이유둜 maven을 μ‚¬μš©ν•  수 μ—†μ§€λ§Œ 이것은 κ°€λŠ₯ν•œ μ‚¬λžŒλ“€μ—κ²Œ λ„μ›€μ΄λ©λ‹ˆλ‹€. [ 마λ₯΄μ²Όλ‘œ 사기 κ°μ‚¬ν•©λ‹ˆλ‹€ ]]

  • 당신이 μ‚¬μš©ν•˜λŠ” 경우 개미λ₯Ό λΉŒλ“œ μ‹œμŠ€ν…œμœΌλ‘œ, λ‹€μŒκ³Ό 같은 μž‘μ—… μ„€λͺ… μΊ” 도움은 μ—¬λŸ¬ κ°€μ§€ λ°©λ²•μœΌλ‘œ λΉŒλ“œλ‘œ 접을 μˆ˜μžˆλŠ” Java .properties의 파일 캑처 λΉŒλ“œ 정보λ₯Ό μƒμ‚°ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. [μš°λ¦¬λŠ” marty-lamb 덕뢄에 hudson νŒŒμƒ 정보λ₯Ό ν¬ν•¨ν•˜λ„λ‘μ΄ 아이디어λ₯Ό ν™•μž₯ν–ˆμŠ΅λ‹ˆλ‹€ ].

  • Ant 및 Maven (및 hudson 및 cruise 컨트둀)은 λΉŒλ“œ 번호λ₯Ό .properties 파일 λ˜λŠ” .txt / .html 파일둜 κ°€μ Έ μ˜€λŠ” μ‰¬μš΄ 방법을 μ œκ³΅ν•©λ‹ˆλ‹€. 이 β€œμ•ˆμ „ν•œβ€λΆ€λΆ„μ΄ μ˜λ„μ μœΌλ‘œ λ˜λŠ” μ‹€μˆ˜λ‘œ λ³€μ‘°λ˜μ§€ μ•Šλ„λ‘ν•˜κΈ°μ— μΆ©λΆ„ν•©λ‹ˆκΉŒ? λΉŒλ“œμ‹œ β€œversioningβ€ν΄λž˜μŠ€λ‘œ μ»΄νŒŒμΌν•˜λŠ” 것이 더 λ‚«μŠ΅λ‹ˆκΉŒ?

  • μ£Όμž₯ : λΉŒλ“œ λ„˜λ²„λ§μ€ hudson κ³Ό 같은 지속적인 톡합 μ‹œμŠ€ν…œμ—μ„œ μ •μ˜ / μ œμ •λ˜μ–΄μ•Όν•©λ‹ˆλ‹€ . [ marcelo-morales μ—κ²Œ κ°μ‚¬λ“œλ¦½λ‹ˆλ‹€. ] μš°λ¦¬λŠ”μ΄ μ œμ•ˆμ„ λ°›μ•˜μ§€λ§Œ, 릴리즈 μ—”μ§€λ‹ˆμ–΄λ§ μ§ˆλ¬Έμ„ κ³΅κ°œν•©λ‹ˆλ‹€ : λ¦΄λ¦¬μ¦ˆλŠ” μ–΄λ–»κ²Œ 이루어 μ§‘λ‹ˆκΉŒ? λ¦΄λ¦¬μŠ€μ— μ—¬λŸ¬ λΉŒλ“œ λ²ˆν˜Έκ°€ μžˆμŠ΅λ‹ˆκΉŒ? λ‹€λ₯Έ 릴리슀의 λΉŒλ“œ 번호 κ°„μ—λŠ” μ˜λ―ΈμžˆλŠ” 관계가 μžˆμŠ΅λ‹ˆκΉŒ?

  • 질문 : λΉŒλ“œ 번호의 λͺ©ν‘œλŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? ν’ˆμ§ˆ 관리에 μ‚¬μš©λ©λ‹ˆκΉŒ? μ–΄λ–»κ²Œ? κ°œλ°œμžκ°€ 주둜 개발 쀑에 μ—¬λŸ¬ λΉŒλ“œλ₯Ό λͺ…ν™•ν•˜κ²Œν•˜κ±°λ‚˜ QAκ°€ μ΅œμ’… μ‚¬μš©μžκ°€ 얻은 λΉŒλ“œλ₯Ό κ²°μ •ν•˜κΈ° μœ„ν•΄ 더 많이 μ‚¬μš©ν•©λ‹ˆκΉŒ? μž¬ν˜„μ„±μ΄ λͺ©ν‘œλΌλ©΄ 이둠적으둜 이것은 릴리슀 버전 λ²ˆν˜Έκ°€ μ œκ³΅ν•΄μ•Όν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. μ™œ κ·Έλ ‡μ§€ μ•ŠμŠ΅λ‹ˆκΉŒ? (μ•„λž˜ λ‹΅λ³€μ˜ μΌλΆ€λ‘œμ΄ 닡변에 λ‹΅ν•˜μ‹­μ‹œμ˜€. 선택 / μ œμ•ˆν•œ 사항을 λ°νžˆλŠ” 데 λ„μ›€μ΄λ©λ‹ˆλ‹€ …)

  • 질문 : μˆ˜λ™ λΉŒλ“œμ— λΉŒλ“œ 번호λ₯Όμœ„ν•œ μž₯μ†Œκ°€ μžˆμŠ΅λ‹ˆκΉŒ? λͺ¨λ‘κ°€ CI μ†”λ£¨μ…˜μ„ μ‚¬μš©ν•΄μ•Ό ν•  μ •λ„λ‘œ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆκΉŒ?

  • 질문 : λΉŒλ“œ 번호λ₯Ό SCM에 μ²΄ν¬μΈν•΄μ•Όν•©λ‹ˆκΉŒ? λͺ©ν‘œκ°€ ν™•μ‹€ν•˜κ³  λͺ…ν™•ν•˜κ²Œ νŠΉμ • λΉŒλ“œλ₯Ό μ‹λ³„ν•˜λŠ” 경우 좩돌 / μž¬μ‹œμž‘ λ“±μ˜ λ‹€μ–‘ν•œ 연속 λ˜λŠ” μˆ˜λ™ λΉŒλ“œ μ‹œμŠ€ν…œμ— λŒ€μ²˜ν•˜λŠ” 방법 …

  • 질문 : λΉŒλ“œ λ²ˆν˜Έκ°€ μ§§κ³  λ‹¬μ½€ν•©λ‹ˆλ‹€ (즉, 단쑰 μ¦κ°€ν•˜λŠ” μ •μˆ˜)ν•˜μ—¬ 보관을 μœ„ν•΄ 파일 이름을 μ‚¬μš©ν•˜κΈ° 쉽고 ν†΅μ‹ μ—μ„œ μ°Έμ‘°ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€. λ‚ μ§œ, 기계 이름 λ“±?

  • 질문 : λΉŒλ“œ 번호 할당이 λŒ€κ·œλͺ¨ μžλ™ 릴리슀 ν”„λ‘œμ„ΈμŠ€μ— μ–΄λ–»κ²Œ μ μš©λ˜λŠ”μ§€ μžμ„Ένžˆ μ„€λͺ…ν•˜μ‹­μ‹œμ˜€. 예, 메이븐 μ• ν˜Έκ°€λ“€, μš°λ¦¬λŠ” 이것이 μ™„λ£Œλ˜μ—ˆλ‹€λŠ” 것을 μ•Œκ³  μžˆμ§€λ§Œ, 우리 λͺ¨λ‘κ°€ 아직 μΏ¨ μ—μ΄λ“œλ₯Ό λ§ˆμ‹  것은 μ•„λ‹™λ‹ˆλ‹€ …

λ‚˜λŠ” 적어도 cvs / ant / hudson μ„€μ •μ˜ ꡬ체적인 예λ₯Ό μœ„ν•΄ 이것을 μ™„μ „ν•œ λŒ€λ‹΅μœΌλ‘œ 윑체 ν™”ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ λˆ„κ΅°κ°€μ΄ μ§ˆλ¬Έμ— κΈ°μ΄ˆν•˜μ—¬ μ™„μ „ν•œ μ „λž΅μ„ μ„ΈμšΈ 수 μžˆμŠ΅λ‹ˆλ‹€. 이 νŠΉμ • 사둀 (cvs νƒœκ·Έ μ§€μ • 체계, κ΄€λ ¨ CI ꡬ성 ν•­λͺ© 및 λΉŒλ“œ 번호λ₯Ό 릴리슀둜 μ ‘λŠ” 릴리슀 절차λ₯Ό ν¬ν•¨ν•˜μ—¬ ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ μ„€λͺ…)λ₯Ό 제곡 ν•  μˆ˜μžˆλŠ” μ‚¬λžŒμ΄λΌλ©΄ λˆ„κ΅¬λ‚˜ β€œλ‹΅λ³€β€μœΌλ‘œ ν‘œμ‹œν•˜κ² μŠ΅λ‹ˆλ‹€. λ‹€λ₯Έ νŠΉμ • ꡬ성 (예 : svn / maven / cruise control)에 λŒ€ν•΄ 질문 / λ‹΅λ³€μ„ν•˜λ €λ©΄ μ—¬κΈ°μ—μ„œ μ§ˆλ¬Έμ— μ—°κ²°ν•˜κ² μŠ΅λ‹ˆλ‹€. –JA

[νŽΈμ§‘ 10 10 μ›” 9 일] λ‚˜λŠ” 그것이 합리적인 해결책이라고 μƒκ°ν•˜κΈ° λ•Œλ¬Έμ— κ°€μž₯ μΈκΈ°μžˆλŠ” 닡변을 μˆ˜λ½ν–ˆμ§€λ§Œ λ‹€λ₯Έ 닡변듀도 쒋은 아이디어λ₯Ό ν¬ν•¨ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λˆ„κ΅°κ°€κ°€ 이듀 쀑 일뢀λ₯Ό marty-lamb κ³Ό ν•©μ„±ν•˜λŠ” 데 어렀움 을 κ²ͺκ³  μ‹Άλ‹€λ©΄ λ‹€λ₯Έ 것을 λ°›μ•„λ“€μ΄λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. 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();
  }
}

μœ„ν‚€ 토둠이 λ λ§Œν•œ 의견이 있으면 λ‚¨κ²¨μ£Όμ„Έμš”.



λ‹΅λ³€

λ‚΄ ν”„λ‘œμ νŠΈ 쀑 μΌλΆ€μ—μ„œλŠ” Subversion κ°œμ • 번호, μ‹œκ°„, λΉŒλ“œλ₯Ό μ‹€ν–‰ ν•œ μ‚¬μš©μž 및 일뢀 μ‹œμŠ€ν…œ 정보λ₯Ό μΊ‘μ²˜ν•˜μ—¬ μ‘μš© ν”„λ‘œκ·Έλž¨ 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();

λ‹΅λ³€

  • λΉŒλ“œ λ²ˆν˜ΈλŠ” hudson κ³Ό 같은 지속적인 톡합 μ„œλ²„μ™€ μ—°κ²°λ˜μ–΄μ•Όν•©λ‹ˆλ‹€ . 지점 / νŒ€ / λ°°ν¬λ§ˆλ‹€ λ‹€λ₯Έ μž‘μ—…μ„ μ‚¬μš©ν•˜μ‹­μ‹œμ˜€.
  • μ΅œμ’… λΉŒλ“œμ—μ„œ 버전 번호λ₯Ό μœ μ§€ν•˜λ €λ©΄ λΉŒλ“œ μ‹œμŠ€ν…œμ— maven 을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€ . μ΅œμ’… .jar / .war / .whatever-ar에 μ•„μΉ΄μ΄λΈŒ 된 .properties νŒŒμΌμ„ μž‘μ„±ν•©λ‹ˆλ‹€ META-INF/maven/<project group>/<project id>/pom.properties. .properties νŒŒμΌμ—λŠ” 버전 속성이 ν¬ν•¨λ©λ‹ˆλ‹€.
  • maven을 ꢌμž₯ν•˜κΈ° λ•Œλ¬Έμ— μ†ŒμŠ€ μ €μž₯μ†Œμ—μ„œ 릴리슀λ₯Ό μ€€λΉ„ν•˜κ³  버전을 동기화 μƒνƒœλ‘œ μœ μ§€ν•˜κΈ° μœ„ν•΄ 릴리슀 ν”ŒλŸ¬κ·ΈμΈ 을 ν™•μΈν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€ .

λ‹΅λ³€

μ†Œν”„νŠΈμ›¨μ–΄:

  • SVN
  • 개미
  • 지속적인 ν†΅ν•©μ„μœ„ν•œ Hudson
  • SVN κ°œμ •μ„ μ°ΎκΈ°μœ„ν•œ Ant νƒœμŠ€ν¬ 인 svntask : http://code.google.com/p/svntask/

Hudsonμ—λŠ” Continuous, Nightly 및 Release의 μ„Έ κ°€μ§€ λΉŒλ“œ / μž‘μ—…μ΄ μžˆμŠ΅λ‹ˆλ‹€.

Continuous / Nightly λΉŒλ“œμ˜ 경우 : λΉŒλ“œ λ²ˆν˜ΈλŠ” svntaskλ₯Ό μ‚¬μš©ν•˜μ—¬ 찾은 SVN κ°œμ •μž…λ‹ˆλ‹€.

릴리슀 λΉŒλ“œ / μž‘μ—… : λΉŒλ“œ λ²ˆν˜ΈλŠ” νŠΉμ„± νŒŒμΌμ—μ„œ Antκ°€ 읽은 릴리슀 λ²ˆν˜Έμž…λ‹ˆλ‹€. λŸ°νƒ€μž„μ— λΉŒλ“œ 번호λ₯Ό ν‘œμ‹œν•˜κΈ° μœ„ν•΄ λ¦΄λ¦¬μŠ€μ™€ ν•¨κ»˜ νŠΉμ„± νŒŒμΌμ„ λΆ„λ°° ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

Ant λΉŒλ“œ μŠ€ν¬λ¦½νŠΈλŠ” λΉŒλ“œ 쀑에 μž‘μ„±λœ jar / war 파일의 Manifest νŒŒμΌμ— λΉŒλ“œ 번호λ₯Ό λ„£μŠ΅λ‹ˆλ‹€. λͺ¨λ“  λΉŒλ“œμ— μ μš©λ©λ‹ˆλ‹€.

릴리슀 λΉŒλ“œμ˜ λΉŒλ“œ ν›„ 쑰치 : λΉŒλ“œ λ²ˆν˜Έκ°€μžˆλŠ” Hudson ν”ŒλŸ¬κ·ΈμΈ : νƒœκ·Έ SVN을 μ‚¬μš©ν•˜μ—¬ μ‰½κ²Œ μˆ˜ν–‰ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν˜œνƒ:

  • jar / war의 개발 λ²„μ „μ˜ 경우 κ°œλ°œμžλŠ” jar / warμ—μ„œ SVN κ°œμ •μ„ μ°Ύμ•„ SVNμ—μ„œ ν•΄λ‹Ή μ½”λ“œλ₯Ό 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 릴리슀의 경우 SVN κ°œμ •μ€ 릴리슀 λ²ˆν˜Έκ°€ 포함 된 SVN νƒœκ·Έμ— ν•΄λ‹Ήν•˜λŠ” κ°œμ •μž…λ‹ˆλ‹€.

도움이 λ˜μ—ˆκΈ°λ₯Ό λ°”λžλ‹ˆλ‹€.


λ‹΅λ³€

훨씬 κ°„λ‹¨ν•œ μ‹œλ‚˜λ¦¬μ˜€μ΄μ§€λ§Œ ν—ˆλ“œμŠ¨λ„ μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λ‚΄ Ant μŠ€ν¬λ¦½νŠΈμ—λŠ” λ‹€μŒκ³Ό 같은 λŒ€μƒμ΄ μžˆμŠ΅λ‹ˆλ‹€.

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

Hudson은 μž‘μ—…μ΄ 싀행될 λ•Œλ§ˆλ‹€ μ΄λŸ¬ν•œ ν™˜κ²½ λ³€μˆ˜λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

ν•„μžμ˜ 경우이 ν”„λ‘œμ νŠΈλŠ” webapp이며 webapp build-number.txt의 루트 폴더 에이 νŒŒμΌμ„ ν¬ν•¨μ‹œν‚€κ³  μžˆμŠ΅λ‹ˆλ‹€.

λΉŒλ“œκ°€ μ™„λ£Œλ˜λ©΄ λΉŒλ“œ 번호 / νƒ€μž„ μŠ€νƒ¬ν”„λ‘œ νƒœκ·Έλ₯Ό μ§€μ •ν•˜κΈ° μœ„ν•΄ Hudson μž‘μ—…μ΄ 이미 μ„€μ •λ˜μ–΄ μžˆμœΌλ―€λ‘œ μ†ŒμŠ€ μ»¨νŠΈλ‘€μ— νƒœκ·Έλ₯Ό μ§€μ •ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‚΄ μ†”λ£¨μ…˜μ€ κ°œλ°œμ„μœ„ν•œ 증뢄 λΉŒλ“œ 번호 만 닀루지 만 아직 릴리슀 번호λ₯Ό λ‹€λ£¨λŠ” ν”„λ‘œμ νŠΈμ—μ„œλŠ” μΆ©λΆ„νžˆ μ–»μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.


λ‹΅λ³€

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>

이 글은 Java μΉ΄ν…Œκ³ λ¦¬λ‘œ λΆ„λ₯˜λ˜μ—ˆκ³  λ‹˜μ— μ˜ν•΄ 에 μž‘μ„±λμŠ΅λ‹ˆλ‹€.