8

我如何设置构建Play中的应用和(自定义)在CI系统播放模块,因此,当一个模块的构建是好的,构建安装在本地模块文物存储库和/或将它们部署到远程存储库,并且这些应用程序使用该存储库中的工件?如何使用自定义模块,播放和持续集成

该解决方案还应该谁的工作在本地开发工作。

我使用詹金斯和麻烦尽我尝试这样做运行。

我阐述一下我遇到的所有问题之前,我会等待,因为它是费力的,也许别人可以提供他们是如何做到这一点。

回答

6

我在詹金斯的设置,从开发能很好地生产。

首先这里是在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存储库下载工件。

建立我在詹金斯模块我使用自定义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 "[email protected]/$APPLICATION-$VERSION.zip" --verbose 

有了这个脚本,你可以和你的模块推到关系上的每个詹金斯建设。这并不是我所做的。我使用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 "[email protected]/$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文件。

有了这个詹金斯可以建立依赖于模块的本地版本,同时它不被释放,之后可以通过从关系信息库下载模块artifcat构建应用程序的应用程序。这对开发者来说是一样的

+1

我觉得这个技术将会使我的设置的差异;我还没有时间尝试它,这就是为什么我还没有接受它。后续问题:您的localModules repo配置看起来不像典型的Jenkins设置,其中构建工作区不在相邻的目录中。我有点困惑,从你Jenkins构建的位置检索dev(相对于发布)版本的依赖关系。 – Ladlestein

+1

在jenkins中,我只有一个工作空间,所有的模块目录都是相邻的,因为它在开发中。如果没有,那么每次构建模块时都必须在nexus中发布您的artefact,并使用某种类型的快照版本控制,这会对设置和使用更加繁琐 –

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 '~ '