【问题标题】:How to use Play with custom modules and continuous integration如何将 Play 与自定义模块和持续集成一起使用
【发布时间】:2011-11-30 04:40:21
【问题描述】:

如何在 CI 系统中设置 Play 应用程序和(自定义)Play 模块的构建,以便在模块构建良好时,构建将模块工件安装到本地存储库和/或将它们部署到远程存储库,并且应用程序使用该存储库中的工件?

该解决方案也应该适用于在本地工作的开发人员。

我正在使用 Jenkins,但无论我尝试如何做都会遇到麻烦。

在我详细说明我遇到的所有问题之前,我会等待,因为这很费力,也许其他人可以提供他们如何做到这一点。

【问题讨论】:

    标签: continuous-integration playframework build-automation dependency-management


    【解决方案1】:

    我在 jenkins 中有一个设置,可以很好地从开发到生产。

    首先是自定义模块存储库的dependencies.yml中的配置

    repositories:
        - modules:
            type: chain
            using:
                - localModules:
                    type: local
                    descriptor: "${application.path}/../[module]/conf/dependencies.yml"
                    artifact: "${application.path}/../[module]"
                - repoModules:
                    type: http
                    artifact: "http://mynexus/nexus/content/repositories/releases/com/myorg/[module]/[revision]/[module]-[revision].zip"
            contains:
                - com.myorg -> *
    

    有了这个开发者和詹金斯首先在同一个仓库中搜索,看看是否有一个模块存在,如果没有,就去nexus仓库下载工件。

    为了在 jenkins 中构建我的模块,我使用了这样的自定义 sh 脚本

    #!/bin/bash
    APPLICATION="myModule"
    PLAY_PATH="/usr/local/play"
    set –xe
    
    $PLAY_PATH/play deps --sync
    $PLAY_PATH/play build-module --require 1.2.3
    VERSION=`grep self conf/dependencies.yml | sed "s/.*$APPLICATION //"`
    echo "Sending $APPLICATION-$VERSION.zip to nexus repository"
    curl --request POST --user user:passwd http://mynexus/nexus/content/repositories/releases/com/myorg/$APPLICATION/$VERSION/$APPLICATION-$VERSION.zip -F "file=@dist/$APPLICATION-$VERSION.zip"  --verbose
    

    使用此脚本,您可以在每个 jenkins 构建中将您的模块推送到 nexus。这不是我真正要做的。我只在构建发布时使用 jenkins 发布模块来推送它。对于一个版本,我有一个特殊的脚本

    #!/bin/bash
    APPLICATION="myModule"
    PLAY_PATH="/usr/local/play"
    set –xe
    
    if [ -z "$RELEASE_VERSION" ]
    then
      echo "Parameter RELEASE_VERSION is mandatory"
      exit 1
    fi
    if [ -z "$DEVELOPMENT_VERSION" ]
    then
      echo "Parameter DEVELOPMENT_VERSION is mandatory"
      exit 1
    fi
    echo "Release version : $RELEASE_VERSION"
    echo "Development version : $DEVELOPMENT_VERSION"
    VERSION=`grep self conf/dependencies.yml | sed "s/.*$APPLICATION //"`
    if [ "$RELEASE_VERSION" != "$VERSION" ]
    then
      echo "Release version $RELEASE_VERSION and play version $VERSION in dependencies.yml does not match : release failed"
      exit 1
    fi
    REVISION=`svnversion .`
    echo "Tag svn repository in revision $REVISION with version $VERSION"
    svn copy -m "Version $VERSION" -r $REVISION http://mysvn/myRepo/$APPLICATION/trunk/ http://mysvn/myRepo/$APPLICATION/tags/$VERSION
    echo "svn tag applied"
    echo "Sending $APPLICATION-$VERSION.zip to nexus repository"
    curl --request POST --user user:passwd http://mynexus/nexus/content/repositories/releases/com/myorg/$APPLICATION/$VERSION/$APPLICATION-$VERSION.zip -F "file=@dist/$APPLICATION-$VERSION.zip"  --verbose
    echo "$APPLICATION-$VERSION.zip sent to nexus repository"
    echo "Update module to version $DEVELOPMENT_VERSION"
    sed -i "s/self\(.*\)$VERSION/self\1$DEVELOPMENT_VERSION/g" conf/dependencies.yml
    svn commit -m "Version $DEVELOPMENT_VERSION" conf/dependencies.yml
    svn update
    echo "Version $DEVELOPMENT_VERSION créée"
    

    此脚本在我们的 svn 存储库中放置一个标签,将模块推送到 nexus 并更新 dependencies.yml 文件。

    有了这个 jenkins 可以构建一个依赖于本地版本的模块的应用程序,而它还没有发布,然后可以通过从 nexus 存储库下载模块 artifcat 来构建应用程序。开发人员也是如此

    【讨论】:

    • 我认为这种技术会对我的设置产生影响;我只是还没有时间尝试,这就是为什么我还没有接受它。后续问题:您的 localModules repo 配置看起来与典型的 Jenkins 设置不匹配,其中构建工作区不在相邻目录中。对于您的 Jenkins 从哪里构建检索开发(而不是发布)版本的依赖项,我有点困惑。
    • 在 jenkins 中,我只有一个工作区,并且我的所有模块目录都是相邻的,就像在 dev 中一样。如果没有,您必须在每次构建模块时在 nexus 中发布您的工件,并使用某种快照版本控制,这将更加繁琐的设置和使用
    【解决方案2】:

    我写了这个小剧本!命令基本上它做同样的事情,但很好地集成到 Play!

    http://www.playframework.org/community/snippets/25

    from play.utils import *
    from poster.encode import multipart_encode
    from poster.streaminghttp import register_openers
    import urllib
    import urllib2
    import yaml
    
    COMMANDS = ['nexus-commit',]
    
    HELP = {
        'nexus-commit': 'push built module to nexus'
    }
    
    def execute(**kargs):
        app = kargs.get("app")
        args = kargs.get("args")
        play_env = kargs.get("env")
    
        print '~ '
        print '~ Commiting to nexus server'
        print '~ '
    
        app.check()
        nexus = app.readConf('nexus.server.url')
        user = app.readConf('nexus.server.user')
        password = app.readConf('nexus.server.password')
    
        if nexus:
            print '~ Found nexus repository : %s' % nexus
        else:
            print '~ No nexus server configured'
            print '~ Set up the following on your application.conf:'
            print '~    nexus.server.url'
            print '~    nexus.server.user'
            print '~    nexus.server.password'
            sys.exit(0)
    
        #Getting module version from dependencies file
        deps_file = os.path.join(app.path, 'conf', 'dependencies.yml')
        if os.path.exists(deps_file):
            f = open(deps_file)
            deps = yaml.load(f.read())
            #Is this a Play~ module?
            if "self" in deps:
                d = deps["self"].split(" ")
                module_version = d.pop()
                app_name = d.pop()
            else:
                app_name = app.name()
                print '~ This is not a Play module'
                module_version = app.readConf('application.version')
                if not module_version:
                    print '~ '
                    print '~ No application.version found in application.conf file'
                    print '~ '
                    module_version = raw_input('~ Provide version number to be pushed to Nexus:')
            f.close
    
        if module_version:
            print '~ Module version : %s' % module_version
            print '~ '
        else:
            print '~ No module version configured.'
            print '~ Configure your dependencies file properly'
            sys.exit(0)
    
        dist_dir = os.path.join(app.path, 'dist')
    
        #Only interested on .zip files
        for root, dirs, files in os.walk(dist_dir):
            files = [ fi for fi in files if fi.endswith(".zip") ]
    
        #Loop over all found files
        if len(files) >0:
            for file in files:
                if "-a" in args:
                    #We won't ask the user if he wants to commit
                    resp = "Y"
                else:
                    resp = raw_input('~ Do you want to post %s to nexus? (Y/N) ' % file)
                if resp == 'Y':
                    url = '%s/%s/%s-SNAPSHOT/%s-%s-SNAPSHOT.zip' % (nexus, app_name, module_version, app_name, module_version)
                    print '~ '
                    print '~ Sending %s to %s' % (file, url)
    
                    try:
                        data = open(os.path.join(dist_dir, file), 'rb')
                    except:
                        print '~ Error: could not open file %s for reading' % file
                        continue 
    
                    openers = register_openers()
                    #post data to Nexus using configured credentials
                    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
                    passman.add_password(None, url, user, password)
                    authhandler = urllib2.HTTPBasicAuthHandler(passman)
                    openers.add_handler(authhandler)
                    openers.add_handler(urllib2.HTTPHandler(debuglevel=1))
                    datagen, headers = multipart_encode({"file": data})
                    request = urllib2.Request(url, datagen, headers)
    
                    try:
                        print urllib2.urlopen(request).read()
                        print '~ File correctly sent'
                    except urllib2.HTTPError, err:
                        print '~ Error: Nexus replied with -- %s' % err
    
                else:
                    print '~ '
                    print '~ Skiping %s' % file
        else:
            print '~ '
            print '~ No module build found.'
            print '~ Try "play build-module" command first'
            print '~ '
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      相关资源
      最近更新 更多