相信大家看完了上篇文章(http://gull.iteye.com/blog/1137200),会对自动化编译,部署和测试的过程与实现细节有所了解。那么我们稍微总结下就会发现其实现的实质就是一系列linux shell命令组成,且都是很常见的,如maven, ssh, scp, unzip, cp, mv, delete, kill, sed, awk等.
我们回想下——项目是采用maven2构建的,而我们CI自动化job的阶段也是借鉴maven2中默认的phases,因此我们做了下映射, 如下图:
此时你会有什么样的想法? —— 我们能否扩展maven2的生命周期,将我们不同流程的脚本嵌入到maven2的各个生命周期中,这样就可以直接使用原生的maven2命令来完成CI自动化流程了。
所幸的是maven2已经提供了这样的机制和插件,在实践中我们主要用到了下面这2个插件:
- maven-antrun-plugin: 自定义ant task来完成代码同步(p4 sync),参数替换,打包上传(scp),集成测试(ant-jmeter)等操作
- maven-sshexec-plugin:主要是用来执行远程服务器命令来完成清理和部署(ssh, del, unzip, scp, kill, java)等操作
这2个插件如何操作可以查看相关手册:
http://maven.apache.org/plugins/maven-antrun-plugin/
http://evgeny-goldin.com/wiki/Maven-sshexec-plugin
maven-antrun-plugin这个插件官方介绍得比较简单,远不能达到我们的需要,因此我们需要扩展ant task来完成CI流程的定制化。
如何扩展?我们将以code sync和test为例来介绍。
code sync&test stage
- 实现org.apache.tools.ant.Task接口
public class CodeSync extends Task {
//todo
public void execute() throws BuildException {
//todo prepare some parameters
try {
//sync the application code
sync(depot, p4ClientRoot, p4ClientFolder);
} catch (Exception e) {
e.printStackTrace();
throw new BuildException(e);
}
}
private void sync(String depotRoot, String clientRoot, String folderPath) throws Exception {
String depotPath = depotRoot + "/" + folderPath + "/...";
IServer server = ServerFactory.getServer("p4java://p4host:p4port", null);
server.connect();
server.setCharsetName(p4Charset);
server.setUserName(p4User);
//login the p4 server
server.login(p4Passwd);
IClient client = server.getClient(p4Client);
server.setCurrentClient(client);
List<IFileSpec> fileSpecs = server.getDepotFiles(FileSpecBuilder.makeFileSpecList(new String[] { depotPath }), false);
log("sync "+fileSpecs.size()+" flies");
client.sync(fileSpecs, true, false, false, false);
server.logout();
}
}
codesync=com.xxx.ant.tasks.CodeSync
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>initialize</id>
<phase>initialize</phase>
<configuration>
<target>
<echo message="**************************"/>
<echo message="** A P P S CODE SYNC "/>
<echo message="**************************"/>
<typedef file="$typedef.properties" />
<codesync>
<parameter name="maven">xxx.xxx.xxx</parameter>
<parameter name="xxxx">yyyy</parameter>
</codesync>
<echo message="**************************"/>
<echo message="** END CODE SYNC *********"/>
<echo message="**************************"/>
<echo message=""/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>compile-skip-unittest</id>
<phase>test</phase>
<configuration>
<target if="maven.test.skip">
<echo message="*****************************************"/>
<echo message="===== BEGIN COMPILE(TEST) ===="/>
<echo message="*****************************************"/>
<exec dir="/xxx/yyy/sourceFolder" executable="mvn">
<arg line="clean compile -Dmaven.test.skip=true -Ddependency.locations.enabled=false"/>
</exec>
<echo message= "***************************************"/>
<echo message= "===== END COMPILE(TEST) ===="/>
<echo message= "***************************************"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>compile-unit-test</id>
<phase>test</phase>
<configuration>
<target unless="maven.test.skip">
<echo message="***********************************"/>
<echo message="===== BEGIN COMPILE ===="/>
<echo message="***********************************"/>
<echo message="//TODO: prepare unittest environment "/>
<exec dir="/xxx/yyy/sourceFolder" executable="mvn">
<arg line="clean compile -Ddependency.locations.enabled=false"/>
</exec>
<echo message="***********************************"/>
<echo message="===== BEGIN COMPILE ===="/>
<echo message="***********************************"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>ci-anttasks</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
在这个配置文件中,我们扩展了maven2的initialize和test周期,并通过ant来执行我们想要的操作。
Deploy Stage
对于deploy过程也是比较杂的,也需要按照相同的方式来扩展,并且还要配合maven-sshexec-plugin插件来完成部署操作。
pom.xml配置片段
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>upload package</id>
<phase>pre-integration-test</phase>
<configuration>
<target>
<mkdir dir="..."/>
<!-- upload package to the remote server-->
<scp todir="deployserver:path"
keyfile="$keyfile" trust="true"
failonerror="false">
<fileset dir="$buildFolder/">
<include name="*.zip"/>
</fileset>
</scp>
...
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.xxxx</groupId>
<artifactId>ci-anttasks</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>com.goldin.plugins</groupId>
<artifactId>maven-sshexec-plugin</artifactId>
<executions>
<!-- Run commands on each remote server -->
<execution>
<id>do deploy</id>
<phase>pre-integration-test</phase>
<goals>
<goal>sshexec</goal>
</goals>
<configuration>
<location>scp://$deployserver/uploadFolder</location>
<keyfile>$keyFile</keyfile>
<commands>
<command>echo '********************************'</command>
<command>echo '==== { Run Remote Commands} ===='</command>
<command>echo '********************************'</command>
<command>
unzip xx.zip
</command>
<command>echo ''</command>
<command>echo '==== END Run Remote Commands ===='</command>
<command>echo '*********************************'</command>
<command>echo ''</command>
</commands>
</configuration>
</execution>
</executions>
</plugin>
Integration Test Stage
目前integration test我们主要是采用jmeter来进行完成API测试的,因此我们需要配置ant jmeter task.
<execution>
<phase>integration-test</phase>
<configuration>
<target>
<echo message="******************************************"/>
<echo message="==== { Run Integration test Scripts } ===="/>
<echo message="******************************************"/>
<path id="jmeter.classpath">
<fileset dir="$jarFolder">
<include name="ant-jmeter*.jar"/>
</fileset>
</path>
<taskdef name="jmeter" classpathref="jmeter.classpath" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>
<property name="transformation.xsl" value="$resourcesFolder/jmeter-results-detail-report.xsl" />
<property name="resourcesFolder" value="$resourcesFolder" />
<ant antfile="$jmeter.integration.testscript" />
<echo message=""/>
<echo message="=====END Integration Test====="/>
<echo message="******************************"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
到此maven2生命周期的扩展算是结束了,但如果子项目比较多的话,每一个这样配置很是麻烦,可以通过下面2种手段解决:
- 构建maven parent project: 通过继承和参数覆盖的方式简化配置,具体方式可参考maven手册。
- 编写pom生成工具: 通过简单的配置参数和文件模板生成目标pom,如图所示
——全文完
- 大小: 8.6 KB
- 大小: 38.1 KB
分享到:
相关推荐
For any software developer who has spent days in “integration hell,” cobbling together myriad software components, Continuous Integration: Improving Software Quality and Reducing Risk illustrates ...
From there, you'll integrate code repositories, applications, and build tools for the implementation of continuous integration. Finally, you'll explore the automated deployment of an application in ...
From there, you'll integrate code repositories, applications, and build tools for the implementation of Continuous Integration. Finally, you will also learn how to automate your deployment on cloud ...
Perform Continuous Integration and deployment and fine-tune the way you deliver on AWS Book Description Knowing how to adopt DevOps in your organization is becoming an increasingly important skill for...
Develop your Xtext DSLs using Continuous Integration mechanisms; Use an Xtext editor in a web application In Detail Xtext is an open source Eclipse framework for implementing domain-specific languages...
Physically Based Rendering from Theory to Implementation 一共3部分~~~~~~~~~, 源码下载to h t t p ://www.p b r t . o r g /downloads.php /////////////////////////////////// CHAPTER 01. ...
Mobile DevOps is the future of continuous integration and continuous delivery for mobile application development, and is a very important requirement of today's fast-paced development culture....
You will gradually move on to setting up the development environment and configuring it before implementing continuous integration to deploy your microservice architecture. Using Spring Security, you...
Software Testing and Continuous Quality Improvement <br>SECTION I SOFTWARE QUALITY IN PERSPECTIVE . . . . . . . . . . . . . . . 1 1 Quality Assurance Framework. . . . . . . . . . . . . . . . . ....
The book also shows you how to build and release a DSL so that it can be installed in Eclipse, and gives you hints on how to build the DSL headlessly in a continuous integration server. ...
在软件开发中,持续集成(Continuous Integration,简称CI)是一种实践,旨在频繁地将开发人员的代码更改合并到共享存储库中,并自动构建和测试这些更改,以尽早发现潜在的问题。"first-CI-implementation"项目是一...
With this practical book, build administrators, developers, testers, and other professionals will learn how the features in Jenkins 2 let you define pipelines as code, leverage integration with other...
Facilitate technical tasks and processes: testing, refactoring, continuous integration, simple design, collective code ownership, and pair programming Act as an effective coach, learning to engage the...
The integration of project information resources is crucial to centralize data and improve accessibility. By consolidating scattered resources into a unified platform, P company can streamline ...
- **Version Control and Continuous Integration (CI):** Guidance on integrating RSpec with version control systems and CI/CD pipelines to automate testing processes. **RSpec Essentials** is not just a...
10. 持续集成与重构(Continuous Integration and Refactoring):为了保证软件质量,领域驱动设计提倡持续集成,不断重构模型和代码以适应变化的业务需求。 这本书《领域驱动设计:软件核心复杂性应对之道》由...
The chapter finishes with a discussion on test runners, test reporting, and using continuous integration build servers. Chapter 9, Testing TypeScript Compatible Frameworks, shows how to unit test, ...