개발자 지침

개발자 지침 (Developer Guidelines)

HBase 기여자를 위한 코드 표준, 인터페이스 분류, 포맷팅 규칙, Git 모범 사례, 패치 제출 지침을 살펴볼게요. 커밋터 가이드와 hbase-thirdparty 의존성에 대해서도 다뤄요.

출처: 문서

본문

브랜치 (Branches)

우리는 소스 코드 관리를 위해 Git을 사용하며 최신 개발은 master 브랜치에서 일어나요. 과거의 major/minor/maintenance 릴리스용 브랜치가 있으며, 중요한 기능과 버그 수정은 종종 그 브랜치로 백포트돼요.

JIRA의 Fix Version 정책

주어진 수정이 릴리스 번호만으로 주어진 릴리스에 있는지 판단하기 위해 다음 규칙이 정의돼요.

  • X.Y.Z의 Fix version => 모든 X.Y.Z' 릴리스에 수정됨(여기서 Z' = Z).
  • X.Y.0의 Fix version => 모든 X.Y'.* 릴리스에 수정됨(여기서 Y' = Y).
  • X.0.0의 Fix version => 모든 X'.. 릴리스에 수정됨(여기서 X' = X).

이 정책으로 1.3.0의 fix version은 1.4.0을 암시하지만, 1.3.2는 숫자만으로 어떤 릴리스가 먼저 왔는지 알 수 없으므로 1.4.0을 암시하지 않아요.

코드 표준 (Code Standards)

인터페이스 분류 (Interface Classifications)

인터페이스는 관객(audience)과 안정성 수준(stability level) 모두로 분류돼요. 이 라벨들은 클래스 시작 부분에 나타나요. HBase가 따르는 규약은 부모 프로젝트인 Hadoop에서 상속됐어요.

다음 인터페이스 분류가 일반적으로 사용돼요.

InterfaceAudience

@InterfaceAudience.Public 사용자와 HBase 애플리케이션을 위한 API. 이 API들은 HBase의 major 버전을 통해 폐기될 거예요.

@InterfaceAudience.Private HBase 내부 개발자를 위한 API. 미래 버전의 호환성이나 가용성에 대한 보장 없음. Private 인터페이스는 @InterfaceStability 분류가 필요 없어요.

@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) HBase coprocessor 작성자를 위한 API.

@InterfaceAudience 분류 없음: @InterfaceAudience 라벨이 없는 패키지는 private으로 간주돼요. 공개적으로 접근 가능하다면 새 패키지를 표시해 주세요.

API 문서에서 비공개 인터페이스 제외하기 API 문서(Javadoc)에는 @InterfaceAudience.Public으로 분류된 인터페이스만 포함되어야 해요. 커밋터는 공개 클래스를 포함하지 않는 새 패키지에 대해 pom.xml의 ExcludePackageNames 섹션에 새 패키지 제외를 추가해야 해요.

@InterfaceStability

@InterfaceStability는 @InterfaceAudience.Public으로 표시된 패키지에 중요해요.

@InterfaceStability.Stable 안정으로 표시된 공개 패키지는 폐기 경로나 아주 좋은 이유 없이는 변경할 수 없어요.

@InterfaceStability.Unstable 불안정으로 표시된 공개 패키지는 폐기 경로 없이 변경될 수 있어요.

@InterfaceStability.Evolving 진화 중으로 표시된 공개 패키지는 변경될 수 있지만, 권장되지는 않아요.

@InterfaceStability 라벨 없음: @InterfaceStability 라벨이 없는 공개 클래스는 권장되지 않으며, 암묵적으로 불안정한 것으로 간주되어야 해요.

패키지를 어떻게 표시할지 불확실하면 개발 목록에 물어보세요.

코드 포맷팅 규약 (Code Formatting Conventions)

패치가 더 빨리 검토될 수 있도록 다음 지침을 준수해 주세요. 이 지침은 새 기여자의 패치에 대한 공통 피드백을 바탕으로 개발됐어요.

Java의 코딩 규약에 대한 자세한 내용은 Java 프로그래밍 언어용 코드 규약(Code Conventions for the Java Programming Language)을 참고해 주세요. Eclipse 코드 포맷팅에서 이러한 지침 중 일부를 자동으로 확인하도록 Eclipse를 설정하는 방법을 참고해 주세요.

Space Invaders

괄호 주위에 여분의 공백을 사용하지 마세요. 첫 번째 스타일이 아니라 두 번째 스타일을 사용하세요.

