Python을위한 "예쁜"지속적인 통합


116

이것은 약간 .. 헛된 질문이지만 BuildBot의 출력은보기에 특히 좋지 않습니다 ..

예를 들어 ..

.. 그리고 다른 것들, BuildBot 은 오히려 .. 고풍 스럽게 보입니다.

저는 현재 Hudson을 사용하고 있지만 매우 Java 중심적입니다 ( 이 가이드를 사용 하면 BuildBot보다 설정이 더 쉽고 더 많은 정보를 생성했습니다).

기본적으로 : Python을 겨냥한 지속적인 통합 시스템이 있습니까?


업데이트 : 이번 이후로 Jenkins 프로젝트는 패키지의 커뮤니티 버전으로 Hudson을 대체했습니다. 원저자도이 프로젝트로 이동했습니다. Jenkins는 이제 Ubuntu / Debian, RedHat / Fedora / CentOS 등의 표준 패키지입니다. 다음 업데이트는 여전히 기본적으로 정확합니다. Jenkins 로이 작업을 수행하는 시작점 은 다릅니다.

업데이트 : 몇 가지 대안을 시도한 후 Hudson을 고수 할 것이라고 생각합니다. 무결성 은 훌륭하고 단순했지만 매우 제한적이었습니다. 저는 Buildbot 이제가 사용 하던 것처럼 단일 머신에서 모든 것을 실행하는 것보다 수많은 빌드 슬레이브를 갖는 데 더 적합하다고 생각합니다.

Python 프로젝트를 위해 Hudson을 설정하는 것은 매우 간단합니다.

  • http://hudson-ci.org/ 에서 Hudson 다운로드
  • 함께 실행 java -jar hudson.war
  • 기본 주소에서 웹 인터페이스를 엽니 다. http://localhost:8080
  • Hudson, 플러그인 관리로 이동하여 "업데이트"또는 유사 항목을 클릭합니다.
  • Git 플러그인을 설치합니다 ( gitHudson 전역 환경 설정에서 경로 를 설정해야했습니다 ).
  • 새 프로젝트 생성, 저장소 입력, SCM 폴링 간격 등
  • 아직 설치 하지 않은 경우 nosetests통해 설치easy_install
  • 빌드 단계에서 nosetests --with-xunit --verbose
  • "JUnit 테스트 결과 보고서 공개"를 선택하고 "테스트 보고서 XML"을 다음으로 설정하십시오. **/nosetests.xml

그게 필요한 전부입니다. 이메일 알림을 설정할 수 있으며 플러그인 을 살펴볼 가치가 있습니다. 현재 Python 프로젝트에 몇 가지를 사용하고 있습니다.

  • SLOCCount 플러그인 을 사용하여 코드 줄을 계산하고 그래프로 표시합니다. sloccount를 별도로 설치해야합니다.
  • PyLint 출력을 구문 분석하기위한 위반 (경고 임계 값을 설정하고 각 빌드에 대한 위반 수를 그래프로 표시 할 수 있음)
  • Cobertura 는 coverage.py 출력을 구문 분석 할 수 있습니다. Nosetest는 다음을 사용하여 테스트를 실행하는 동안 적용 범위를 수집 할 수 있습니다 nosetests --with-coverage(출력을 **/coverage.xml).

좋은 질문입니다. 지금 바로 비슷한 것을 조사하고 있습니다. 한 가지 길을 가면 다른 사람들과 경험을 공유 할 수 있습니까?
André

3
이 글을 썼을 때 사용할 수 있었는지 모르겠습니다. Hudson 용 Chuck Norris 플러그인을 사용하여 항목에 대한 제어를 더욱 강화하십시오!
Johannes Charra 2009

8
2011/2012 업데이트 : 그 생각 허드슨 사용해야 젠킨스 , 허드슨 프로젝트의 오픈 소스 계속 (허드슨 지금 오라클에 의해 제어 )
mindthief

답변:


41

NoseXunit 출력 플러그인 을 확인하는 것이 좋습니다 . 다음 명령으로 단위 테스트를 실행하고 범위 검사를 수행하도록 할 수 있습니다.

nosetests --with-xunit --enable-cover

Jenkins 경로로 이동하거나 JUnit 테스트보고를 지원하는 다른 CI 서버를 사용하려는 경우 유용합니다.

마찬가지로 Jenkins 용 위반 플러그인을 사용하여 pylint의 출력을 캡처 할 수 있습니다.


