Как использовать Play с пользовательскими модулями и непрерывной интеграцией - PullRequest
8 голосов
/ 30 ноября 2011

Как настроить сборки приложений Play и (настраиваемых) модулей Play в системе CI, чтобы при хорошей сборке модуля сборка устанавливала артефакты модуля в локальном хранилище и / или развертывала их в удаленном хранилище. и приложения используют артефакты в этом хранилище?

Решение также должно хорошо работать для разработчика, который работает локально.

Я использую Дженкинс и попадаю в неприятности любым способом, которым я пытаюсь это сделать.

Прежде чем подробно остановиться на всех проблемах, с которыми я столкнулся, я подожду, потому что это кропотливо, и, возможно, кто-то другой может предложить, как они это делают.

Ответы [ 2 ]

6 голосов
/ 30 ноября 2011

У меня есть настройка в 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 -> *

С этими разработчикамии jenkins сначала ищут в том же репозитории, чтобы увидеть, присутствует ли модуль, и если нет, попали в репозиторий 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.Это не совсем то, чем я занимаюсь.Я использую модуль релиза 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 можно собратьприложение, которое зависит от локальной версии модуля, пока оно не выпущено, и после этого может создать приложение, загрузив artifcat модуля из репозитория nexus.То же самое для разработчиков

2 голосов
/ 17 февраля 2012

Я написал эту маленькую пьесу!Команда, которая в основном делает то же самое, но хорошо интегрируется в 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 '~ '
...