지속적인 통합으로 점점 더 다양한 코드베이스를 유지


10

지속적인 통합 설정의 철학과 디자인에 대한 도움이 필요합니다.

현재 CI 설정은 buildbot을 사용합니다. 디자인을 시작했을 때 전체 빌드를 한 번에 밤새 실행하도록 맞춤화 된 맞춤형 CI 빌더 (1 년 전 디자인에 참여한 것처럼 엄격하지는 않음)를 물려 받았습니다. 잠시 후, 우리는 이것이 불충분하다고 판단하고 다른 CI 프레임 워크를 탐색하기 시작하여 결국에는 buildbot을 선택했습니다. 빌드 봇으로 전환하는 나의 목표 중 하나는 모든 위즈 뱅 엑스트라를 즐기는 것 외에도 우리가 주문한 야간 건축업자의 부족함을 극복하는 것이었다.

잠시 유머를 가지고 상속받은 것을 설명하겠습니다. 우리 회사의 코드베이스는 거의 150 개의 고유 한 c ++ Windows 응용 프로그램으로, 각각 하나 이상의 내부 라이브러리 (및 타사 라이브러리에도 포함) 중 하나 이상에 종속되어 있습니다. 이러한 라이브러리 중 일부는 상호 의존적이며 해당 라이브러리의 동일한 빌드로 빌드해야하는 종속 응용 프로그램이 있습니다 (서로 관련이 없음). 이러한 애플리케이션 및 라이브러리의 절반은 "레거시"로 간주하고 이식 할 수 없으며 IBM 컴파일러의 고유 한 여러 구성으로 빌드해야하며 ( Compile다른 하위 클래스는 ), 나머지 절반은 Visual Studio로 빌드됩니다.ShellCommandVSS에 대한 지원이 없으므로 s).

우리의 독창적 인 야간 건축업자는 모든 것에 대한 소스를 간단히 가져 와서 특정 순서로 물건을 만들었습니다. 단일 응용 프로그램 만 작성하거나 개정을 선택하거나 항목을 그룹화 할 수있는 방법이 없었습니다. 여러 응용 프로그램을 구축하기 위해 가상 머신을 시작했습니다. 매우 강력하지 않았으며 배포 할 수 없었습니다. 정말 확장 할 수 없었습니다. 빌드 봇에서 이러한 모든 한계를 극복하고 싶었습니다.

원래이 작업을 수행 한 방식은 빌드하려는 각 응용 프로그램 (모두 150ish)에 대한 항목을 만든 다음 다양한 응용 프로그램을 그룹으로 구축 할 수있는 트리거 된 스케줄러를 만든 다음 해당 그룹을 전체 야간 빌드 스케줄러 아래에 포함시키는 것입니다. 이것들은 전용 슬레이브 (더 이상 가상 머신 chicanery가 아님)에서 실행될 수 있으며 원하는 경우 단순히 새로운 슬레이브를 추가 할 수 있습니다. 이제 일정을 벗어나 전체 빌드를 수행하려면 클릭 한 번이지만 원하는 경우 하나의 응용 프로그램 만 빌드 할 수도 있습니다.

There are four weaknesses of this approach, however. One is our source tree's complex web of dependencies. In order to simplify config maintenace, all builders are generated from a large dictionary. The dependencies are retrieved and built in a not-terribly robust fashion (namely, keying off of certain things in my build-target dictionary). The second is that each build has between 15 and 21 build steps, which is hard to browse and look at in the web interface, and since there are around 150 columns, takes forever to load (think from 30 seconds to multiple minutes). Thirdly, we no longer have autodiscovery of build targets (although, as much as one of my coworkers harps on me about this, I don't see what it got us in the first place). Finally, aformentioned coworker likes to constantly bring up the fact that we can no longer perform a full build on our local machine (though I never saw what that got us, either, considering that it took three times as long as the distributed build; I think he is just paranoically phobic of ever breaking the build).

이제 새로운 개발로 넘어 가면서 g ++ 및 서브 버전을 사용하기 시작했습니다 (이전 저장소를 포팅하지 않고 새로운 것만 고려하십시오). 또한 더 많은 단위 테스트 ( "more"는 잘못된 그림을 줄 수 있습니다 ... 더 비슷 합니다 ) 및 통합 테스트 (python 사용)를 시작했습니다. 이 구성을 기존 구성에 맞추는 방법을 알아내는 데 어려움을 겪고 있습니다.