4
코는 이제 기본적으로 xUnit의 플러그인을 포함 -nosetests --with-xunit
DBR

3
그렇다면 Pylint에서 감사를 어떻게 실행합니까? nosetests --with-xunit --enable-audit내가 얻을 때nosetests: error: no such option: --enable-audit
Adam Parkin

2
현대화 된 대답, NoseXUnit 물건은 이제 내장되어 있으며 불행한 경우 --with-nosexunit에서 --with-xunit.
dbr


9

TeamCity 를 CI 서버로 사용하고 nose를 테스트 러너로 사용하여 큰 성공을 거두었습니다 . nosetests 용 Teamcity 플러그인은 통과 / 실패 카운트, 실패한 테스트에 대한 읽기 쉬운 표시를 제공합니다 (이메일로 전송 가능). 스택이 실행되는 동안 테스트 실패에 대한 세부 정보도 볼 수 있습니다.

물론 여러 컴퓨터에서 실행하는 것과 같은 것을 지원하고 buildbot보다 설정 및 유지 관리가 훨씬 간단합니다.



6

Atlassian의 Bamboo 는 확실히 확인할 가치가 있습니다. 전체 Atlassian 제품군 (JIRA, Confluence, FishEye 등)은 매우 달콤합니다.


6

이 스레드는 꽤 오래되었다고 생각하지만 여기에 허드슨에 대한 내 의견이 있습니다.

나는 pip를 사용하기로 결정하고 성공적인 테스트를 통해 hudson이 자동으로 업로드하는 repo (일하기 힘들지만 멋져 보이는 달걀 바구니)를 설정했습니다. 다음은 허드슨 구성 실행 스크립트와 함께 사용하기위한 대략적이고 준비된 스크립트입니다. /var/lib/hudson/venv/main/bin/hudson_script.py -w $ WORKSPACE -p my.package -v $ BUILD_NUMBER, 그냥 넣어 ** / coverage.xml, pylint.txt 및 nosetests.xml 구성 비트 :

#!/var/lib/hudson/venv/main/bin/python
import os
import re
import subprocess
import logging
import optparse

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(levelname)s %(message)s')

#venvDir = "/var/lib/hudson/venv/main/bin/"

UPLOAD_REPO = "http://ldndev01:3442"

def call_command(command, cwd, ignore_error_code=False):
    try:
        logging.info("Running: %s" % command)
        status = subprocess.call(command, cwd=cwd, shell=True)
        if not ignore_error_code and status != 0:
            raise Exception("Last command failed")

        return status

    except:
        logging.exception("Could not run command %s" % command)
        raise

def main():
    usage = "usage: %prog [options]"
    parser = optparse.OptionParser(usage)
    parser.add_option("-w", "--workspace", dest="workspace",
                      help="workspace folder for the job")
    parser.add_option("-p", "--package", dest="package",
                      help="the package name i.e., back_office.reconciler")
    parser.add_option("-v", "--build_number", dest="build_number",
                      help="the build number, which will get put at the end of the package version")
    options, args = parser.parse_args()

    if not options.workspace or not options.package:
        raise Exception("Need both args, do --help for info")

    venvDir = options.package + "_venv/"

    #find out if venv is there
    if not os.path.exists(venvDir):
        #make it
        call_command("virtualenv %s --no-site-packages" % venvDir,
                     options.workspace)

    #install the venv/make sure its there plus install the local package
    call_command("%sbin/pip install -e ./ --extra-index %s" % (venvDir, UPLOAD_REPO),
                 options.workspace)

    #make sure pylint, nose and coverage are installed
    call_command("%sbin/pip install nose pylint coverage epydoc" % venvDir,
                 options.workspace)

    #make sure we have an __init__.py
    #this shouldn't be needed if the packages are set up correctly
    #modules = options.package.split(".")
    #if len(modules) > 1: 
    #    call_command("touch '%s/__init__.py'" % modules[0], 
    #                 options.workspace)
    #do the nosetests
    test_status = call_command("%sbin/nosetests %s --with-xunit --with-coverage --cover-package %s --cover-erase" % (venvDir,
                                                                                     options.package.replace(".", "/"),
                                                                                     options.package),
                 options.workspace, True)
    #produce coverage report -i for ignore weird missing file errors
    call_command("%sbin/coverage xml -i" % venvDir,
                 options.workspace)
    #move it so that the code coverage plugin can find it
    call_command("mv coverage.xml %s" % (options.package.replace(".", "/")),
                 options.workspace)
    #run pylint
    call_command("%sbin/pylint --rcfile ~/pylint.rc -f parseable %s > pylint.txt" % (venvDir, 
                                                                                     options.package),
                 options.workspace, True)

    #remove old dists so we only have the newest at the end
    call_command("rm -rfv %s" % (options.workspace + "/dist"),
                 options.workspace)

    #if the build passes upload the result to the egg_basket
    if test_status == 0:
        logging.info("Success - uploading egg")
        upload_bit = "upload -r %s/upload" % UPLOAD_REPO
    else:
        logging.info("Failure - not uploading egg")
        upload_bit = ""

    #create egg
    call_command("%sbin/python setup.py egg_info --tag-build=.0.%s --tag-svn-revision --tag-date sdist %s" % (venvDir,
                                                                                                              options.build_number,
                                                                                                              upload_bit),
                 options.workspace)

    call_command("%sbin/epydoc --html --graph all %s" % (venvDir, options.package),
                 options.workspace)

    logging.info("Complete")

