CI 중심 개발을 피하는 방법…


45

저는 다른 많은 정기적 인 기여자들과 함께 대규모의 연구 주도형 오픈 소스 프로젝트를 진행하고 있습니다. 현재 프로젝트 규모가 상당히 크기 때문에, 2 명의 정규직 직원과 소수의 구성원으로 구성된 컨소시엄이 프로젝트 유지 관리, 지속적인 통합 (CI) 등을 담당합니다. 외부 통합을위한 시간이 없습니다. 그래도 기여.

이 프로젝트는 "핵심"프레임 워크, 약 50 만 줄 정도의 코드 라인, 컨소시엄에서 유지 관리하는 "플러그인"및 여러 외부 플러그인으로 구성됩니다. 심지어는 알지 못한다.

현재 CI는 핵심 및 유지 관리 플러그인을 빌드합니다.

우리가 직면 한 가장 큰 문제 중 하나는 대부분의 기고자 (특히 비정기적인 것)가 유지 보수 된 플러그인의 90 %를 구축하지 않기 때문에 코어에서 리팩토링 변경을 제안 할 때 (요즘 꽤 정기적으로 발생 함), 그들은 GitHub에서 풀 요청을하기 전에 코드가 머신에서 컴파일되는지 확인했습니다.

코드가 작동하고 만족 스러우면 CI가 빌드를 완료하고 문제가 시작됩니다. 컨소시엄이 유지 관리하는 플러그인에서 컴파일이 실패하여 컨트 리뷰 터가 자신의 머신을 빌드하지 않았습니다.

해당 플러그인은 CUDA 와 같은 타사 라이브러리에 의존 할 수 있으며 사용자는 원하는 플러그인을 원하지 않거나, 하드웨어적인 이유로 간단하게 컴파일 할 수없는 방법을 모릅니다.

그럼 - 일 수-합병 결코-에-의 림보의 PR 체류 광고 aeternam 의 PR을 - 또는 기여자, 깨진 플러그인의 소스에서 이름이 바뀐 변수를 greps의 코드, 그 / 그녀의 분기에 밀어, 대기 변경 CI는 컴파일을 마치고 일반적으로 오류가 더 많이 발생하고 CI가 만족할 때까지 프로세스를 반복합니다. 또는 컨소시엄에서 이미 초과 예약 된 2 명의 지속 물 중 하나가 손을 잡고 머신에서 PR을 수정하려고합니다.

이러한 옵션 중 어느 것도 실행 가능하지는 않지만 다른 방법을 모릅니다. 프로젝트의 비슷한 상황에 직면 한 적이 있습니까? 그렇다면 어떻게이 문제를 처리 했습니까? 여기에 보이지 않는 해결책이 있습니까?


84
시스템에 플러그인 API를 제공하는 가장 중요한 규칙은 안정적으로 유지 되거나 최소한 이전 버전과 호환 된다는 것입니다 . 의도적으로 플러그인 API를 변경하지 않고 코어를 변경하면 플러그인 컴파일이 중단되지 않습니다 (사고로 기능이 중단 될 수는 있지만 컴파일이 아님). 코어 내부에서 변수 이름을 간단하게 변경 하면 플러그인 컴파일이 중단 될 수 있으면 플러그인과 코어 사이의 분리가 완전히 깨진 것처럼 보입니다.
Doc Brown

Martin Fowler의 "Public vs Published Interfaces" 는 유용한 정보 일 것입니다.
Schwern

1
@KevinKrumwiede : 나는 그들이 이미 이것을 알고 있다고 확신한다 ;-) 만약 당신이 비 호환성을 경험했다면, 그들이 의도적으로 API를 변경했다고 확신한다.
Doc Brown

3
나는 실제로 오도하기 때문에 질문을 다시 말하고 싶습니다. 같은 뭔가 가 현재의 CI를 깰 때 어떻게의 PR을 관리 할 수 있습니까? 내가 생각하는 상황을 더 잘 포착하십시오.
bracco23

