通常在Nightly Build的環節,我比較喜歡Clean Build,也就是從Checkout、Compile、Test、Deploy都是一個動作完成的Compile、Test、Deploy都可以靠Maven或Ant完成,但是自VCS中checkout source code就要看plugin的支援程度了。即便是plugin支援度不夠,只要該種VCS有提供command line的模式,我想就能利用shell或script的方式來達到完整的Clean Build。 例如:
git clone [url] #checkout source code from VCS cd [project] mvn site -Pprod
Maven提供的SCM Plugin請參考 http://maven.apache.org/scm/plugins/index.html, 而支援的SCM的完整度則可以考 http://maven.apache.org/scm/matrix.html
為了使用Maven的SCM Plugin,通常單獨將<scm>建一個pom.xml,其他plugin或build的東西就免寫了,當然要用原來project的pom.xml也無不可,簡單看個例子。
01.
<
project
xsi:schemalocation
=
"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns
=
"http://maven.apache.org/POM/4.0.0"
>
02.
<
modelversion
>4.0.0</
modelversion
>
03.
04.
<
groupid
>idv.elliot</
groupid
>
05.
<
artifactid
>BuildDemo</
artifactid
>
06.
<
version
>0.0.1-SNAPSHOT</
version
>
07.
<
packaging
>pom</
packaging
>
08.
09.
<
name
>BuildDemo</
name
>
10.
<
url
>http://github.com/ElliotChen/BuildDemo </
url
>
11.
12.
<
scm
>
13.
<!-- 僅供讀取的Connection URL, 前面必需加上scm:xxx -->
14.
<
connection
>scm:git:git://github.com/ElliotChen/BuildDemo.git </
connection
>
15.
<!-- 可以執行checkin的Connection URL, 前面必需加上scm:xxx -->
16.
<
developerconnection
>scm:git:git://github.com/ElliotChen/BuildDemo.git </
developerconnection
>
17.
<
url
>http://github.com/ElliotChen/BuildDemo </
url
>
18.
</
scm
>
19.
<
build
>
20.
<
plugins
>
21.
<
plugin
>
22.
<
groupid
>org.apache.maven.plugins</
groupid
>
23.
<
artifactid
>maven-scm-plugin</
artifactid
>
24.
<
version
>1.3</
version
>
25.
<!-- Checkout之後要執行的Goal -->
26.
<
configuration
>
27.
<
goals
>site</
goals
>
28.
</
configuration
>
29.
</
plugin
>
30.
</
plugins
>
31.
</
build
>
32.
</
project
>
簡單來說,只要在<scm>裡的<connection>填入SCM checkout source code的url,然後在url之前依你使用的SCM種類加上指定的prefix,然後在<maven-scm-plugin>的<configuration>中填上接下來要執行的goal,最後執行
mvn clean scm:bootstrap這樣就可以看到像下列的輸出:
[INFO] [scm:bootstrap {execution: default-cli}] [INFO] Removing /Users/elliot/tmp/target/checkout [INFO] Executing: /bin/sh -c cd /Users/elliot/tmp/target && git clone git://github.com/ElliotChen/BuildDemo.git /Users/elliot/tmp/target/checkout [INFO] Working directory: /Users/elliot/tmp/target [INFO] Executing: /bin/sh -c cd /Users/elliot/tmp/target/checkout && git pull git://github.com/ElliotChen/BuildDemo.git master [INFO] Working directory: /Users/elliot/tmp/target/checkout [INFO] Executing: /bin/sh -c cd /Users/elliot/tmp/target/checkout && git checkout [INFO] Working directory: /Users/elliot/tmp/target/checkout [INFO] Executing: /bin/sh -c cd /Users/elliot/tmp/target/checkout && git ls-files [INFO] Working directory: /Users/elliot/tmp/target/checkout [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Building BuildDemo [INFO] task-segment: [site] [INFO] ------------------------------------------------------------------------ [INFO] [site:site {execution: default-site}]
除项目内部依赖外,不要依赖其它 SNAPSHOT。项目外部的 SNAPSHOT 依赖随时可能发生变化,且不受你控制,因此不应该使用。
对此处存在理解上的障碍
可以举例吗
@dd
内部依赖,例如你的项目有3个模块,app-dao, app-service, app-web,你让app-service依赖app-dao 1.0-SNAPSHOT没有问题,因为你自己控制app-dao的变化,出了问题自己可以找原因并修复
外部依赖,例如你项目依赖什么 commons-fake-1.0-SNAPSHOT(虚构),可能今天用下来没问题,但明天这个构件更新了,而且和你项目集成出问题了,你得找原因吧?但由于不是你的代码,很难找,就算找出来了,你又没法修。因此不要用外部的SNAPSHOT依赖。
特地跑过来问个问题
首先说一下我的项目结构,我期望做一个多模块的项目。目录结构如下:
ots-projects
+– pom.xml
+– ots-domain
+– pom.xml
+– ots-web
+– pom.xml
由于所有的源码都放在SVN上,所以我想各个项目分别get自己的源代码,如ots-domain和ots-web分别获取自己项目的源代码。
ots-projects目录下的POM文件如下:
4.0.0
org.abcsoft
ots-projects
pom
1.0-SNAPSHOT
OTS Root Project
ots-domain
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
junit
junit
3.8.1
test
org.springframework
spring
2.5.5
ots-domain目录下的POM文件如下:
4.0.0
org.abcsoft
ots-domain
jar
1.0-SNAPSHOT
OTS Domain Object Model
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
scm:svn:http://192.168.1.24/subversion/OTS/DS/Domain
junit
junit
3.8.1
test
org.springframework
spring
2.5.5
org.apache.maven.plugins
maven-compiler-plugin
2.3.1
<!–
-source 5
–>
1.5
1.5
utf-8
org.apache.maven.plugins
maven-scm-plugin
1.4
compile
test
test
我遇到的问题是:
1、我转到ots-domain目录下,运行“MVN scm:bootstrap”,就是checkout源文件后再编译。但是,我发现MVN在checkout文件后,进行编译时,用的是JDK 1.3的版本。我按照Apache网站上的配置,在compiler-plugin里面指定了使用JDK 1.5的参数,并自己写了一个测试JAVA文件,编译可以通过。但是,运行“MVN scm:bootstrap”还是使用JDK 1.3的版本。对于scm:bootstrap,如何指定它用JDK 1.5版本进行编译呢?
2、我直接在ots-projects目录下运行“mvn scm:bootstrap”,MVN没有将checkout出来的文件放到子模块下,而是直接放在ots-projects目录下。而我直接在ots-domain目录下运行这个命令,checkout出来的文件是放在ots-domain目录下的。我要如何做才能让MVN将不同模块的文件放在不同模块的目录下?
之前主要使用的是Ant,刚刚开始使用Maven,看网络上,好像Maven的知名度还不错,所以也打算使用Maven来做持续集成。难道是我的用法错了?我想从版本库上获取源代码,再编译,这个是每日编译的基本工作啊!不知道为什么Maven配置起来这么困难呢?
@kevin
首先我不推荐你使用maven-scm-plugin来执行日常的svn操作,mvn的作用之一是构建,svn的作用是版本控制,因此在你不熟悉maven的时候,集成两者只会增加复杂度
关于你的第一个问题,请确认ots-domain继承自ots-projects,也就是说前者有parent元素指向后者,这样才能继承maven-compiler-plugin的相关配置
你就用svn co签出源码,然后运行mvn clean install执行构建,这样出了问题也方便定位
Maven比较成熟了,就是学习曲线比Ant陡峭,另外有些理念也不一样,我的网站提供了不少相关资料,你可以慢慢学习