if __name__ == "__main__":
    main()

배포와 관련하여 다음과 같이 할 수 있습니다.

pip -E /location/of/my/venv/ install my_package==X.Y.Z --extra-index http://my_repo

그리고 사람들은 다음을 사용하여 무언가를 개발할 수 있습니다.

pip -E /location/of/my/venv/ install -e ./ --extra-index http://my_repo

이 항목은 setup.py 및 종속성이 모두 설정된 패키지 당 저장소 구조가 있다고 가정하고 트렁크를 확인하고이 항목을 실행할 수 있습니다.

나는 이것이 누군가를 돕기를 바랍니다.

------최신 정보---------

허드슨과 정말 잘 어울리는 epydoc을 추가했습니다. html 폴더로 설정에 javadoc을 추가하십시오.

요즘 pip는 -E 플래그를 제대로 지원하지 않으므로 venv를 별도로 만들어야합니다.


이 답변은 매우 유용하며 Jenkins 등에서 무료로 얻을 수없는 Python CI의 내부와 관련하여 많은 세부 정보를 제공합니다. 감사!
maksimov 2013 년



2

신호는 또 다른 옵션입니다. 그것에 대해 더 많이 알 수 있으며 여기 에서도 비디오를 볼 수 있습니다 .



1

continuum의 binstar는 이제 github에서 빌드를 트리거 할 수 있으며 Linux, osx 및 Windows 용으로 컴파일 할 수 있습니다 (32/64). 깔끔한 점은 배포와 지속적인 통합을 밀접하게 연결할 수 있다는 것입니다. 그것은 t를 넘어 통합의 I를 점하는 것입니다. 사이트, 워크 플로 및 도구는 정말 다듬어졌으며 AFAIK conda는 C / C ++ / Fotran 라이브러리 를 래핑 하고 배포 해야하는 복잡한 파이썬 모듈을 배포하는 가장 강력하고 파이썬적인 방법 입니다.


0

우리는 bitten을 꽤 많이 사용했습니다. 예쁘고 Trac과 잘 통합되지만 비표준 워크 플로가있는 경우 사용자 정의하는 것은 골칫거리입니다. 또한 더 많이 사용되는 도구만큼 플러그인이 많지 않습니다. 현재 우리는 Hudson을 대체품으로 평가하고 있습니다.



0

약간의 면책 조항이지만 실제로 git push에서 모든 코드 를 자동으로 테스트하고 배포 하고 git notes를 통해 문제 티켓을 관리 하는 방법을 원하는 클라이언트를 위해 이와 같은 솔루션을 구축해야했습니다 . 이것은 또한 AIMS 프로젝트 에 대한 나의 작업으로 이어집니다 .

하나는 그냥 쉽게 설치를 빌드 사용자를 가지고 있으며 통해 빌드를 관리 베어 노드 시스템 수 make(1), expect(1), crontab(1)/ systemd.unit(5),과 incrontab(1). 한 단계 더 나아가 gridfs / nfs 파일 저장소가있는 분산 빌드에 ansible과 celery를 사용할 수도 있습니다.

비록 Graybeard UNIX 전문가 나 Principle 레벨 엔지니어 / 아키텍트 이외의 다른 사람이 실제로 여기까지 갈 것이라고 기대하지는 않습니다. 빌드 서버는 자동화 된 방식으로 스크립팅 된 작업을 임의로 실행하는 방법에 불과하므로 좋은 아이디어와 잠재적 인 학습 경험을 제공합니다.

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