if ( foo.equals( bar ) ) {     // don't do this
if (foo.equals(bar)) {
foo = barArray[ i ];     // don't do this
foo = barArray[i];

자동 생성 코드 (Auto Generated Code)

Eclipse의 자동 생성 코드는 종종 arg0 같은 나쁜 변수 이름을 사용해요. 더 정보적인 변수 이름을 사용하세요. 여기 두 번째 예시 같은 코드를 사용하세요.

 public void readFields(DataInput arg0) throws IOException {    // don't do this
   foo = arg0.readUTF();                                       // don't do this
 public void readFields(DataInput di) throws IOException {
   foo = di.readUTF();

긴 줄 (Long Lines)

줄을 100자 미만으로 유지하세요. IDE에서 이 작업을 자동으로 수행하도록 구성할 수 있어요.

Bar bar = foo.veryLongMethodWithManyArguments(argument1, argument2, argument3, argument4, argument5, argument6, argument7, argument8, argument9);  // don't do this
Bar bar = foo.veryLongMethodWithManyArguments(
 argument1, argument2, argument3,argument4, argument5, argument6, argument7, argument8, argument9);

끝 공백 (Trailing Spaces)

코드 끝에 줄바꿈이 있는지 확인하고, 공백만 있는 줄을 피하세요. 이렇게 하면 diff가 더 의미 있어져요. IDE가 도와주도록 구성할 수 있어요.

Bar bar = foo.getBar();     <--- imagine there is an extra space(s) after the semicolon.

API 문서 (Javadoc)

Javadoc을 잊지 마세요!

Javadoc 경고는 precommit 중에 검사돼요. precommit 도구가 '-1'을 주면 javadoc 문제를 고쳐 주세요. 그런 경고를 추가하면 패치가 커밋되지 않을 거예요.

또한 @author 태그는 없어요 — 그건 규칙이에요.

Findbugs

Findbugs는 일반적인 버그 패턴을 감지하는 데 사용돼요. precommit 빌드 중에 확인돼요. 오류가 발견되면 고쳐 주세요. findbugs를 로컬에서 mvn findbugs:findbugs로 실행할 수 있으며, 로컬에 findbugs 파일을 생성할 거예요. 때로는 findbugs보다 더 영리한 코드를 작성해야 할 수도 있어요. 다음 주석으로 클래스를 주석 처리해 자신이 무슨 일을 하고 있는지 알고 있다고 findbugs에 알릴 수 있어요.

@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value="HE_EQUALS_USE_HASHCODE",
justification="I know what I'm doing")

Apache 라이선스 버전의 주석을 사용하는 것이 중요해요. 일반적으로 edu.umd.cs.findbugs.annotations 패키지의 주석을 사용해 javax.annotations 패키지의 주석보다 cleanroom 재구현에 의존할 수 있다는 뜻이에요.

Javadoc - 쓸모없는 기본값

Javadoc 태그를 IDE가 생성하는 방식으로 그냥 두지 말고, 여기에 중복 정보를 채우지 마세요.

  /**
   * @param table                              <---- don't leave them empty!
   * @param region An HRegion object.          <---- don't fill redundant information!
   * @return Foo Object foo just created.      <---- Not useful information
   * @throws SomeException                     <---- Not useful. Function declarations already tell that!
   * @throws BarException when something went wrong  <---- really?
   */
  public Foo createFoo(Bar bar);

태그에 설명적인 내용을 추가하거나 그냥 제거하세요. 설명적이고 유용한 내용을 추가하는 것이 선호돼요.

한 번에 한 가지씩 (One Thing At A Time, Folks)

한 가지를 위한 패치를 제출할 때, 완전히 다른 코드 영역에 대해 자동 재포맷팅이나 무관한 재포맷팅을 하지 마세요. 마찬가지로 Jira 범위 밖의 무관한 정리나 리팩토링을 추가하지 마세요.

모호한 단위 테스트 (Ambiguous Unit Tests)

단위 테스트에서 무엇을 테스트하고 있고 왜 하는지 명확히 하세요.

가비지 컬렉션 절약 지침 (Garbage-Collection Conserving Guidelines)

다음 지침은 http://engineering.linkedin.com/performance/linkedin-feed-faster-less-jvm-garbage에서 빌려왔어요. 이 지침을 유념해 예방 가능한 가비지 컬렉션을 최소화하세요. 이 지침에 따라 코드를 리팩토링하는 방법에 대한 좋은 예제는 블로그 글을 보세요.

  • Iterator를 조심하세요
  • 초기화할 때 컬렉션의 크기를 추정하세요
  • 표현식 평가를 지연하세요
  • 정규식 패턴을 미리 컴파일하세요
  • 할 수 있으면 캐시하세요
  • String Intern은 유용하지만 위험해요

불변 조건 (Invariants)

우리에겐 많지는 않지만, 가진 것은 아래에 나열해요. 물론 모두 도전 대상이지만, 그때까지는 규칙을 지켜 주세요.

ZooKeeper에 영구 상태 없음

ZooKeeper 상태는 일시적이어야 해요(메모리처럼 취급). ZooKeeper 상태가 삭제되면 hbase는 복구해 본질적으로 같은 상태에 있을 수 있어야 해요.

  • 예외: 현재 테이블이 활성화(enabled) 또는 비활성화(disabled)되었는지에 대한 몇 가지 예외가 있으며 이를 고쳐야 해요.
  • 복제 데이터는 현재 ZooKeeper에만 저장돼요. 복제와 관련된 ZooKeeper 데이터를 삭제하면 복제가 비활성화될 수 있어요. /hbase/replication/ 복제 트리를 삭제하지 마세요.

ZooKeeper에서 /hbase/replication/ 복제 트리를 삭제하면 복제가 중단되고 데이터 손실이 발생할 수 있어요. 이 이슈의 진행 상황은 HBASE-10295를 통해 추적해 주세요.

In-Situ 실행 (Running In-Situ)

Apache HBase를 개발 중이라면, 변경 사항을 단위 테스트에서 찾을 수 있는 것보다 더 실제적인 클러스터에 대해 테스트하는 것이 종종 유용해요. 이 경우 HBase는 로컬 모드에서 소스에서 직접 실행될 수 있어요. 해야 할 일은 다음을 실행하는 것뿐이에요.

${HBASE_HOME}/bin/start-hbase.sh

이것은 HBase를 패키징해서 머신에 설치한 것처럼 전체 로컬 클러스터를 띄울 거예요.

in-situ 클러스터가 제대로 작동하려면 HBase를 로컬 maven 저장소에 설치해야 한다는 점을 명심해 주세요. 즉, 다음을 실행해야 해요.

mvn clean install -DskipTests

maven이 올바른 classpath와 의존성을 찾을 수 있도록 하기 위해서요. 일반적으로 위 명령은 maven이 이상하게 작동하면 먼저 실행해 보기 좋은 명령이에요.

지표 추가 (Adding Metrics)

새 기능을 추가한 후 개발자는 지표를 추가하고 싶을 수 있어요. HBase는 Hadoop Metrics 2 시스템을 사용해 지표를 노출하므로, 새 지표를 추가하는 것은 그 지표를 hadoop 시스템에 노출하는 것을 포함해요. 불행히도 metrics2의 API는 hadoop 1에서 hadoop 2로 변경됐어요. 이를 해결하기 위해 런타임에 로드되어야 하는 인터페이스와 구현 집합이 있어요. 이러한 클래스의 근거와 구조를 깊이 있게 보려면 여기의 블로그 글을 읽을 수 있어요. 기존 MBean에 지표를 추가하려면 아래 짧은 가이드를 따르세요.

Hadoop Compat Interface에 지표 이름과 함수 추가

지표가 생성되는 곳에 해당하는 소스 인터페이스 안에서(예: HMaster에서 오는 것의 MetricsMasterSource) 지표 이름과 설명을 위한 새 정적 문자열을 만들어요. 그런 다음 새 읽기를 추가하기 위해 호출될 새 메서드를 추가해요.

Hadoop 1과 Hadoop 2 Compat 모듈 모두에 구현 추가

소스의 구현 안에서(예: 위 예시의 MetricsMasterSourceImpl) init 메서드에 새 histogram, counter, gauge 또는 stat를 만들어요. 그런 다음 인터페이스에 추가된 메서드에서 전달된 매개변수를 histogram에 연결해 주세요.

이제 데이터가 metrics 2 시스템에 올바르게 내보내지는지 확인하는 테스트를 추가하세요. 이를 위해 MetricsAssertHelper가 제공돼요.

Git 모범 사례 (Git Best Practices)

git 병합을 피하세요. git pull --rebase 또는 git fetch 후 git rebase를 사용하세요.

git push --force를 사용하지 마세요. push가 작동하지 않으면 문제를 고치거나 도움을 요청하세요.

다른 Git 모범 사례를 생각나면 이 문서에 기여해 주세요.

rebase_all_git_branches.sh

dev-support/rebase_all_git_branches.sh 스크립트가 Git 저장소를 깨끗하게 유지하는 데 도움을 주기 위해 제공돼요. 사용법을 얻으려면 -h 매개변수를 사용해 주세요. 스크립트가 추적 브랜치를 자동으로 새로고침하고, 각 로컬 브랜치를 원격 브랜치에 대해 자동 rebase를 시도하며, 닫힌 HBASE- JIRA를 나타내는 브랜치를 삭제할지 선택하게 해줘요. 스크립트에는 선택적 구성 옵션인 Git 디렉터리 위치가 하나 있어요. 스크립트를 편집해 기본값을 설정할 수 있어요. 그렇지 않으면 -d 매개변수를 사용하고 그 다음에 절대 또는 상대 디렉터리 이름, 심지어 현재 작업 디렉터리용 '.'를 전달해 git 디렉터리를 수동으로 전달할 수 있어요. 스크립트는 진행하기 전에 디렉터리에 .git/라는 하위 디렉터리가 있는지 확인해요.

패치 제출 (Submitting Patches)

오픈소스에 패치를 제출하는 것이 처음이거나 Apache에 패치를 제출하는 것이 처음이라면, Apache Commons 프로젝트의 On Contributing Patches 페이지를 읽고 시작하세요. 이것은 Apache HBase 프로젝트에도 동일하게 적용되는 좋은 개요를 제공해요.

코드 스타일은 Code Formatting Conventions를 검토하세요. 패치가 잘못 생성되었거나 코드가 코드 포맷팅 지침을 따르지 않으면 일부 작업을 다시 요청받을 수 있어요.

HBase는 maven plugin으로 코드 스타일을 강제해요. 변경 사항을 작성한 후 커밋하기 전에 formatter를 적용해 주세요.

$ mvn spotless:apply

커밋이 준비되면 GitHub Pull Request로 커뮤니티에 제시해 주세요.

몇 가지 일반적인 지침 (Few general guidelines)

  • 다른 브랜치를 패치하고 싶더라도 항상 먼저 master 브랜치에 패치하세요. HBase 커밋터는 항상 먼저 master 브랜치에 패치를 적용하고 필요에 따라 백포트해요. 복잡한 패치의 경우 백포트를 직접 수행하도록 요청받을 수 있어요.
  • 단일 수정에 대해 단일 PR을 제출하세요. 필요하면 로컬 커밋을 스쿼시해 단일 커밋으로 병합하세요. 커밋 스쿼싱에 대한 자세한 내용은 이 Stack Overflow 질문을 참고해 주세요.
  • 모든 패치가 커밋되지는 않을 수 있고, 패치에 대한 피드백이 제공될 가능성이 높다는 것을 이해해 주세요.

단위 테스트 (Unit Tests)

변경할 때 관련 단위 테스트를 항상 추가/갱신하세요. 전체 테스트 스위트를 실행하는 presubmit 결과를 기다리는 것보다 빠르므로, 패치를 제출하기 전에 새/변경된 단위 테스트가 로컬에서 통과하는지 확인하세요. 이것은 자신의 시간과 노력을 절약해 줄 거예요. 적절한 실패를 주입해 실패 시나리오를 테스트하는 데 매우 유용한 mock을 만들려면 Mockito를 사용하세요.

새 단위 테스트 클래스를 만들 때, 다른 단위 테스트 클래스가 클래스 이름 앞에 분류/크기 조정 주석을 어떻게 가지는지, 테스트 환경 설정/해제를 위한 static 메서드를 가지는지 주목하세요. 새 단위 테스트 파일에 주석을 반드시 포함하세요. 테스트에 대한 자세한 내용은 Tests를 참고해 주세요.

통합 테스트 (Integration Tests)

의미 있는 새 기능은 단위 테스트 외에도 통합 테스트를 제공해야 하며, 새 기능을 구성 공간의 다른 지점에서 시험하기에 적합해야 해요.

ReviewBoard

한 화면보다 큰 패치, 또는 검토하기 까다로운 패치는 ReviewBoard를 거쳐야 해요.

절차: ReviewBoard 사용

아직 계정이 없으면 계정을 등록하세요. issues.apache.org의 자격 증명을 사용하지 않아요. 로그인하세요.

New Review Request를 클릭하세요.

hbase-git 저장소를 선택하세요.

Choose File을 클릭해 diff와 선택적으로 parent diff를 선택하세요.

Create Review Request를 클릭하세요.

필요에 따라 필드를 채우세요. 최소한 Summary를 채우고 hbase를 Review Group으로 선택하세요. Bugs 필드를 채우면 review board가 관련 JIRA로 연결해요. 더 많은 필드를 채울수록 더 좋아요.

Publish를 클릭해 검토 요청을 공개하세요. hbase 그룹의 모든 사람에게 패치를 검토하라는 이메일이 전송될 거예요.

JIRA로 돌아가서, ReviewBoard 요청 URL을 붙여넣어 주세요. 이렇게 하면 ReviewBoard가 JIRA에 첨부되어 쉽게 접근할 수 있어요.

요청을 취소하려면, 를 클릭하세요.

ReviewBoard 사용법에 대한 자세한 내용은 ReviewBoard 문서를 참고해 주세요.

GitHub

GitHub pull request 제출은 패치 기여의 또 다른 인정된 형태예요. pull request 만드는 방법에 대한 자세한 내용은 GitHub 문서를 참조해 주세요.

이 섹션은 불완전하며 갱신이 필요해요. HBASE-23557을 참조하세요.

GitHub 도구 (GitHub Tooling)

브라우저 북마크

다음은 GitHub pull request에서 해당 jira 작업 항목으로 리다이렉트하는 유용한 javascript 기반 브라우저 북마크예요. PR의 이슈 제목에 언급된 HBase jira ID를 기준으로 리다이렉트해요. 다음 javascript 스니펫을 브라우저 북마크로 도구 막대에 추가하세요. HBase GitHub PR 페이지에 있는 동안 클릭하면 해당 jira 항목으로 리다이렉트돼요.

location.href =
  "https://issues.apache.org/jira/browse/" +
  document.getElementsByClassName("js-issue-title")[0].innerHTML.match(/HBASE-\d+/)[0];

HBase 커밋터를 위한 가이드 (Guide for HBase Committers)

커밋터 되기 (Becoming a committer)

커밋터는 코드 변경을 검토하고 통합하며, 릴리스 후보를 테스트하고 투표하며, 설계 논의에 의견을 내고, 기타 유형의 프로젝트 기여를 담당해요. PMC는 프로젝트에 대한 기여 평가를 바탕으로 기여자를 커밋터로 만들지 투표해요. 커밋터는 프로젝트와 커뮤니티 참여에 지속적으로 고품질 기여를 하는 것이 기대돼요.

기여는 여러 방식으로 이루어질 수 있어요. 커밋터가 되는 단일 경로나 예상 타임라인은 없어요. 기능, 개선, 버그 수정을 제출하는 것이 가장 흔한 경로지만, 다른 방법도 인정되고 권장돼요(그리고 HBase의 프로젝트 및 커뮤니티로서의 건강에 더 중요할 수도 있어요). 잠재적 기여의 비완전한 목록(특별한 순서 없음):

  • 새 변경, 모범 사례, 레시피, 기타 개선에 대한 문서를 갱신하세요.
  • 웹사이트를 최신으로 유지하세요.
  • 테스트를 수행하고 결과를 보고하세요. 예를 들어 스케일 테스트와 비표준 구성 테스트는 항상 감사히 여겨져요.
  • 공유 Jenkins 테스트 환경과 기타 테스트 인프라를 유지하세요.
  • 검증을 수행한 후 릴리스 후보에 투표하세요(비구속적이라도). 비구속 투표는 비-커밋터의 투표예요.
  • 메일링 리스트(보통 제목에 [DISCUSS]가 있는)의 논의 스레드에 의견을 제공하세요.
  • 사용자 또는 개발자 메일링 리스트와 Slack의 질문에 답하세요.
  • HBase 커뮤니티가 환영하는 곳이 되고 우리 행동 강령을 따르도록 하세요. 우려가 있으면 PMC에 알리세요.
  • 다른 사람의 작업(코드와 비코드 모두)을 검토하고 공개 피드백을 제공하세요.
  • 발견한 버그를 보고하거나 새 기능 요청을 제출하세요.
  • 이슈를 트리아지하고 JIRA를 정리하세요. 여기에는 낡은 이슈 닫기, 새 이슈 라벨링, 메타데이터 갱신, 기타 필요한 작업이 포함돼요.
  • 모든 종류의 새 기여자를 멘토하세요.
  • HBase에 대해 발표하고 블로그를 쓰세요. 웹사이트의 News 섹션에 추가하세요.
  • HBase, 웹 UI, CLI, API, 웹사이트에 대한 UX 피드백을 제공하세요.
  • 데모 애플리케이션과 스크립트를 작성하세요.
  • 다양한 커뮤니티를 끌어들이고 유지하는 데 도움을 주세요.
  • HBase와 그 다른 프로젝트에 이익이 되는 방식으로 다른 프로젝트와 상호작용하세요.

모든 개인이 이 목록의 모든(또는 어떤) 항목을 할 수 있는 것은 아니에요. 다른 기여 방법을 생각나면 그걸 하세요(그리고 목록에 추가하세요). 좋은 태도와 기여 의지가 HBase 프로젝트에 긍정적 영향을 미치는 데 필요한 전부예요. 커밋터가 되라는 초대는 장기간에 걸쳐 커뮤니티와의 꾸준한 상호작용의 결과이며, 신뢰와 인정을 쌓아요.

새 커밋터 (New committers)

새 커밋터는 먼저 Apache의 일반적인 커밋터 문서를 읽는 것이 권장돼요:

  • Apache New Committer Guide
  • Apache Committer FAQ

검토 (Review)

HBase 커밋터는 가능한 한 자주 다른 사람이 제출한 패치를 검토하려 시도해야 해요. 이상적으로 모든 제출된 패치는 며칠 안에 커밋터가 검토할 거예요. 커밋터가 자신이 작성하지 않은 패치를 검토하고 충분한 품질이라고 믿으면 패치를 커밋할 수 있어요. 그렇지 않으면 패치를 거부 이유에 대한 명확한 설명과 함께 취소해야 해요.

제출된 패치 목록은 마지막 수정 시간으로 정렬된 HBase Review Queue에 있어요. 커밋터는 목록을 위에서 아래로 스캔하며 검토하고 커밋할 자격이 있다고 느끼는 패치를 찾아봐야 해요. 다른 사람이 검토하는 것이 더 적합하다고 생각되는 패치를 보면 JIRA에서 사용자 이름으로 그 사람을 언급할 수 있어요.

사소하지 않은 변경의 경우 커밋 전에 다른 커밋터가 패치를 검토하는 것이 요구돼요. 사소하지 않은 패치의 자가 커밋은 허용되지 않아요. 다른 기여자처럼 JIRA의 Submit Patch 버튼을 사용하고, 커밋 전에 다른 커밋터의 +1 응답을 기다리세요.

거부 (Reject)

HowToContribute와 코드 검토 체크리스트의 지침을 따르지 않는 패치는 거부되어야 해요. 커밋터는 항상 기여자에게 정중하고, 더 나은 패치를 기여하도록 지시하고 격려하려 노력해야 해요. 커밋터가 허용할 수 없는 패치를 개선하고 싶다면 먼저 거부하고, 추가 검토를 위해 커밋터가 새 패치를 첨부해야 해요.

커밋 (Commit)

커밋터는 Apache HBase GIT 저장소에 패치를 커밋해요.

커밋하기 전에!!!! 로컬 구성, 특히 자신의 신원과 이메일이 올바른지 확인하세요. $ git config --list 명령의 출력을 검토하고 올바른지 확인해 주세요. 포인터가 필요하면 Set Up Git을 참고하세요.

패치를 커밋할 때:

  • 커밋 메시지에 Jira 이슈 ID와 변경 사항에 대한 짧은 설명을 포함하세요. git log 출력을 보는 사람이 변경 내용이 무엇에 관한 것인지 알아내기 위해 Jira에 가지 않아도 되도록 Jira 제목만이 아니라 뭔가 더 추가해 주세요. 이슈 ID를 정확히 적어야 하는데, 이것이 Jira가 Git의 변경에 링크하도록 하기 때문이에요(이 자동 링크를 보려면 이슈의 "All" 탭을 사용하세요).
  • master 또는 의도한 다른 브랜치를 기준으로 한 새 브랜치에 패치를 커밋하세요. 이 브랜치 이름에 JIRA ID를 포함하는 것이 좋아요. 커밋하려는 관련 대상 브랜치를 체크아웃하고, git pull --rebase 또는 비슷한 명령으로 로컬 브랜치에 모든 원격 변경이 있는지 확인하세요. 다음으로 각 관련 브랜치(예: master)에 변경을 cherry-pick하고, git push 같은 명령으로 변경을 원격 브랜치로 푸시하세요. 원격 변경이 모두 없으면 push가 실패할 거예요. 어떤 이유로든 push가 실패하면 문제를 고치거나 도움을 요청하세요. git push --force를 하지 마세요. 패치를 커밋하기 전에 패치가 어떻게 생성되었는지 판단해야 해요. 패치를 만드는 방법에 대한 지침과 선호가 변경되었고, 전환 기간이 있을 거예요. 패치가 어떻게 생성되었는지 판단하세요.

패치의 처음 몇 줄이 From, Date, Subject가 있는 이메일 헤더처럼 보이면 git format-patch로 생성된 것이에요. 이는 커밋 메시지를 재사용할 수 있으므로 선호되는 방식이에요. 커밋 메시지가 적절하지 않으면 그래도 커밋을 사용한 다음 git commit --amend를 실행해 적절히 다시 표현해도 돼요.

패치의 첫 줄이 다음과 비슷하면 +git diff+를 --no-prefix 없이 생성한 것이에요. 이것도 허용돼요. 파일 이름 앞의 a와 b를 주목하세요. 이것은 패치가 --no-prefix로 생성되지 않았다는 표시예요. diff --git a/src/main/asciidoc/_chapters/developer.adoc b/src/main/asciidoc/_chapters/developer.adoc

패치의 첫 줄이 다음과 비슷하면(a와 b 없이) git diff --no-prefix로 생성된 것이며 아래 git apply 명령에 -p0을 추가해야 해요. diff --git src/main/asciidoc/_chapters/developer.adoc src/main/asciidoc/_chapters/developer.adoc

패치 커밋의 예시 이 예시에서 눈치챘을 한 가지는 git pull 명령이 많다는 것이에요. 원격 저장소에 실제로 무엇인가를 기록하는 유일한 명령은 git push이며, push 전에 모든 것이 올바른 버전이고 충돌이 없음을 절대적으로 확신해야 해요. 추가 git pull 명령은 보통 중복이지만, 안전한 것이 낫지요. 첫 번째 예시는 +git format-patch+로 생성된 패치를 적용하고 master와 branch-1 브랜치에 적용하는 방법을 보여줘요. git diff가 아닌 git format-patch를 사용하고 --no-prefix를 사용하지 말라는 지시는 새로운 것이에요. git diff로 생성된 패치를 적용하는 방법은 두 번째 예시를 참고하고, 패치를 만든 사람에게 교육해 주세요.

$ git checkout -b HBASE-XXXX
$ git am ~/Downloads/HBASE-XXXX-v2.patch --signoff  # If you are committing someone else's patch.
$ git checkout master
$ git pull --rebase
$ git cherry-pick <sha-from-commit>
# Resolve conflicts if necessary or ask the submitter to do it
$ git pull --rebase          # Better safe than sorry
$ git push origin master

# Backport to branch-1
$ git checkout branch-1
$ git pull --rebase
$ git cherry-pick <sha-from-commit>
# Resolve conflicts if necessary
$ git pull --rebase          # Better safe than sorry
$ git push origin branch-1
$ git branch -D HBASE-XXXX

이 예시는 --no-prefix 없이 git diff로 생성된 패치를 커밋하는 방법을 보여줘요. 패치가 --no-prefix로 생성되었으면 git apply 명령에 -p0을 추가해 주세요.

$ git apply ~/Downloads/HBASE-XXXX-v2.patch
$ git commit -m "HBASE-XXXX Really Good Code Fix (Joe Schmo)" --author=<contributor> -a  # This and next command is needed for patches created with 'git diff'
$ git commit --amend --signoff
$ git checkout master
$ git pull --rebase
$ git cherry-pick <sha-from-commit>
# Resolve conflicts if necessary or ask the submitter to do it
$ git pull --rebase          # Better safe than sorry
$ git push origin master

# Backport to branch-1
$ git checkout branch-1
$ git pull --rebase
$ git cherry-pick <sha-from-commit>
# Resolve conflicts if necessary or ask the submitter to do it
$ git pull --rebase           # Better safe than sorry
$ git push origin branch-1
$ git branch -D HBASE-XXXX
  • 이슈를 fixed로 해결하고 기여자에게 감사하세요. 항상 이 시점에 "Fix Version"을 설정하지만, 변경이 커밋된 각 브랜치에 단일 fix version만 설정하고, 그 브랜치에서 변경이 나타날 가장 이른 릴리스로 설정하세요.

커밋 메시지 형식 (Commit Message Format) 커밋 메시지는 JIRA ID와 패치가 무엇을 하는지에 대한 설명을 포함해야 해요. 선호되는 커밋 메시지 형식은:

<jira-id> <jira-title> (<contributor-name-if-not-commit-author>)
HBASE-12345 Fix All The Things ([email protected])

기여자가 git format-patch로 패치를 생성했다면 커밋 메시지가 그 패치에 있고 그것을 사용할 수 있지만, 기여자가 빼놓았더라도 JIRA ID가 커밋 메시지 앞에 오도록 하세요.

여러 작성자가 있을 때 GitHub의 "Co-authored-by" 사용

가능할 때마다 master에 커밋하고 브랜치로 cherry pick하는 관행을 확립했지만, 다음과 같은 경우는 제외해요.

  • 호환성을 깨는 경우: 이 경우 minor 릴리스에 들어갈 수 있으면 branch-1과 branch-2로 백포트하세요.
  • 새 기능: maintenance 릴리스에는 안 되고, minor 릴리스에는 토론하고 합의에 도달하세요.

패치에 여러 작성자가 있는 경우가 있어요. 예를 들어 사소한 충돌이 있을 때 그것을 고쳐 커밋을 진행할 수 있어요. 수정하는 작성자는 원래 커밋터와 다르므로, 커밋 메시지에 Co-authored-by 트레일러를 하나 이상 추가해 원래 작성자에게도 귀속해야 해요. "여러 작성자로 커밋 만들기"에 대한 GitHub 문서를 참고해 주세요.

간단히 말해 GitHub가 추적하는 Co-authors를 추가하는 단계는 다음과 같아요.

  • 각 공동 작성자의 이름과 이메일 주소를 수집하세요.
  • 변경을 커밋하되, 커밋 설명 뒤에 닫는 따옴표 대신 빈 줄 두 개를 추가하세요. (커밋 메시지를 따옴표로 닫지 마세요)
  • 커밋 메시지의 다음 줄에 Co-authored-by: name [email protected]을 입력하세요. 공동 작성자 정보 뒤에 닫는 따옴표를 추가하세요.

여기 GitHub 페이지의 예시가 있어요(공동 작성자 2명 사용).

$ git commit -m "Refactor usability tests.
>
>
Co-authored-by: name <[email protected]>
Co-authored-by: another-name <[email protected]>"

참고: 이 DISCUSSION 이전에는 Amending-Author: Author committer@apache가 사용됐어요.

관련 GitHub PR 닫기 프로젝트로서 각 변경에 JIRA가 연관되도록 노력하지만, 검토에 특정 도구를 사용하도록 강제하지는 않아요. 호스팅된 git 저장소와 GitHub 사이의 ASF 통합 구현 세부 사항 때문에, PMC는 GitHub 저장소에서 PR을 직접 닫을 능력이 없어요. 기여자가 GitHub에서 Pull Request를 만드는 경우(기여자가 JIRA에 패치를 첨부하는 것보다 쉽다고 느끼거나, 검토자가 변경을 검토하기 위해 그 UI를 선호하거나), master 브랜치로 가는 커밋에서 PR을 기록해 두어 PR이 최신 상태로 유지되도록 하는 것이 중요해요.

커밋 메시지의 어떤 종류가 GitHub의 "커밋의 키워드로 닫기" 메커니즘과 작동하는지에 대한 자세한 내용은 "키워드를 사용해 이슈 닫기"에 대한 GitHub 문서를 참고해 주세요. 요약하면, "closes #XXX"라는 구절이 있는 줄을 포함해야 하며, 여기서 XXX는 pull request id예요. pull request id는 보통 주제 제목 끝에 회색으로 GitHub UI에 주어져요.

커밋터는 커밋이 빌드나 테스트를 깨지 않게 하는 책임이 있음 커밋터가 패치를 커밋하면 테스트 스위트를 통과하는지 확인하는 것이 그들의 책임이에요. 기여자가 자신의 패치가 hbase 빌드 및/또는 테스트를 깨지 않는지 주시하는 것이 도움이 되지만, 궁극적으로 기여자가 HBase 같은 프로젝트에서 발생하는 특정한 변덕과 상호연결을 모두 알 것이라고 기대할 수는 없어요. 커밋터는 알아야 해요.

패치 에티켓 (Patching Etiquette) HBase, mail # dev - ANNOUNCEMENT: Git Migration In Progress 스레드에서 다음 패치 흐름에 동의했어요.

  • 먼저 master에 대해 패치를 개발하고 커밋하세요.
  • 가능하면 백포트할 때 패치를 cherry-pick하려고 시도하세요.
  • 이것이 작동하지 않으면 브랜치에 패치를 수동으로 커밋하세요.

병합 커밋 (Merge Commits) 병합 커밋은 git 기록에 문제를 만들므로 피하세요.

문서 커밋 (Committing Documentation) 문서 기여 부록을 참고해 주세요.

github Pull Request 검사/재빌드를 다시 트리거하는 방법 Pull Request(PR) 제출은 hbase yetus 검사를 트리거해요. 검사는 패치가 빌드를 깨지 않거나 테스트 실패를 도입하지 않는지 확인해요. 검사는 약 4시간이 걸려요(HBASE JIRA를 통해 패치를 제출할 때 실행되는 것과 동일한 집합이에요). 완료되면 PR에 보고서를 댓글로 추가해요. 패치에 문제(컴파일 실패, checkstyle 위반, 추가된 findbugs)가 있으면 원래 작성자가 수정하고 새 패치를 푸시해요. 이렇게 하면 검사가 다시 실행되어 새 보고서를 만들어요.

때로는 패치가 좋지만 flaky하거나 무관한 테스트가 보고서에 -1을 주는 경우가 있어요. 이 경우 커밋터는 정확히 같은 패치를 force push해 검사 실행을 다시 트리거할 수 있어요. 또는 보고서 끝에 표시되는 Console output 링크(예: https://builds.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-289/1/console)를 클릭하세요. 이렇게 하면 실패한 빌드 실행인 builds.apache.org로 이동해요. 이 특정 빌드 페이지로 이끄는 디렉터리 목록인 "breadcrumbs"를 위쪽에서 보세요. Jenkins > HBase-PreCommit-GitHub-PR > PR-289 > #1처럼 보일 거예요. PR 번호(예시의 PR-289)를 클릭하고, PR 페이지에 도착하면 'Build with Parameters' 메뉴 항목(왼쪽 위 메뉴를 따라)을 찾으세요. 여기를 클릭하고 JIRA_ISSUE_KEY를 비워둔 채 Build하세요. 이렇게 하면 검사가 다시 실행돼요.

대화 (Dialog)

커밋터는 실시간 논의를 위해 irc.freenode.net의 #hbase 방에 있어야 해요. 하지만 어떤 실질적 논의(다른 off-list 프로젝트 관련 논의와 마찬가지로)는 Jira나 개발자 목록에서 반복되어야 해요.

JIRA 댓글을 편집하지 마세요

오타나 잘못된 문법은 JIRA 댓글 편집의 방해보다 선호돼요.

hbase-thirdparty 의존성과 shading/relocation

hbase-2.0.0 릴리스를 위해 새 프로젝트가 만들어졌어요. 이름은 hbase-thirdparty예요. 이 프로젝트는 guava, netty, protobuf 같은 인기 있는 서드파티 라이브러리의 relocated(또는 shaded) 버전만 메인 hbase 프로젝트에 제공하기 위해 존재해요. 메인라인 HBase 프로젝트는 보통 위치에서 이 클래스를 찾는 대신 hbase-thirdparty에서 얻은 이 라이브러리의 relocated 버전에 의존해요. 우리가 원하는 어떤 버전이든 지정할 수 있도록 이렇게 해요. relocate하지 않으면 hadoop, spark, 다른 프로젝트가 사용하는 버전과 일치하도록 버전을 조화시켜야 해요.

개발자에게 이것은 netty, guava, protobuf, gson 등의 클래스를 참조할 때 주의해야 한다는 뜻이에요(제공하는 것에 대해 hbase-thirdparty pom.xml 참고). 개발자는 hbase-thirdparty가 제공하는 클래스를 참조해야 해요. 실제로 이것은 보통 문제가 되지 않아요(좀 성가실 수는 있지만). 특정 클래스의 relocated 버전을 찾아야 할 거예요. 일반 relocation 접두사인 org.apache.hbase.thirdparty.를 앞에 붙여 찾을 수 있어요. 예를 들어 com.google.protobuf.Message를 찾고 있다면, HBase 내부가 사용하는 relocated 버전은 org.apache.hbase.thirdparty.com.google.protobuf.Message에서 찾을 수 있어요.

protobuf 같은 몇몇 서드파티 라이브러리(이유는 이 책의 protobuf 챕터 참고)의 경우, IDE가 두 옵션(com.google.protobuf.와 org.apache.hbase.thirdparty.com.google.protobuf.)을 모두 줄 수 있는데, 두 클래스가 CLASSPATH에 있기 때문이에요. Coprocessor Endpoint 개발에서 요구되는 특별한 저글링을 하지 않는 한(위에서 인용한 protobuf 챕터 다시 참고), 항상 shaded 버전을 사용하고 싶을 거예요.

hbase-thirdparty 프로젝트는 groupid가 org.apache.hbase.thirdparty예요. 이 글을 쓰는 시점 기준으로 세 개의 jar를 제공해요. hbase-thirdparty-netty의 artifactid를 가진 netty용 하나, hbase-thirdparty-protobuf의 protobuf용 하나, 그리고 그 밖의 모든 것(gson, guava)용 hbase-thirdpaty-miscellaneous jar 하나가 있어요.

hbase-thirdparty 아티팩트는 HBase 프로젝트 관리 위원회의 후원 아래 Apache HBase 프로젝트가 생산한 제품이에요. 릴리스는 hbase dev 메일링 리스트의 일반적인 투표 프로젝트로 이루어져요. hbase-thirdparty에 이슈가 있으면 hbase JIRA와 메일링 리스트를 사용해 알려 주세요.

HBase 관련 Maven archetype 개발

HBase 관련 Maven archetype 개발은 HBASE-14876으로 시작됐어요. hbase-archetypes 인프라의 개요와 새 HBase 관련 Maven archetype 개발 지침은 hbase/hbase-archetypes/README.md를 참고해 주세요.

더 알아보기 (Learn more)

테스트, 빌드, 참여 방법은 Tests, Building Apache HBase, Getting Involved 문서를 보시길 권해요.