그래서 여기서 철학적으로 어디 잘못 갔습니까? 구성을 실제로 유지 관리 할 수 ​​있도록 빌드 봇으로 작업을 진행하는 가장 좋은 방법은 무엇입니까? 내 디자인의 약점을 어떻게 해결합니까? 복잡한 대규모 코드베이스에 대한 CI 전략 측면에서 실제로 효과가있는 것은 무엇입니까?

편집하다:

나는 내 문제를 설명했다고 생각했지만 분명히 명확하지 않았습니다. 나는 하지 CI 플랫폼 변경에 대한 제안을 찾고. 그것은 일어나지 않을 것이며, 그 제안은 받아 들여지지 않을 것입니다. 내가 알고 싶은 것은 다른 사람들이 CI를 사용하여 복잡한 코드베이스를 관리하는 방법입니다. 저는 12 가지 제곱의 다른 제품을 가지고 있으며 바람에 흩어져있는 종속성을 가지고 있으며 모두 다릅니다. 이것이 내가 다루는 방법을 알고 싶은 것입니다.


나도 이것에 대한 답을 알고 싶습니다. 우리 환경은 당신만큼 복잡하지는 않지만 의존성 종속성의 종속성이 있습니다 (설정 프로젝트의 경우 4 계층 깊이의 종속성이 있음). 각 프로젝트가 CI 프로젝트인지 아니면 Visual Studio .sln 파일을 사용하여 처리 해야하는지 알지 못하므로 각 프로젝트의 종속성 트리를 다시 만들 필요가 없습니다. (그리고 미래의 프로젝트).
moswald

로컬 컴퓨터에 구축 할 수 없으면 CI 서버의 임무가 비즈니스에 중요 합니다. 이것을 다시 생각할 수도 있습니다.
Thorbjørn Ravn Andersen

답변:


3

설명 한 것처럼 나쁜 상황에 직면하지는 않았지만 수십 가지 구성 요소로 CI 구성을 유지하고 있으며 그 사이에는 '간단한'종속성이 있습니다. 내 접근 방식으로 진행할 힌트를 얻을 수 있기를 바랍니다. 문제는 CI 서버의 선택뿐만 아니라 전체 빌드 프로세스 및 프로젝트 구조와도 관련이 있습니다.

나는 문제를 빌딩과 CI의 두 부분으로 나눌 것이다.

건물

"빌딩"이란 소스 코드를 최종 아티팩트로 변경하는 프로세스를 의미합니다. 우리 회사는 주로 개발에 Java를 사용하며 우리가 사용한 빌드 도구는 Maven입니다. 프로젝트의 특성으로 인해 사용할 수는 없지만 Maven에는 다음과 같은 유용한 개념이 있습니다.

1) Maven 세계에서 각 아티팩트 (lib, 실제 프로그램 등)는 명확하게 분리되고 분리되어야합니다. 아티팩트 간 종속성이 명확해야합니다. 지저분한 의존성, 특히 빌드 아티팩트 사이의 순환 종속성은 빌드 프로세스를 혼란스럽게 만들 것임을 강조해야합니다.

예를 들어, 전체 빌드 프로세스 후에 여러 JAR (Java의 lib / dll로 간주 할 수 있음)이 빌드되었지만 실제로는 상호 의존적입니다. 마찬가지로 A.jar은 B.jar에서 사용하고 있으며 그 반대도 마찬가지입니다. 이러한 종류의 '모듈화'는 전혀 의미가 없습니다. A.jar과 B.jar은 항상 배포하고 함께 사용해야합니다. 그 의미는 나중에 다른 프로젝트로 분리하려는 경우 (예를 들어 다른 프로젝트에서 재사용하기 위해) 그렇게 할 수 없기 때문에 어떤 프로젝트 A 또는 B를 먼저 빌드할지 결정할 수 없습니다.

예, 소프트웨어 디자인에 적합해야하지만 지저분한 프로젝트에서 복잡한 건축 도구 / 모델 작업을하는 데 시간을 지불하는 대신 시간을 투자하여 디자인을 재구성하는 데 시간을 소비한다고 생각합니다. 간단한 건물 모델.

2) 종속성은 선언적이어야합니다. 이전에 본 많은 빌드 프로세스가 있으며 여기에는 프로젝트에서 로컬로 필요한 모든 라이브러리가 포함됩니다. 일부 라이브러리가 실제로 빌드해야하는 다른 아티팩트 인 경우 빌드 프로세스가 매우 번거 롭습니다.