2
빌드 / 테스트 프로세스는 얼마나 어렵고 복잡한가? 단일 명령을 실행하거나 단일 버튼을 클릭하기 만하면됩니다. 이 시점에서 사용자는 PR을 제출하기 전에 모든 테스트를 스스로 수행해야합니다.
Alexander

답변:


68

CI 중심 개발은 괜찮습니다! 테스트를 실행하지 않고 깨진 코드를 포함하는 것보다 훨씬 좋습니다! 그러나 관련된 모든 사람에게 이것을 쉽게하기 위해 몇 가지가 있습니다.

  • 기대치 설정 : CI가 종종 추가 문제를 발견하고 이러한 문제를 병합하기 전에 수정해야한다는 설명 문서를 제공하십시오. 아마도 소규모의 로컬 변경이 잘 작동 할 가능성이 높기 때문에 큰 변경을 여러 PR로 나누는 것이 합리적 일 수 있습니다.

  • 로컬 테스트 권장 : 시스템에 대한 테스트 환경을 쉽게 설정할 수 있습니다. 모든 종속성이 설치되었는지 확인하는 스크립트? 준비가 된 Docker 컨테이너? 가상 머신 이미지? 테스트 러너에는 더 중요한 테스트의 우선 순위를 지정할 수있는 메커니즘이 있습니까?

  • CI를 스스로 사용하는 방법을 설명 하십시오. 좌절의 일부는이 피드백이 PR을 제출 한 후에 만 ​​제공된다는 것입니다. 기고자가 자신의 리포지토리에 대해 CI를 설정하면 더 빠른 피드백을 받고 다른 사람에게 적은 CI 알림을 생성합니다.

  • 어떤 방법 으로든 모든 PR을 해결하십시오. 문제가 발생 하여 병합 할 수없고 문제를 해결하는 데 진전이없는 경우 닫으십시오. 이렇게 버려진 공개 PR은 모든 것을 혼란스럽게 만들고 피드백을 문제를 무시하는 것보다 낫습니다. 이것을 매우 훌륭하게 표현할 수 있으며, 문제가 해결되면 기꺼이 병합 할 수 있음을 분명히하십시오. (또한 참조 : Jessie Frazelle 의 마감 기술 , 관리자를위한 모범 사례 : 아니요 말하기 학습 )

    또한 포기 된 PR을 검색 가능하게하여 다른 사람이 선택할 수 있도록하십시오. 남은 문제가 더 기계적이고 시스템에 대해 잘 모르는 경우, 새로운 기고자에게 좋은 작업 일 수 있습니다.

장기적인 관점에서 볼 때 이러한 변경은 관련없는 기능을 중단하는 것처럼 보이므로 현재 디자인이 약간 문제가 될 수 있습니다. 예를 들어, 플러그인 인터페이스가 코어의 내부를 올바르게 캡슐화합니까? C ++을 사용하면 실수로 구현 세부 정보를 유출 할 수 있지만 오용하기 매우 어려운 강력한 추상화를 만들 수도 있습니다. 밤새도록 변경할 수는 없지만 소프트웨어의 장기적인 발전을 덜 취약한 아키텍처로 발전시킬 수 있습니다.


13
"이 버려진 공개 PR은 모든 것을 어지럽히고 있습니다"나는 더 많은 관리자가 이런 태도를 갖기를 바랍니다.
GammaGames

34

지속 가능한 플러그인 모델을 구축하려면 핵심 프레임 워크가 플러그인이 신뢰할 수있는 안정적인 인터페이스를 노출해야합니다. 가장 중요한 규칙은 시간이 지남에 따라 새 인터페이스를 도입 할 수 있지만 이미 게시 된 인터페이스를 수정할 수는 없다는 것입니다. 이 규칙을 준수하면 컨소시엄이 유지 관리하는 플러그인이든 외부 플러그인이든 플러그인을 실수로 중단 할 염려없이 원하는 핵심 프레임 워크 구현 을 리팩토링 할 수 있습니다 .

