PEP 462 – CPython 핵심 개발 워크플로 자동화
- Author:
- Alyssa Coghlan <ncoghlan at gmail.com>
- Status:
- Withdrawn
- Type:
- Process
- Requires:
- 474
- Created:
- 23-Jan-2014
- Post-History:
- 25-Jan-2014, 27-Jan-2014, 01-Feb-2015
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
이 PEP는 현재 핵심 개발 팀이 CPython에 변경 사항을 반영하기 위해 수행해야 하는 지루하고 시간이 많이 걸리는 여러 활동의 자동화에 투자할 것을 제안합니다. 이 제안은 핵심 개발자가 CPython에 기여하는 데 사용할 수 있는 시간을 더욱 효과적으로 활용하도록 하기 위한 것이며, 이는 변경 사항을 반영하기 위해 핵심 팀에 의존하는 다른 기여자에게도 더 나은 경험을 제공할 것입니다.
PEP 철회
이 PEP는 작성자에 의해 철회되었습니다. 이는 PEP 507의 GitLab 기반 제안을 지지하기 위한 것입니다.
다른 누군가가 이 PEP의 지지 활동을 이어받고 싶다면 core-workflow 메일링 리스트 에 연락하십시오.
핵심 개발 워크플로 변경의 근거
POSIX 시스템에서 새 기능을 CPython에 병합하는 현재 핵심 개발자 워크플로는 다음과 같이 “작동합니다”:
- 다른 사용자가 bugs.python.org에 제출한 변경 사항을 적용하는 경우, 먼저 해당 사용자가 PSF 기여자 라이선스 계약에 서명했는지 확인합니다. 서명하지 않았다면 변경 사항 병합을 계속하기 전에 계약서에 서명하도록 요청합니다.
- 현재 CPython 주 저장소를 체크아웃한 작업 트리에 변경 사항을 로컬로 적용합니다(일반적으로 변경 사항은 먼저 bugs.python.org에서 패치로 논의되고 검토되지만, 핵심 개발자가 직접 시작한 변경 사항에는 현재 이 단계가 필수로 간주되지 않습니다).
- 최소한
make test또는./python -m test를 사용하여 테스트 모음을 로컬에서 실행합니다(시스템 사양에 따라 기본 구성에서는 몇 분이 걸리지만, 외부 네트워크 액세스와 같은 모든 선택적 리소스를 활성화하면 상당히 오래 걸립니다). - 공백 문제를 수정하고 필요할 수 있는 다른 변경 사항(예: Misc/ACKS 업데이트 또는 Misc/NEWS에 항목 추가)을 상기하기 위해
make patchcheck를 실행합니다. - 변경 사항을 커밋하고 주 저장소로 푸시합니다. hg가 이렇게 하면 원격 저장소에 새 헤드가 생성된다고 표시하는 경우
hg pull --rebase(또는 이에 상응하는 명령)를 실행합니다. 이론적으로는 이 시점에 테스트를 다시 실행해야 하지만, 그 단계를 건너뛰고 싶은 유혹이 매우 큽니다. - 푸시한 후 변경 사항으로 인해 새로 발생한 오류가 있는지 안정 빌드봇을 모니터링합니다. 특히 POSIX 시스템의 개발자는 Windows 빌드봇을 중단시키는 경우가 많으며, 그 반대도 마찬가지입니다. 빈도는 낮지만 Linux 또는 Mac OS X의 개발자가 다른 POSIX 시스템을 중단시키는 경우도 있습니다.
Windows에서 필요한 단계는 비슷하지만, 사용하는 정확한 명령은 달라집니다.
더 단순하기는커녕 버그 수정 워크플로는 새 기능의 워크플로보다 더 복잡합니다! 새 기능은 default 브랜치에만 적용하면 된다는 장점이 있지만, 버그 수정은 유지 관리 브랜치에 포함할지도 고려해야 합니다.
- 버그 수정이 Python 2.7에 적용 가능하다면, Mercurial에서 독립적인 헤드로 유지되는 2.7 브랜치에도 별도로 적용합니다.
- 버그 수정이 현재 3.x 유지 관리 릴리스에 적용 가능하다면, 먼저 유지 관리 브랜치에 적용한 다음 default 브랜치로 순방향 병합합니다. 두 브랜치는 동시에 hg.python.org로 푸시합니다.
문서 패치는 기능 패치보다 간단하지만, 크게 간단한 것은 아닙니다. 주요 이점은 테스트 모음을 실행하는 대신 문서 빌드가 성공하는지만 확인하면 된다는 점입니다.
모든 일이 순조롭게 진행되더라도 깔끔하게 적용되는 버그 수정 패치를 커밋하는 데 여전히 최소 20~30분은 걸릴 것으로 예상합니다. 이러한 작업 중 여러 가지를 자동화할 수 있어야 한다는 점을 고려하면, 현재 관행이 부족한 핵심 개발자 자원을 효과적으로 활용하고 있다고 생각하지 않습니다.
현재 워크플로에는 수많은 불만스러운 점이 있으며, 이는 곧바로 바람직하지 않은 일부 개발 관행으로 이어집니다.
- 이러한 오버헤드의 상당 부분은 적용되는 패치마다 발생합니다. 이는 작고 독립적인 변경보다는 큰 커밋을 하도록 유도합니다. 500줄짜리 기능을 커밋하는 데 필요한 시간은 1줄짜리 버그 수정을 커밋하는 데 필요한 시간과 본질적으로 동일합니다. 더 큰 변경에 필요한 추가 시간은 커밋 과정의 일부가 아니라 그에 앞선 리뷰에서 발생합니다.
- 버그 수정을 적용하는 작업의 추가 오버헤드는 대신 새 기능을 작업하도록 하는 추가적인 동기를 부여하며, 새 기능은 이미 본질적으로 작업하기에 더 흥미롭습니다. 새 기능에는 작업 흐름의 어려움이 도움을 더해 줄 필요가 없습니다!
- bugs.python.org에서 선행 리뷰를 받는 것은 추가적인 작업이므로 변경 사항을 직접 커밋하도록 하는 동기가 생기며, python-checkins 메일링 리스트의 사후 리뷰에 대한 의존도가 높아집니다.
- 트래커에 있는 완전하고 올바르며 병합할 준비가 된 패치도 이를 병합할 시간을 낼 수 있는 핵심 개발자를 기다리느라 여전히 오랫동안 방치될 수 있습니다.
- 푸시 경쟁의 위험, 특히 병합된 버그 수정을 푸시할 때의 위험은 전체 로컬 테스트 실행을 건너뛰고 싶은 유혹을 만듭니다. 특히 푸시 경쟁을 이미 한 번 겪은 후에는 더욱 그러하며, 이로 인해 빌드봇을 망가뜨릴 가능성이 높아집니다.
- 빌드봇은 때때로 오랫동안 오류 상태가 되어 로컬 테스트 실행에 오류를 유입하며, 패치가 플랫폼 간 문제를 도입했는지 여부를 신뢰할 수 있는 지표로 제공하지 못하는 경우도 있습니다.
- 컨퍼런스 후 개발 스프린트는 푸시 경쟁의 수렁으로 무너져 내리므로 악몽과 같습니다. 스프린트가 끝날 때까지 패치를 트래커에 그대로 두었다가 나중에 정리하고 싶은 유혹이 생깁니다.
또한 핵심 개발자가 다른 사람들에게 불편을 초래하는 실수를 저지를 가능성도 매우 많습니다. Mercurial 브랜치를 관리할 때도 그렇고, 즉시 수정할 수 없는 상황에서 빌드봇을 망가뜨릴 때도 그렇습니다. 이는 기존 핵심 개발 팀이 새 개발자에게 커밋 액세스 권한을 부여할 때 신중해지게 하며, 새 개발자들 역시 높아진 액세스 수준을 실제로 사용하는 데 신중해지게 합니다.
또한 NEWS 파일을 최신 상태로 유지하는 것과 같은 부수적인 불편도 있으며, 이러한 문제 역시 이 제안의 일부로 필연적으로 해결될 것입니다.
자원봉사자 중심 오픈 소스 프로젝트의 가장 중요한 자원 중 하나는 기여자들의 정서적 에너지입니다. 현재의 변경 사항 통합 방식은 누구에게도 이러한 측면에서 좋은 평가를 받지 못합니다.
- 핵심 개발자에게 버그 수정을 위한 브랜치 조정은 섬세하고 실수하기 쉽습니다. NEWS 파일의 충돌과 변경 사항을 업로드하려 할 때 발생하는 푸시 경쟁은 우리 대부분이 시간을 들인 대가를 받지 않는 일에 대한 짜증을 더합니다. 보수를 받는 사람들에게도 CPython 기여는 여러 책임 중 하나에 불과할 가능성이 높습니다. 변경 사항을 실제로 병합하는 데 쓰는 시간은 추가 변경 사항을 코딩하거나 문서를 작성 및 업데이트하거나 다른 사람의 기여를 검토하는 데 쓰지 못하는 시간입니다.
- 빨간 빌드봇은 다른 개발자들(로컬 테스트 실패가 해당 개발자가 수행한 작업 때문이 아닐 수 있기 때문입니다), 릴리스 관리자들(릴리스 전에 테스트 실패를 정리하는 데 도움을 요청해야 할 수도 있기 때문입니다), 그리고 개발자 자신들(보다 편리한 때가 아니라 바로 지금 우리가 부주의하게 도입한 실패를 수정해야 한다는 상당한 압박을 만들기 때문이며, 새로운 실패의 원인을 식별하는 데
hg annotate가 충분하지 않다면hg bisect를 사용하기 더 어렵게 만들 가능성도 있기 때문입니다)의 일을 어렵게 만듭니다. - 다른 기여자들에게 핵심 개발자가 변경 사항을 실제로 병합하는 데 시간을 쓰고 있다는 것은 이 개발자가 이슈 트래커의 패치를 검토하고 논의하거나 다른 사람들이 효과적으로 기여하도록 돕지 못하고 있다는 의미입니다. 이는 프로젝트의 CI 시스템에서 이미 자동으로 테스트된 풀 리퀘스트에서 개발자가 간단히 “Merge”를 누르기만 하면 되는 방식에 익숙한 기여자들에게 특히 답답한 일입니다. 이러한 작업 흐름은 GitHub나 BitBucket과 같은 사이트에서 일반적이며, 병합 과정의 사후 리뷰 부분이 완전히 자동화된 경우도 마찬가지입니다. OpenStack이 그 예입니다.
현재 도구
다음 도구는 현재 CPython 핵심 개발 작업 흐름의 여러 부분을 관리하는 데 사용됩니다.
- 버전 관리를 위한 Mercurial (hg.python.org)
- 이슈 추적을 위한 Roundup (bugs.python.org)
- 코드 리뷰를 위한 Rietveld (bugs.python.org에서도 호스팅됨)
- 자동화된 테스트를 위한 Buildbot (buildbot.python.org)
이 제안은 코드 리뷰에 Rietveld를 사용하는 대신 PEP 474에서 제안된, 더 많은 기능을 갖춘 Kallithea 기반 forge.python.org 서비스를 사용할 것을 제안합니다. Guido는 원래 Rietveld 구현이 주로 Google App Engine을 위한 공개 시연 애플리케이션으로 의도되었다고 밝혔으며, Kallithea로 전환하면 Roundup에서 패치 파일을 작업하고 통합된 Rietveld 인스턴스에서 관련 리뷰를 진행할 때 의도한 대상 브랜치를 식별하는 데 발생하는 일부 문제를 해결할 수 있습니다.
또한 작업 흐름의 추가 부분을 자동화할 수 있도록 새로운 도구를 추가하고, 어떤 도구가 교체 후보가 될 수 있는지 검토하기 위해 남은 도구를 비판적으로 검토할 것을 제안합니다.
제안
이 제안의 핵심은 CPython이 OpenStack 프로젝트에서 사용하는 것과 유사한 “핵심 리뷰어” 개발 모델을 채택하는 것을 목표로 삼는 것입니다.
CPython 핵심 개발 팀이 겪는 워크플로 문제는 고유한 것이 아닙니다. OpenStack 인프라 팀은 다음을 보장하도록 설계된 잘 설계된 자동화 워크플로를 고안했습니다:
- 패치를 검토한 후에는 병합 전에 자동화된 테스트가 실패하는 경우에만 추가적인 개발자 참여가 필요합니다
- 현재 브랜치 상태를 기준으로 테스트하지 않은 패치는 절대로 병합되지 않습니다
- 주 개발 브랜치는 항상 정상 상태를 유지합니다. 자동화된 테스트를 통과하지 못한 패치는 병합되지 않습니다
핵심 개발자가 병합 전에 패치를 수정하려는 경우, 소스 코드 저장소에 직접 푸시하는 대신 검토 도구에서 패치를 다운로드하여 수정한 후 검토 도구에 다시 업로드합니다.
이 워크플로의 핵심은 Zuul_이라는 도구를 사용하여 구현되며, Zuul은 OpenStack 프로젝트를 위해 특별히 제작된 Python 웹 서비스이지만, 다른 코드 검토 시스템, 이슈 추적 시스템 및 CI 시스템에 더 쉽게 적용할 수 있도록 플러그인 기반 트리거 및 작업 시스템을 사용하도록 의도적으로 설계되었습니다. OpenStack 인프라 팀의 James Blair는 linux.conf.au 2014에서 Zuul에 대한 훌륭한 개요 를 제공했습니다.
Zuul은 OpenStack의 여러 워크플로를 처리하지만, 이 PEP에서 관심을 두는 특정 워크플로는 “merge gating” 워크플로입니다.
이 워크플로에서 Zuul은 “Approved”로 표시된 패치를 찾기 위해 Gerrit 코드 검토 시스템을 모니터링하도록 구성됩니다. 이러한 패치를 발견하면 Zuul은 이를 가져와 “candidate merges” 큐에 결합합니다. 그런 다음 Jenkins에서 병렬로 실행되는 테스트 실행 파이프라인을 생성하고(전체 테스트 실행에 한 시간 가까이 걸릴 때 하루에 24개가 넘는 커밋을 허용하기 위해), 테스트를 통과하는 패치와 큐에서 그보다 앞선 모든 후보 병합이 테스트를 통과하는 대로 병합합니다. 패치가 테스트에 실패하면 Zuul은 해당 패치를 큐에서 제거하고, 큐에서 해당 패치 뒤에 있는 모든 테스트 실행을 취소하며, 실패한 패치 없이 큐를 다시 구성합니다.
개발자가 병합 시 실패한 테스트를 살펴보고 그것이 간헐적인 실패 때문이라고 판단하면, 패치를 다시 제출하여 병합을 재시도할 수 있습니다.
이 프로세스를 CPython에 적용하려면 Zuul이 승인된 풀 리퀘스트를 찾기 위해 Kallithea를 모니터링하고(Kallithea에 기능을 추가해야 할 수도 있습니다), 이를 안정 버전 빌드봇에서 테스트하도록 Buildbot에 제출한 다음, Mercurial에서 변경 사항을 적절하게 병합하도록 하는 것이 가능해야 합니다. 이 아이디어에는 몇 가지 기술적 과제가 있으며, 이에 대해서는 아래에 별도의 절이 있습니다.
CPython의 경우 Zuul의 병렬 테스트 실행 능력을 활용할 필요는 없을 것으로 생각합니다(적어도 초기 반복에서는 확실히 그렇습니다. 병합 게이팅 시스템에 의한 패치의 직렬 테스트가, 패치를 검토하고 승인하는 데 필요한 사람들을 확보하는 것보다 우리의 주요 병목이 되는 시점에 이른다면, 그것은 매우 좋은 날일 것입니다).
그러나 병합 큐 자체는 매우 강력한 개념이며, 위의 근거에서 설명한 여러 문제를 직접 해결할 수 있습니다.
연기된 제안
OpenStack 팀은 여러 다른 활동을 조정하는 데에도 Zuul을 사용합니다:
- Gerrit에 게시된 패치에 대해 예비 “check” 테스트 실행
- 변경 사항이 병합될 때 업데이트된 릴리스 산출물을 생성하고 문서를 다시 게시
- 사용자가 로그를 수동으로 검색하도록 요구하는 대신, 스팸 필터와 함께 ElasticSearch를 사용하여 테스트 출력을 모니터링하고 테스트 실패를 일으켰을 수 있는 구체적인 간헐적 실패를 제안하는 Elastic recheck기능
이러한 기능은 향후 살펴볼 가치가 있는 가능성이고(OpenStack 인프라 팀과 더 긴밀히 협력함으로써 얻을 수 있는 이점 중 하나라고 생각하는 부분이기도 합니다), 병합 게이팅이 제공하는 것으로 보이는 것과 같은 종류의 근본적인 워크플로 개선을 제공한다고는 생각하지 않습니다.
그러나 게이트에서 간헐적인 테스트 실패로 인해 너무 많은 문제를 겪고 있다는 사실을 발견한다면, 초기 배포의 일부로 “Elastic recheck” 기능을 도입하는 방안을 고려해야 할 수도 있습니다.
제안된 변형
Terry Reedy는 승인된 문서 전용 패치를 특별히 찾는 초기 필터를 수행하자고 제안했습니다(공개된 CPython 이슈 4000개 이상 중 약 700개는 순수한 문서 업데이트입니다). 이 접근 방식은 불안정한 테스트 및 플랫폼 간 테스트와 관련된 여러 문제를 피하면서, 나머지 자동화 흐름(예: 패치를 병합 큐에 넣는 방법)을 계속 구체화할 수 있게 합니다.
이 접근 방식의 주요 단점은 Zuul이 일반적으로 예상하는 것처럼 병합 프로세스를 완전히 제어할 수 없다는 것이므로, 이를 조율하기 위한 추가 협력이 필요할 가능성이 있다는 점입니다.
초기 배포에서 예상보다 테스트 신뢰성 문제가 더 많이 발생하는 것으로 나타날 경우를 대비한 대체 옵션으로 이 접근 방식을 유지할 만할 수 있습니다.
또한 병합 게이팅 기준을 조정하여 패치가 “Docs” 트리 외부의 파일을 수정하지 않았음을 감지하면 테스트 모음을 실행하지 않고, 대신 문서가 오류 없이 빌드되는지만 확인하도록 할 수도 있습니다.
또 다른 대안으로, 문서의 일부(예: 튜토리얼과 HOWTO 가이드)를 주 소스 저장소에서 분리하여 PEP 474에 설명된 더 단순한 풀 리퀘스트 기반 모델을 사용해 관리하는 것이 합리적일 수 있습니다.
예상되는 이점
이 제안의 이점은 가장 직접적으로 핵심 개발 팀에 돌아갑니다. 무엇보다도, 업데이트된 코드 리뷰 시스템에서 패치를 “Approved”로 표시하면 대개 작업이 끝납니다. 실제로 패치를 적용하고 테스트를 실행한 다음 Mercurial에 병합하는 데 추가로 필요한 20~30분(또는 그 이상)의 작업은 모두 Zuul이 조율하게 됩니다. 푸시 경쟁도 과거의 일이 됩니다. 스프린트에서 많은 핵심 개발자가 패치를 승인한다면, 이는 개발자가 변경 사항을 병합하려다 실패하며 좌절하는 대신 Zuul의 대기열이 더 길어진다는 의미일 뿐입니다. 테스트 실패는 여전히 발생하겠지만, 주 저장소의 코드를 손상시키는 대신 해당 패치가 병합 대기열에서 제거됩니다.
대부분의 시간 투자를 리뷰 프로세스로 옮기면 “리뷰 가능성을 고려한 개발”도 장려됩니다. 테스트를 여러 번 실행하는 오버헤드를 핵심 개발자가 아니라 Zuul이 부담하므로, 더 작고 리뷰하기 쉬운 패치를 작성하게 됩니다.
그러나 핵심 개발 팀에서 이러한 시간 소모를 제거하면 다른 기여자들의 CPython 개발 경험도 개선될 것입니다. 패치가 “방치되는” 기회를 여러 차례 없애는 동시에, 핵심 개발자가 기여된 패치를 리뷰하는 데 사용할 수 있는 시간도 늘어나기 때문입니다.
다른 기여자들에게 돌아가는 이점의 또 다른 예로, 주로 신규 기여자를 대상으로 하는 스프린트에 핵심 개발자가 한 명만 참여하는 경우(지난 몇 년간 PyCon AU에서 열린 스프린트 등), 병합 대기열을 통해 해당 개발자는 패치 리뷰와 스프린트의 다른 기여자 지원에 더 많은 시간을 집중할 수 있습니다. 패치를 포함하도록 승인하는 일이 현재의 비교적 시간이 많이 걸리는 프로세스가 아니라 이제 Kallithea UI에서 한 번 클릭하는 일이 되기 때문입니다. 여러 핵심 개발자가 참여하는 경우에도, 컴퓨터가 처리할 수 있고 처리해야 할 만큼 기계적인 작업보다 다른 스프린트 참가자들과 교류하는 데 시간과 노력을 사용할 수 있도록 하는 편이 더 좋습니다.
변경 사항을 커밋할 때 실수할 수 있는 대부분의 방법이 자동화로 사라지면, 기여자가 핵심 개발자가 되도록 지명되었을 때 새로 배워야 할 사항도 크게 줄어듭니다. 이는 기존 핵심 개발자가 추가적인 책임 수준을 부여하는 데 더 편안함을 느끼게 하고, 신규 기여자가 그 책임을 행사하는 데 더 편안함을 느끼게 하는 두 가지 이점을 가져올 것입니다.
마지막으로 CPython의 더 안정적인 기본 브랜치는 다른 Python 프로젝트가 새 릴리스의 릴리스 후보 단계까지 기다리지 않고 주 저장소를 대상으로 직접 지속적 통합을 수행하기 쉽게 만듭니다. 현재는 이러한 시스템을 설정하는 것이 그다지 매력적이지 않습니다. CPython 자체의 Buildbot 팜이 빌드가 사용 가능한 상태임을 나타낼 때까지 기다리는 추가 메커니즘을 포함해야 하기 때문입니다. 제안된 병합 게이팅 시스템을 사용하면 트렁크는 항상 사용 가능한 상태로 유지됩니다.
기술적 과제
OpenStack 인프라에서 CPython 인프라로 Zuul을 조정하려면 최소한 추가적인 Zuul 트리거 및 작업 플러그인을 개발해야 하며, 기존 도구 중 일부도 추가로 개발해야 할 수 있습니다.
Kallithea와 Gerrit
Kallithea에는 현재 Gerrit의 기능에 상응하는 투표/승인 기능이 포함되어 있지 않습니다. CPython에는 Gerrit의 투표 시스템만큼 정교한 기능이 필요하지 않습니다. Zuul의 작업을 트리거할 수 있는 단순한 핵심 개발자 전용 “Approved” 표시로 충분합니다. Roundup에는 핵심 개발자인지 여부를 나타내는 플래그가 있으며, 패치 업로더가 PSF 기여자 라이선스 계약에 서명했는지 여부를 나타내는 플래그도 있습니다. 이를 위해 Kallithea 인스턴스와 Roundup 간에 기여자 계정을 연결하는 추가 개발이 필요할 수 있습니다.
기존 Zuul 트리거 중 일부는 특정 댓글을 감시하는 방식으로 작동합니다(특히, 이전에 관련 없는 간헐적 실패로 인해 거부된 변경 사항의 병합을 Zuul에 다시 시도하도록 요청하는 recheck/reverify 댓글). Kallithea에도 이와 유사한 명시적 트리거가 필요할 가능성이 높습니다.
현재 Gerrit용 Zuul 플러그인은 특정 이벤트를 찾기 위해 Gerrit 활동 스트림을 감시하는 방식으로 작동합니다. Kallithea에 이에 상응하는 기능이 없다면, 트리거하려는 이벤트에 적합한 기능을 추가해야 합니다.
Gerrit 대신 Kallithea 활동을 감시하는 Zuul 플러그인을 만드는 개발 작업도 필요합니다.
Mercurial과 Gerrit/git
Gerrit은 패치의 실제 저장 메커니즘으로 git을 사용하며, 승인된 패치의 병합을 자동으로 처리합니다. 반면 Kallithea는 특정 DVCS 구현 위의 추상화 계층으로 RhodeCode가 만든 vcs 라이브러리를 사용합니다(현재 Mercurial 및 git 백엔드를 사용할 수 있습니다).
Zuul은 패치 조작을 위해 git과도 직접 통합되어 있으며, 제가 아는 한 이 설계 부분은 현재 플러그인 방식으로 교체할 수 없습니다. 그러나 PyCon US 2014에서 스프린트에 참여한 Mercurial 핵심 개발자들은 git뿐만 아니라 Mercurial에서도 Zuul을 사용할 수 있도록 핵심 개발 팀 및 Zuul 개발자들과 협력하는 데 관심을 표명했습니다. Zuul 자체가 Python 애플리케이션이므로, RhodeCode 및 Kallithea와 동일한 DVCS 추상화 라이브러리를 사용하도록 마이그레이션하는 것이 이를 달성하기 위한 실행 가능한 경로일 수 있습니다.
Buildbot 대 Jenkins
Zuul의 CI 시스템과의 상호 작용도 플러그인 방식으로 교체할 수 있으며, Gearman을 선호 인터페이스 로 사용합니다. 따라서 CI 작업을 Jenkins가 아닌 Buildbot에서 실행하도록 조정하는 일은 Zuul의 요청을 처리하여 Buildbot 마스터로 전달할 수 있는 Gearman 클라이언트를 작성하는 것만으로 해결될 것입니다. Zuul은 Gearman과 통신하기 위해 순수 Python gear 클라이언트 라이브러리를 사용하며, 이 라이브러리는 Buildbot 측 작업을 처리하는 데에도 유용할 것입니다.
초기 단계에서는 테스트 실행을 파이프라인화하려고 시도하지 않도록 제안한다는 점에 유의하십시오. 이는 Zuul이 매우 단순한 모드로 실행되어, 여러 패치를 병렬로 테스트하는 대신 병합 대기열 선두의 패치만 Buildbot 팜에서 테스트한다는 의미입니다. Buildbot 마스터에 강제 빌드를 요청한 다음, 대기열의 두 번째 패치로 넘어가기 전에 결과가 돌아오기를 기다리는 것과 같은 방식을 생각하고 있습니다.
궁극적으로 이것이 충분하지 않다고 판단하여 Zuul의 CI 파이프라인 기능을 사용하기 시작해야 한다면, 현재처럼 자원봉사자가 유지 관리하는 정적으로 프로비저닝된 시스템에 의존하기보다는 테스트 실행을 동적으로 프로비저닝된 클라우드 이미지로 옮기는 방안을 검토해야 할 수 있습니다. OpenStack CI 인프라 팀은 현재 Jenkins 마스터를 더 단순한 순수 Python 테스트 실행기로 교체하는 방안을 모색하고 있으므로, Buildbot이 파이프라인화된 테스트 모델을 효과적으로 지원하도록 만들 수 없다면 CPython용 Jenkins 인스턴스를 설정하기보다는 그 작업에 참여할 가능성이 높습니다.
이 경우 주요 기술적 위험은 Linux 이외의 플랫폼에서도 테스트를 지원하도록 보장하는 문제입니다. 현재 안정 버전 빌드봇은 서로 다른 Linux 변형 몇 가지에 더해 Windows, Mac OS X, FreeBSD 및 OpenIndiana를 지원합니다.
이러한 시나리오에서도 Buildbot 팜은 마스터 저장소에 대해 “check” 실행을 수행하는 역할을 계속 맡을 수 있으며, 이는 정기적으로 수행하거나 모든 커밋마다 수행할 수 있습니다. 병합 게이팅 프로세스에서 역할을 하지 않더라도 그러합니다. 스레드 없이 빌드하거나 SSL/TLS 지원 없이 빌드하는 등의 더 특수한 구성은 게이트 기준에 포함하기보다는 (적어도 초기에는) 여전히 이러한 방식으로 처리할 가능성이 높습니다.
유지 관리 브랜치 처리
OpenStack 프로젝트는 유지 관리 브랜치 문제를 직접 처리하기보다는 대체로 다운스트림 공급업체에 맡깁니다. 이는 자체 유지 관리 브랜치를 처리하도록 Zuul을 조정하는 방법과 관련하여 답해야 할 질문이 있음을 의미합니다.
Python 2.7은 별도의 패치 대기열로 취급하면 충분히 쉽게 처리할 수 있습니다. Kallithea에서는 Python 2.7 유지 관리 브랜치를 업데이트하기 위해 별도의 풀 리퀘스트를 제출하는 방식으로 이를 기본적으로 처리할 수 있습니다.
Python 3.x 유지 관리 브랜치는 잠재적으로 더 복잡합니다. 현재 제안은 해당 브랜치를 관리하는 데 Mercurial 병합을 사용하는 것을 중단하고, 대신 Python 2.7 브랜치와 유사하게 독립적인 헤드로 취급하는 것입니다. 활성 Python 3 유지 관리 브랜치와 기본 개발 브랜치에 대해 별도의 풀 리퀘스트를 제출해야 합니다. 이 접근 방식의 단점은 수정 사항이 기본 브랜치에는 제출되지 않은 채 유지 관리 브랜치에만 병합될 위험을 높인다는 점입니다. 따라서 모든 유지 관리 브랜치 풀 리퀘스트가 병합되기 전에 이에 대응하는 기본 브랜치 풀 리퀘스트를 갖도록 보장하거나, 해당 브랜치에만 적용되며 이후 브랜치로 포팅할 필요가 없음을 명시적으로 밝히는 면책 문구를 포함하도록 하는 추가 도구를 설계할 필요가 있을 수 있습니다.
이러한 접근 방식은 Python 3 유지 관리 브랜치가 두 개 활성화되는 간헐적인 기간에도 비교적 깔끔하게 대응할 수 있다는 장점이 있습니다.
이 문제는 Kallithea의 잠재적인 사용자 인터페이스 아이디어를 제시하기도 합니다. 두 번째 브랜치에 적용할 수 있도록 풀 리퀘스트를 복제하는 기능이 바람직할 수 있습니다.
보안 브랜치 처리
단순성을 위해 보안 수정 전용 브랜치의 처리는 현재 방식 그대로 두는 것이 좋겠습니다. 해당 브랜치의 릴리스 관리자는 계속해서 특정 변경 사항을 수동으로 백포트하게 됩니다. 유일한 변경 사항은 병합 전에 다른 사람들이 업데이트를 검토하기를 원하는 경우, 백포트에 Kallithea 풀 리퀘스트 워크플로를 사용할 수 있게 된다는 점입니다.
NEWS 파일 업데이트 처리
현재 NEWS 파일 업데이트 처리 방식은 활성 유지 관리 브랜치에서 이후 브랜치로 버그 수정 사항을 병합할 때 정기적으로 불필요한 충돌을 일으킵니다.
Issue #18967* 에서는 이 영역에서 가능한 몇 가지 개선 사항을 논의하며, Zuul을 워크플로 자동화 도구로 채택하는지 여부와 관계없이 이러한 개선은 유익할 것입니다.
“stable” Buildbot 슬레이브의 안정성
명목상 안정적인 빌드봇의 불안정성은 이 제안에서 상당히 더 큰 영향을 미칩니다. 개발 브랜치로의 병합을 승인하는 각 시스템에 대해 우리가 진정으로 만족하는지 확인해야 하며, 그렇지 않으면 해당 시스템을 “unstable” 상태로 변경해야 합니다.
간헐적인 테스트 실패
기존 Buildbot 플릿의 일부 테스트, 특히 타이밍 테스트는 간헐적으로 실패합니다. 특히 가상 머신으로 실행되는 테스트 시스템은 VM 호스트의 부하가 정상보다 높을 때 간혹 타이밍 실패를 보일 수 있습니다.
OpenStack CI 인프라에는 간헐적인 실패에 대응하는 데 도움이 되는 여러 추가 기능이 포함되어 있으며, 그중 가장 기본적인 기능은 원래 실패가 알려진 간헐적 실패 때문인 것으로 보일 때 개발자가 패치 병합을 다시 시도하도록 요청할 수 있게 하는 것입니다(해당 간헐적 실패가 OpenStack 자체에서 발생했든 단지 불안정한 테스트에서 발생했든 관계없습니다).
더 정교한 Elastic recheck 기능을 고려할 가치가 있을 수 있습니다. 특히 CPython 테스트 모음의 출력은 OpenStack의 더 복잡한 다중 서비스 테스트 출력보다 상당히 단순하므로 자동 분석에 훨씬 더 적합할 가능성이 높습니다.
사용자 지정 Mercurial 클라이언트 워크플로 지원
OpenStack 워크플로에서 유용한 부분 중 하나는 “git review” 플러그인입니다. 이 플러그인을 사용하면 로컬 git 클론에서 브랜치를 Gerrit으로 올려 검토받기가 비교적 쉽습니다.
PEP 474에서는 기존 CPython 핵심 개발 워크플로의 일부 측면을 자동화하는 초안 custom Mercurial extension을 언급합니다.
이 제안의 일부로 해당 사용자 지정 확장을 기존 Roundup/Rietveld 기반 검토 워크플로뿐만 아니라 새로운 Kallithea 기반 검토 워크플로에서도 작동하도록 확장합니다.
사회적 과제
여기서 주요 사회적 과제는 핵심 개발 팀이 관행을 바꾸도록 하는 것입니다. 그러나 이 제안으로 자동화되는 번거롭지만 필요한 단계는 기존 개발자들이 이 방안을 따르도록 강력한 동기를 부여할 것입니다.
기존 개발자들에게 이 워크플로 자동화의 단점이 없다는 확신을 주려면 다음 세 가지 구체적인 기능이 필요할 수 있다고 생각합니다.
- 패치를 통합하는 데 핵심 개발자 한 명의 승인만 요구합니다. 이는 향후에 재검토할 수 있지만, 최초 도입 시에는 현재 상태를 유지해야 합니다.
- 릴리스 후보 단계 중인 경우를 제외하고 핵심 개발자가 자신의 패치를 승인할 수 있는 자유를 계속 유지한다는 점을 명시적으로 밝힙니다. 이는 향후에 재검토할 수 있지만, 최초 도입 시에는 현재 상태를 유지해야 합니다.
- 최소한 릴리스 관리자가 특정 패치를 병합 대기열의 선두로 강제할 수 있는 “merge it now” 기능을 갖도록 합니다. 릴리스 준비에 별도의 클론을 사용하는 것으로 이 목적을 충분히 달성할 수 있습니다. 장기적으로는 자동 병합 게이팅을 통해 릴리스 산출물 준비도 더욱 자동화할 수 있습니다.
실무적 과제
PSF는 일반 대중에게 무료로 제공되는 인프라의 용납할 수 없을 정도로 낮은 성능과 유연성 부족을 과거에 경험했기 때문에, 주로 직접 또는 간접적으로 후원받는 자체 워크플로 인프라를 운영합니다. CPython 개발은 원래 SourceForge에서 호스팅되었지만, SF가 Subversion 지원 제공에 늦고 CVS 성능 문제도 겪자 소스 제어를 자체 호스팅으로 이전했습니다( PEP 347 참조). 이후 이슈 추적은 SF의 성능 문제와 당시 SF 추적기의 전반적인 사용성 문제로 인해, 전용 후원 호스팅(Upfront Systems 제공)의 오픈 소스 Roundup 이슈 추적기로 이전했습니다(새 추적기 선정 결과와 과정은 PEP가 아니라 python.org wiki에 기록되었습니다).
따라서 “SourceForge 사용성과 신뢰성 문제, 2차전”을 겪게 만드는 제안은 CPython 핵심 개발 팀의 일부 구성원(이 PEP의 작성자 포함)으로부터 상당한 반대에 직면할 것입니다. 이 제안은 후원받거나 PSF가 자금을 지원하는 인프라로 자체 호스팅할 수 있고, CPython 핵심 개발 팀의 요구에 맞게 사용자 지정할 수 있는 오픈 소스 Python 프로젝트인 도구만 권장함으로써 그러한 역사를 존중합니다.
그러나 이 제안이 성공하려면(채택될 경우), 필요한 구성, 사용자 지정, 통합 및 배포 작업을 어떻게 수행할 것인지 파악해야 합니다.
CPython 지원 인프라에 새로운 구성 요소(speed.python.org)를 추가하려던 마지막 시도는 관련 핵심 개발자와 PSF 이사회 구성원들이 프로젝트를 추진할 시간이 부족했고, 다른 사람을 활동을 이끌 수 있을 정도로 교육하는 데 어려움이 있었기 때문에 안타깝게도 좌초되었습니다(HP가 해당 프로젝트에 기증한 하드웨어는 현재 대신 PyPy 지원에 사용되고 있지만, 이러한 상황은 다른 많은 우선순위 높은 요구로 시간이 부족한 자원봉사 인력에 의존하여 프로젝트를 완료까지 이끄는 데 따르는 몇 가지 과제를 잘 보여 줍니다).
궁극적으로 성공한 과거 프로젝트들조차도 CVS에서 Subversion으로, Subversion에서 Mercurial로의 소스 제어 마이그레이션, SourceForge에서 Roundup으로의 이슈 추적기 마이그레이션, Roundup과 Rietveld 간 코드 검토 통합, Buildbot 지속적 통합 플릿 도입과 같이, 자원봉사자들이 관련된 수많은 기술적·사회적 과제를 해결해 나가는 데 오랜 시간이 걸렸습니다.
다행히 이 제안과 PEP 474의 여러 측면이 Red Hat의 Beaker 오픈 소스 하드웨어 통합 테스트 시스템 및 기타 업무 관련 프로젝트에서 검토 중인 다양한 워크플로 개선 사항과 부합하므로, CPython 인프라 프로젝트 작업에 주당 ~1일을 할애할 수 있도록 준비했습니다.
Rackspace가 기존에 pypi.python.org 인프라를 유지 관리하는 데 기여하고 있는 것과 더불어, 저는 개인적으로 이러한 방식이 CPython 재배포자와 주요 사용자들 사이에서 자원 봉사 기여자들이 여가 시간 전부를 들여 해당 인프라를 유지 관리하거나 PSF를 통해 간접적으로 자금을 지원하기를 기대하기보다는, 개발자 시간을 직접 기여하여 업스트림 인프라를 유지하는 데 도움을 주는 것이 가치 있다는 보다 일반적인 인식을 보여 준다고 생각합니다(그에 따르는 추가 관리 부담도 발생합니다). 저는 이를 긍정적인 추세로 여기며, 제가 할 수 있는 최선을 다해 계속 장려할 것입니다.
미해결 질문
사실상 PEP의 거의 모든 내용입니다. 머지 게이팅과 Zuul을 도입하시겠습니까? 다양한 기술적 과제에 어떻게 대응하시겠습니까? Kallithea 및 Zuul 개발 커뮤니티는 이 작업을 성공시키는 데 필요한 종류의 협력에 개방적입니까?
제가 이 작업에 개인 업무 시간의 일부를 할애하도록 조정해 두기는 했지만, OpenStack 자체의 핵심 의존 프로젝트이고 Zuul이 OpenStack 인프라 팀의 창작물이며 현재 OpenStack에 이용 가능한 개발 리소스가 CPython의 리소스를 크게 능가하므로, 추가 지원을 위해 OpenStack 재단에 접근하시겠습니까?
Python 재배포자와 주요 사용자를 위해 일하는 다른 관심 있는 분들도 이 작업을 지원하는 데 개발자 시간을 투자하도록 상급자에게 사업적 근거를 제시할 수 있는 입장입니까?
다음 단계
이 작업을 추진한다면 PEP 474에 제안된 Kallithea 기반 forge.python.org 프로젝트의 후속 프로젝트가 될 것입니다. 현재 진행 중인 논의, 검토 및 개념 증명 파일럿 과정에 대한 자세한 내용은 해당 PEP를 참조하십시오.
감사의 말
이 제안의 예비 초안에 귀중한 피드백을 제공해 주신 Jesse Noller, Alex Gaynor 및 James Blair에게 감사드리며, 초기 초안이 발표된 후 추가적인 기술 피드백을 제공해 주신 James와 Monty Taylor에게도 감사드립니다.
기존 Rietveld 설치 대신 검토 구성 요소에 Kallithea를 사용하는 것을 기반으로 이 제안을 크게 수정하게 된 PEP 474를 둘러싼 논의에 참여해 주신 Bradley Kuhn, Mads Kiellerich 및 다른 Kallithea 개발자분들께 감사드립니다.
Copyright
This document has been placed in the public domain.