3) 종속성을 얻기 위해 아티팩트에 대한 "중앙 집중식"스토리지 또는 아티팩트가 컴파일 된 후 배치합니다. 전체 사무실에 대해 "중앙 집중식"일 필요는 없으며 (있는 경우 좋을 것입니다) 로컬 디렉토리 만 있으면됩니다.

2와 3에 대한 자세한 설명 예를 들기 위해 3 개의 독립적 인 프로젝트가 포함 된 프로젝트를 보았습니다. 각 프로젝트는 소스와 소스 디렉토리의 lib / 디렉토리 아래에있는 lib를 기반으로 빌드됩니다. 프로젝트 A는 프로젝트 B와 C에서 사용되는 여러 라이브러리를 빌드합니다. 몇 가지 단점이 있습니다. 빌드 절차가 복잡하고 자동화하기가 어렵습니다. 소스 컨트롤이 다른 프로젝트에서 재사용되는 불필요한 중복 JAR로 인해 부풀어 오르고 있습니다.

Maven의 세계에서 프로젝트 B와 C는 실제로 프로젝트 소스에 A.jar (및 다른 타사 라이브러리와 같은 다른 종속성)을 포함하지 않습니다. 선언적입니다. 예를 들어, 프로젝트 B의 빌드 구성에서 A.lib v1.0, xyz.lib v2.1 등이 필요하다고 선언하면 빌드 스크립트는 /A/1.0/A에서 lib를 찾습니다. jar 및 /xyz/2.1/xyz.lib

메이븐이 아닌 세계의 경우이 아티팩트 디렉토리는 디렉토리 구조가 합의 된 하나 또는 두 개의 디렉토리 여야합니다. 모든 타사 라이브러리를 공유 위치에 배치하고 개발자가 로컬 컴퓨터에 동기화하거나 복사하도록 할 수 있습니다. 몇 년 전 C ++ 프로젝트에서 내가하고있는 일은 lib와 헤더를 $ {artifact_dir} / lib_name / ver로 설정하고 artifact_id를 환경 변수로 선언하는 것입니다.

프로젝트 A를 빌드하면 artifact_dir에 결과 사본이 생성되므로 프로젝트 B를 빌드 할 때 B는 수동 복사없이 A의 결과를 자동으로 얻을 수 있습니다.

4) 변경 불가능한 릴리스. A.lib 1.0을 릴리스하면 1 개월 후에 A.lib 1.0의 내용이 변경 될 것으로 예상되지 않습니다. 이 경우 A.lib 1.1이어야합니다. 변화하는 코드베이스의 인공물은 특별한 "버전"을 고려해야합니다.이를 위해 Maven에서는이를 스냅 샷이라고합니다.

변경 불가능한 릴리스는보다 윤리적 인 문제입니다. 그러나 해결 된 것은 분명합니다 : 동일한 lib를 사용하는 많은 프로젝트가있을 때 사용중인 해당 lib의 버전을 알고 있으며 다른 프로젝트에서 사용되는 동일한 버전의 lib가 실제로 동일하다는 것을 확신합니다 . 프로젝트 X와 Y가 모두 lib A를 사용하지만 빌드 결과가 다른 이유는 무엇입니까? (그리고 X와 Y가 사용하는 lib A는 lib의 내용이나 파일 크기를 파고 든 후에 실제로 다르다는 것을 알 수 있습니다).


이 모든 것은 프로젝트 A를 먼저 빌드하고 A.lib를 프로젝트 B에 복사 한 다음 프로젝트 B를 빌드하는 것과 같은 많은 수동 트릭없이 프로젝트를 독립적으로 빌드 할 수 있도록합니다.

예를 들어 프로젝트 A를 빌드 할 때 이와 같은 연습을 수행 한 후에는 중앙 집중식 아티팩트 저장소에서 종속성을 가져 오려고 시도합니다. 일부 종속성 (예 : 회사의 다른 프로젝트 (예 : 프로젝트 B))을 찾을 수없는 경우,해야 할 일은 프로젝트 B의 소스를 가져와 빌드 (성공시 중앙 집중식 스토리지에 배치) 및 그런 다음 프로젝트 A를 다시 빌드하십시오.


CI

쉬운 빌드 시스템과 명확한 종속성으로 CI가 훨씬 쉬워집니다. CI 서버가 다음 요구 사항을 충족 할 것으로 기대합니다.

1) 소스 컨트롤을 모니터링하고 소스에 변화가있을 때만 체크 아웃 + 빌드