당신이 묘사 한 것에서, 당신은 잘 정의 된 인터페이스가없는 것처럼 들리므로 변경 사항이 플러그인을 깨뜨릴 수 있는지 알기가 어렵습니다. 이 인터페이스를 정의하고 코드베이스에 명시 적으로 작성하여 기고자가 수정하지 않아야 할 사항을 알 수 있도록하십시오.


20
CI에는 자동화 된 테스트가 있어야합니다. 플러그인이 동일한 인터페이스를 갖도록하려면 모든 플러그인이 필요한 인터페이스를 나타내는 테스트에 기여해야합니다. 이 방법으로 인터페이스가 바뀌면 어떤 플러그인을 사용하고 있는지 알 수 있습니다. 이 테스트를 로컬에서 실행하고 PR을 발행하기 전에 내가 겪고있는 것을 알게 될 것입니다.
candied_orange

1
@lagarkane 잘 정의 된 것은 기술적 인 것보다 정책적인 문제입니다. 거기에는 업그레이드와 같은 이전 동작을 버리는 소프트웨어가 있습니다. Perl5는 Perl6과 호환되지 않으며, Python2.7은 Python3.4 등과 완전히 호환되지 않습니다. 그런 다음 이전 코드를 지원하는 소프트웨어가 있습니다. 최신 브라우저에서 Netscape Navigator 4 용으로 작성된 거의 모든 자바 스크립트 코드를 계속 실행할 수 있습니다. Tcl 프로그래밍 언어는 원래 버전과 같은 방식으로 백 워드 호환됩니다 ...
slebetman

3
@lagarkane : 컨소시엄 형성은 올바른 방향으로 나아가는 단계이며 핵심 구성원이 이러한 인터페이스를 구성하는 데 에너지를 집중하면 미래의 박사 및 인턴의 힘을 활용하여 프로젝트를 강력하게 유지하면서 중단을 최소화 할 수 있습니다. :)
카사 블랑카

4
@Fattie : Apple은 소비자를 대상으로 한 성공적인 제품을 개발하고 개발자가 제품에 참여하기를 원하기 때문에 Apple에 적합합니다. 이러한 개발자가 실제로 변경 내용을 변경하는 것을 좋아할 가능성은 없으며 오픈 소스 프로젝트에는 적합하지 않습니다.
카사 블랑카

1
@casablanca는 MacOS와 WindowsOS 계보 모두 매우 성공적입니다. (아마도, 인간 존재에서 달러 기준으로 가장 큰 두 가지 제품) 수십 년 동안 그들은 완전히 반대의 접근법을 가졌습니다. 분명히 둘 다 성공했습니다!
Fattie

8

솔직히 말해서, 당신이 이것을 더 잘 처리 할 수 ​​있다고 생각하지 않습니다. 변경으로 인해 프로젝트유지 보수 부분 이 중단되면 CI가 실패해야합니다.

프로젝트에 contributing.md신규 및 비정기 공헌자가 기여를 준비하는 데 도움 이되는 비슷한 것이 있습니까? 어떤 플러그인이 핵심 구성 요소이며 호환성을 유지해야하는 명확한 목록이 있습니까?

의존성 등으로 인해 머신에 모든 것을 구축하기 어려운 경우 기꺼이 사용할 도커 이미지를 빌드 환경으로 만드는 것에 대해 생각할 수 있습니다.


1
답장을 보내 주셔서 감사합니다! 예, 공개적으로 제공되는 기여 가이드 라인이 있지만 제안한대로 플러그인을 나열하지 않았으므로 이미 좋은 아이디어입니다. 도커 이미지를 만드는 것은 현재 기여 프로세스를 크게 개선하는 것처럼 들립니다! 의견을 보내 주셔서 감사합니다
lagarkane

8

