DCO and Github Sign-off Commit

어제 밤에 ZAP쪽에 Pull Request를 날렸다가 아래와 같은 상황이 있었습니다.

너의 커밋이 sign-off가 필요해!!

혹시나 하고 Github App의 결과를 봤더니 sign-off되지 않은 commit이 있다는 이야기가 있었네요.

Commit sha: 3898db1,
Author: hahwul,
Committer: hahwul;

The sign-off is missing.

제가 주로 Contribute 하는 프로젝트들은 4k 이하의 star를 가진 규모의 오픈소스 프로젝트다 보니 아직까지 이런 케이스는 못봤었는데 아무래도 ZAP은 보안쪽 오픈소스 프로젝트에선 규모가 있는 편이라서 그런지 Github App 등으로 CI 하는 과정이 조금 더 디테일 한 것 같네요. (현재 ZAP은 8.5k죠.. 내껀 잘해야 1.3k인데…허헣😭)

저에게 한번 더 확인할 기회를 준 sign-off 관련 내용은 DCO(Developer Certificate of Origin)에 관한 내용이였고 오늘은 이러한 DCO가 뭔지, 어떻게 commit 해야하는지, 실수했을 땐 어떻게 해야하는지 간략하게 글로 작성해봅니다.

DCO(Developer Certificate of Origin)

DCO는 오픈소스 프로젝트에 Contributor가 PR 등 코드에 대한 자신의 기여를 인증하는 방법을 의미합니다. 아래 https://developercertificate.org에서 그 내용을 확인할 수 있습니다.

Developer Certificate of Origin
Version 1.1

Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129

Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.


Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.

여기에 대표적으로 사용되는 방법이 바로 sign-off commit입니다. sign-off commit에 대한 내용은 조금 더 아래에서 정리해봅시다.

Sign-off Commit

sign-off commit은 commit에 signed-off-by로 서명한 사람을 남기는 옵션입니다. 그래서 sign-off commit을 하는 경우 아래와 같이 commit에 Signed-off-by: user <mail> 형태로 기록이 남게 됩니다.

Sign-off commit을 하는 방법은 매우 간단합니다. git commit 시 -s 옵션을 통해 signoff로 commit 할 수 있습니다.

git commit -m "메시지" -s
git commit -h

...
-s, --signoff         add a Signed-off-by trailer
...

여기서 commit message를 보면 아래와 같이 Signed-off-by로 명시됩니다.

test commit!!!

Signed-off-by: hahwul <hahwul@gmail.com>

이미 Signoff 없이 PR한 경우

만약 signoff 없이 commit 후 push, 그리고 Pull Request를 진행하였는데, DCO App 등에 의해서 리젝/웨이팅되는 경우가 있습니다. 이럴 때는 -amend 옵션으로 로컬의 마지막 커밋을 -signoff로 변경해줍니다.

git commit --amend --no-edit --signoff

이후 --force 옵션 적용 후 push를 해주면 automatically merge로 인해서 기존에 날렸던 Pull Request에 merge됩니다.

git push --force-with-lease origin master

--force--force-with-lease 는 강제 push인건 동일하지만, --force-with-lease가 조금 더 안정적이라고 하네요.

DCO for owner and main contributors

자신이 프로젝트의 Owner나 Main Contributor인 경우 https://github.com/apps/dco Github app을 통해서 쉽게 Pull Request에 대해서 DCO를 체크하고 상태를 나타내주어 Contributor가 DCO를 준수할 수 있도록 유도해 줄 수 있습니다.

만약 sign-off commit이 없는게 있다면 표기됩니다.

Conclusion

sign-off commit은 예전에 어느(쿠팡인가..) 개발자분이 쓰신 글을 보고 중요성은 인지하고 있던 상태였습니다. 그 글에선 github를 사용하는 하나의 개발문화 같은 느낌의 인상을 주는 글이였었는데, 개발자가 아닌 저에게는 실제로 sign-off commit을 했을 때 소스코드 기여등에 대한 부분보단 단순히 보안적인 부분(verified와 비슷한 효과이니)만 눈에 띄었었습니다. 다만 어제~오늘까지 관련해서 조금 찾아보고 하니 오픈소스를 지원하는 개발자에겐 매력적인 방법이 아닐까 싶습니다.

저도 제 개인 프로젝트에 적용 해볼까 고민이듭니다. (고생하시는 컨트리뷰터에게 영광을 😎)

References