2) 프로젝트 간 종속성 설정 가능

프로젝트에 대한 명확한 종속성을 사용하면 실제 프로젝트에 따라 CI로 프로젝트를 설정하고 프로젝트의 종속성에 따라 CI 프로젝트 종속성을 설정하면됩니다. CI 서버는 프로젝트를 빌드하기 전에 종속 프로젝트를 빌드하도록 설정해야합니다 (물론 프로젝트 소스가 실제로 변경된 경우에만 빌드가 발생 함).

모든 것이 올바르게 진행되면 거대하고 복잡하지만 여전히 관리 가능한 CI (및 더 중요한 관리 가능한 프로젝트 구조)가 있어야합니다.


이 답변이 어디로 가고 있는지 좋아하지만 '빌딩'섹션에서 더 자세히 설명 할 수 있습니까? 즉, 몇 가지 예를 제시하고, 개념 중 일부를 더 자세하게 설명하고 정교하게 설명하십시오.
Nate

흠 ... 어느 부분처럼? 각 부분에 대한 세부 정보를 제공하기 위해 게시물을 편집하려고합니다. 어떤 부분을 정교화해야한다고 생각할 수 있다면 더 좋을 것입니다. 그건 그렇고, Java도 사용하는 경우 maven.apache.org를 살펴보십시오. Maven은 채택하기 가장 쉬운 방법은 아니지만 사물을 깨끗하고 체계적으로 만들어야합니다.
Adrian Shum

1

비슷한 상황에서 나를 위해 일한 것 :

  • 빌드의 일부를 전용 빌드 앱으로 분류하여 앱 수준 추상화 (이 경우 기본 빌드에서 호출 된 PHP 스크립트) 이를 통해 수십 줄의 빌드 단계를 하나의 빌드 단계로 줄일 수 있습니다.
  • 기본 빌드 스크립트에서 시작되는 하위 빌드 스크립트를 작성하여 빌드 레벨 추상화 빌드 봇과 관련이 있는지 여부는 알 수 없습니다 (해당 제품에 대한 경험이 없음).

빌드 자체를 소프트웨어 개발 프로젝트로 취급 할 것을 제안합니다. 즉, 빌드 코드베이스를 모듈화하고 자동 테스트를 작성해야합니다 (예 : 알려진 개정 번호를 빌드하고 올바른 결과를 생성하는지 확인).


0

Jenkins를 CI 서버로 생각하고 여기에서 기능을 볼 수 있습니다.

https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins

왜? 설치가 쉽고, 멋진 인터페이스가 있으며, 구성 및 확장이 쉽고 거의 모든 것을위한 준비된 플러그인이 많이 있습니다.

https://wiki.jenkins-ci.org/display/JENKINS/Plugins

시도 해봐 :)


2
나는 당신이 내 질문에 제목을 읽었지만 본문을 읽지 않았다는 것을 알고 있습니다 ... 나는 제품 제안을 찾고 있지 않습니다. 제품 을 선택 했습니다. 복잡한 CI 설정을 구성하는 방법을 찾고 있습니다.
Nate

네이트, 나는 당신의 모든 게시물을 읽었으며 당신이 잘못된 제품을 선택했다고 생각합니다. 그래서 내가 Jenkins를 제안했습니다. Jenkins를 여러 컴퓨터에서 클러스터링하여 다양한 종류의 C ++ 제품 테스트 (여러 언어로 작성된 테스트조차도)를 위해 일하고 있습니다. 관리 및 구성이 매우 쉽습니다. 실제로 시도해보십시오 :)
Patrizio Rullo

이 블로그 게시물을보십시오 : vperic.blogspot.com/2011/05/…
Patrizio Rullo

0

우리는 지금 그 전에 Got ThoughtWorks 를 사용하고, CruiseControl.Net 을 사용하고있었습니다 . 우리는 두 팀이 서로 떨어져 세계에서 떨어져 있고 우리 사이에 시간대 차이가 크다는 점을 고려하면 유용했습니다.

우리는 여러 프로젝트를 관리하고 있으며 대부분의 작업은 전 세계의 두 개발자가 겹치는 부분을 포함하므로 모든 파일이 다른 사람의 빌드를 중단해서는 안된다는 점을 명심해야합니다.

또한 Go 및 Agile Process Diehard를 통해 관리가 쉬워졌으며 설치 후 두통이 줄었습니다. 테스트도 Go와 통합되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.