그래서 코어에서 리팩토링 변경을 제안 할 때 (요즘 꽤 정기적으로 발생합니다) github에서 풀 요청을하기 전에 코드가 컴퓨터에서 컴파일되는지 확인했습니다.

그래서 이것이 느슨한 스타일의 오픈 소스 프로젝트가 무너질 수있는 곳이라고 생각합니다. 대부분의 중앙에서 구성된 프로젝트는 특히 API 경계를 넘을 때 핵심 리팩토링에주의합니다. 그들이 API 경계 리팩토링 할 경우 모든 변경 사항이 API의 주요 버전으로 증가로 한 번에 예정에 "빅뱅은"보통의, 그리고 기존의 API가 유지된다.

"모든 API 변경을 미리 계획해야합니다"라는 규칙을 제안합니다. PR과 관련하여 유지 보수 담당자와 접촉하지 않은 사람으로부터 API에 대한 이전 버전과 호환되지 않는 변경을하는 경우 사전에 접근 방식에 동의합니다. 단순히 닫히고 제출자는 규칙을 가리 킵니다.

플러그인 API의 명시 적 버전도 필요합니다. 이렇게하면 모든 v1 플러그인이 계속 빌드되고 작동하는 동안 v2를 개발할 수 있습니다.

또한 많은 핵심 리팩토링과 API 변경이 이루어지고 있는지 조금 더 의문을 제기 할 것 입니다. 그들은 정말로 필요합니까 아니면 프로젝트에 개인적인 취향을 부여하는 사람들입니까?


2

CI 프로세스와 같은 소리는 PR을 제기하기 전에 기고자에게 더 강력하고 포괄적이며 가시적이어야합니다. 예를 들어 BitBucket에는 파이프 라인 기능이있어이를 통해 CI 빌드 프로세스를 코드로 정의하는 파일을 제공하고 실패하면 분기가 병합되지 않습니다.

기술에 관계없이 기고자가 지점에 푸시 할 때 자동 빌드를 제공하면 변경시주의해야 할 사항에 대해 훨씬 더 빠른 피드백을 제공 할 수 있으며 사실 이후 수정하지 않아도되는 PR로 이어질 수 있습니다.

디자인 문제는 해결하는 것이 좋지만이 문제와 직교합니다.


2

코드가 작동하고 만족 스러우면 CI가 빌드를 완료하고 문제가 시작됩니다. 컨소시엄이 유지 관리하는 플러그인에서 컴파일이 실패하여 컨트 리뷰 터가 자신의 머신을 빌드하지 않았습니다.

그 플러그인은 CUDA와 같은 타사 라이브러리에 의존 할 수 있으며, 사용자는 원하는 플러그인을 원치 않거나, 모르는 것, 또는 단순히 하드웨어상의 이유로 컴파일 할 수 없습니다.

해결책은 간단합니다. 기여 장벽을 낮추십시오 .

(1) 편집 컴파일 테스트주기를 단축하고 (2) 원활한 환경 차이를 만드는 가장 간단한 방법은 빌드 서버 를 제공 하는 것입니다 .

  • 24, 48 또는 96 코어, 2GB RAM / 코어, SSD와 같은 강력한 시스템을 사용하여 컴파일 속도를 높입니다.
  • FPGA, 그래픽 카드 등 필요한 하드웨어가 올바른지 확인하십시오.
  • 필요한 모든 소프트웨어 라이브러리가 사전 설치된 Docker 이미지를 작성하십시오.

그런 다음 기고자에게 해당 빌드 서버를 엽니 다. 그들은 새로운 Docker 이미지에 원격으로 로그인 하고이 컴퓨터에서 원격으로 편집 컴파일 테스트 할 수 있어야합니다.

그때:

  • 유지 관리되는 플러그인을 빌드 / 테스트하지 않는 것에 대한 변명은 없습니다. 사용 가능한 모든 것이 있습니다.
  • CI 기반 PR로 긴 피드백을 기다릴 필요가 없습니다. 증분 컴파일 및 디버그 기능 (추측이 아닌)이 있습니다.

