Programing

파이썬을위한“예쁜”지속적인 통합

lottogame 2020. 7. 20. 20:36
반응형

파이썬을위한“예쁜”지속적인 통합


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

예를 들어

.. 그리고 다른 사람들은 BuildBot 가 오히려 .. archaic

나는 현재 허드슨과 놀고 있지만 매우 Java 중심적입니다 ( 이 안내서 에서는 BuildBot보다 설정이 더 쉽고 더 많은 정보를 생성했습니다)

기본적으로 : 파이썬을 목표로하는 연속 통합 시스템이 있습니까? 많은 반짝이는 그래프와 같은 것을 생성합니까?


업데이트 : 이후 Jenkins 프로젝트는 Hudson을 패키지의 커뮤니티 버전으로 대체했습니다. 원저자도이 프로젝트로 옮겼습니다. Jenkins는 현재 Ubuntu / Debian, RedHat / Fedora / CentOS 및 기타 표준 패키지입니다. 다음 업데이트는 여전히 정확합니다. Jenkins이것을 시작하는 출발점 은 다릅니다.

업데이트 : 몇 가지 대안을 시도한 후에 허드슨을 고수 할 것이라고 생각합니다. 무결성 은 훌륭하고 단순했지만 상당히 제한적이었습니다. Buildbot 은 내가 사용하는 것과 같은 단일 컴퓨터에서 실행되는 모든 것이 아니라 수많은 빌드 슬레이브에 더 적합하다고 생각합니다.

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

  • http://hudson-ci.org/ 에서 Hudson을 다운로드 하십시오.
  • 로 실행 java -jar hudson.war
  • 기본 주소 인 웹 인터페이스를 엽니 다. http://localhost:8080
  • Hudson, 플러그인 관리로 이동하여 "업데이트"또는 유사한 항목을 클릭하십시오.
  • 힘내 플러그인을 설치하십시오 ( git허드슨 전역 환경 설정에서 경로 를 설정해야했습니다 )
  • 새 프로젝트를 작성하고 저장소, 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)

NoseXunit 출력 플러그인 을 확인하고 싶을 수도 있습니다 . 다음 명령을 사용하여 단위 테스트 및 적용 범위 검사를 실행할 수 있습니다.

nosetests --with-xunit --enable-cover

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

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


잘 모르겠다면 : Bitten 은 Trac을 쓰고 Trac과 통합 된 사람들에 의해 만들어졌습니다. Apache GumpApache에서 사용하는 CI 도구입니다. 파이썬으로 작성되었습니다.


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

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


Buildbot의 워터 폴 페이지는 상당히 예표 할 수 있습니다. 다음은 좋은 예입니다. http://build.chromium.org/buildbot/waterfall/waterfall


Atlassian 's Bamboo 는 확실히 체크 아웃 할 가치가 있습니다. Atlassian 제품군 전체 (JIRA, Confluence, FishEye 등)는 매우 달콤합니다.


나는이 스레드가 꽤 오래 된 것 같지만 여기에 hudson을 사용합니다.

나는 pip와 함께 가기로 결정하고 repo (작업하기가 힘들지만 멋진 달걀 바구니)를 설정했습니다. 허드슨은 성공적인 테스트로 자동 업로드합니다. 다음은 hudson 구성 실행 스크립트와 함께 사용할 수있는 대략적이고 준비된 스크립트입니다. /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

This stuff assumes you have a repo structure per package with a setup.py and dependencies all set up then you can just check out the trunk and run this stuff on it.

I hope this helps someone out.

------update---------

I've added epydoc which fits in really nicely with hudson. Just add javadoc to your config with the html folder

Note that pip doesn't support the -E flag properly these days, so you have to create your venv separately


another one : Shining Panda is a hosted tool for python


If you're considering hosted CI solution, and doing open source, you should look into Travis CI as well - it has very nice integration with GitHub. While it started as a Ruby tool, they have added Python support a while ago.


Signal is another option. You can know more about it and watch a video also here.


I would consider CircleCi - it has great Python support, and very pretty output.


continuum's binstar now is able to trigger builds from github and can compile for linux, osx and windows ( 32 / 64 ). the neat thing is that it really allows you to closely couple distribution and continuous integration. That's crossing the t's and dotting the I's of Integration. The site, workflow and tools are really polished and AFAIK conda is the most robust and pythonic way to distributing complex python modules, where you need to wrap and distribute C/C++/Fotran libraries.


We have used bitten quite a bit. It is pretty and integrates well with Trac, but it is a pain in the butt to customize if you have any nonstandard workflow. Also there just aren't as many plugins as there are for the more popular tools. Currently we are evaluating Hudson as a replacement.


Check rultor.com. As this article explains, it uses Docker for every build. Thanks to that, you can configure whatever you like inside your Docker image, including Python.


Little disclaimer, I've actually had to build a solution like this for a client that wanted a way to automatically test and deploy any code on a git push plus manage the issue tickets via git notes. This also lead to my work on the AIMS project.

One could easily just setup a bare node system that has a build user and manage their build through make(1), expect(1), crontab(1)/systemd.unit(5), and incrontab(1). One could even go a step further and use ansible and celery for distributed builds with a gridfs/nfs file store.

Although, I would not expect anyone other than a Graybeard UNIX guy or Principle level engineer/architect to actually go this far. Just makes for a nice idea and potential learning experience since a build server is nothing more than a way to arbitrarily execute scripted tasks in an automated fashion.

참고URL : https://stackoverflow.com/questions/225598/pretty-continuous-integration-for-python

반응형