일반적으로 빌드 서버는 여러 기고자간에 공유 될 수 있지만 특수 하드웨어 주변 장치가 관련된 경우 기고자가 자체적으로 주변 장치를 사용해야 할 수 있습니다.


출처 : 짐승의 가격과 필요한 다양한 모델을 고려하여 FPGA를 사용하여 소프트웨어 작업을 수행하는 경우 모든 개발자의 컴퓨터에 설치된 FPGA의 각 모델을 찾을 수는 없습니다.


1

계약을 변경하지 않고 코어에 기여하면 종속 소프트웨어가 손상 될 수있는 경우 다음 중 하나를 제안합니다.

  • 인터페이스 계약이 모호 할 수 있습니다. 함수 및 함수 매개 변수에 특성을 추가하면 계약을보다 명확하게하기 위해 클라이언트 코드에 추가 제약 조건을 노출하는 데 도움이 될 수 있습니다. 또는 계약을 변경하는 변경 사항을 적용하는 경우 시맨틱 버전 관리를 채택하면 도움이 될 수 있습니다.
  • 단위 테스트가 가능한 통화 시나리오를 충분히 다루지 못하고 있습니다.

문제는 해결하기 쉬워야하지만 핵심 팀이이를 수행 할 능력이 없을 수도 있습니다. 한 가지 옵션은이 문제를 해결하는 데 도움을 요청하는 것입니다.


1

아무도 이것을 잠재적 인 해결책으로 제기하지 않은 것 같습니다.

  • 액세스 할 수있는 모든 플러그인을 나열하십시오.
  • 이 플러그인이 정의한 모든 테스트를 실행하십시오.
  • 코어와 모든 플러그인 사이의 모든 요청 / 응답 / 상호 작용 기록
  • 이러한 기록을 저장하면 이제 대략적인 호환성 테스트입니다.

핵심을 개발할 때 개발자가 이러한 호환성 테스트를 실행하도록 권장하십시오. 실패하면 체크인하지 마십시오.

이것은 100 % 호환성을 보장하지는 않지만 훨씬 더 많은 문제를 조기에 포착합니다.

두 번째 이점은 이러한 레코딩이 현재 사용중인 인터페이스와 현재 사용중인 기능을 강조 할 수 있다는 것입니다.


0

상황이 다음과 같이 이해되는 데 어려움이 있습니다. CI는 하나의 지점 만 작성합니까?

CI로 둘 이상의 브랜치를 구축 할 수없는 이유가 있습니까?

이 문제에 대한 가장 간단한 해결책 은 모든 제공자가 자신의 기능 분기에서 CI 빌드를 실행할 수있게하는 것 입니다.

그런 다음 해당 지점의 풀 요청을 수락하려면 기능 지점에서 성공적인 CI 빌드가 필요합니다.


이것은 문제를 요약 한 것으로 보입니다.
Fattie

1
질문에 "또는 기고자 [...]가 코드를 변경하고 분기를 푸시하며 CI 컴파일이 완료 될 때까지 기다렸다가 일반적으로 더 많은 오류가 발생하고 CI가 행복해질 때까지 프로세스를 반복합니다"라고 말합니다. 이미 문제가 있지만 문제는 긴 편집 디버그 주기로 개발하기가 다소 고통 스럽다는 것입니다.
npostavs

@npostavs 고마워, 내가 처음 읽었거나 두 번이나 그것을 읽은 것 같아요. 그럼에도 불구하고 ... 문제가 아닌 것 같습니다. 많은 종속성이 있으므로 깨질 수 없으므로 기고자는 모든 호환성을 유지해야합니다. 이것이 큰 소프트웨어의 본질입니다. 확실히 빌드를 더 빨리 만들기 위해 노력할 수 있지만, 그렇지 않으면 어떤 지름길이있을 수 있습니까?
Kyralessa
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.