12,maven 版本管理

一.何为版本管理

    版本管理( Version Management )是指项目整体版本的演变过程管理,如从 1.0.0-SNAPSHOT  1.0.0 。版本控制( Version Control )是指借助版本控制工具(subversion)追踪代码的每一个变更。

    理想的发布版本应该对应项目某个时刻比较稳定的状态,应满足以下条件:

        1)所有自动化测试应通过

        2)项目没有快照版本的依赖

        3)项目没有配置快照版本的插件

        4)项目包含的代码已全部提交到版本控制系统中。

    在 svn中使用标签可以明确地将某个源码版本(也就是项目的某个状态)从主干中标记出来,这样在之后的任何时刻,我们都能够快速地得到发布版本的源代码,从而能够比较各个版本的差异,甚至重新构建一个同样版本的构件。

    从快照版本更新至发布版本之后,应该再执行一次 Maven 构建,确保项目状态是健康的,再将更新提交到 svn 的主干中。接着再为当前主干的状态打上标签。

二.Maven的版本号定义约定

    Maven 的版本号定义为:

        < 主版本 >.< 次版本 >.< 增量版本 >-< 里程碑版本 >

        1)主版本:项目重大架构变更

        2)次版本:较大范围功能变化及 Bug 修复

        3)增量版本:重大 Bug 修复

        4)里程碑版本:一个版本的 milestone ,表示不是非常稳定,还需要很多测试

    一般主版本和次版本都会声明,增量版本和里程碑版本不一定会声明。

    Maven 对前三者的比较是基于数字的,对里程碑版本只进行简单的字符串比较,因此会得到如1.2-beta-3 >1.2=beta11的结果。

三.主干、标签与分支

    使用版本控制工具都会遇到以下概念:

        1) 主干( trunk ):项目开发代码的主体,从项目开始直到当前都处于活动状态,可以获得项目最新源码及所有变更历史。

        2) 分支( branch ):从主干的某个点分离出来的代码拷贝,通常是为了在不影响主干的前提下进行重大 Bug 的修复或做些实验性质的开发,当分支达到预期的目的后,分支上的变更会被合并到主干上。如下图中为了不影响1.2.0 的开发,从 1.1.0 分了一个分支出来进行 Bug 修复。

        3) 标签( tag ):用来标识主干或者分支的某个点的状态,以某个稳定状态(通常是版本发布时的状态)

四.自动化版本发布

1.Maven Release Plugin概述

    Maven Release Plugin 能完成所有版本发布所涉及的操作,它主要有三个目标:

        1) release:prepare :准备版本发布,主要执行以下操作:

            a)  检查项目是否有未提交代码

            b)  检查项目是否有快照版本依赖

            c)  根据用户输入将快照版升级为发布版

            d)  将 POM 中的 SCM 信息更新为标签地址

            e)  基于修改后的 POM 执行 Maven 构建

            f)   提交 POM 变更

            g)  基于用户输入为代码打标签

            h)  将代码从发布版升级为新的快照版

            i)   提交 POM 变更

        2) release:rollback :回退 release:prepare 所执行的所有操作,提交回退后的 POM ,但不会删除标签

        3)  release:perform :执行版本发布。签出 release:prepare 生成的标签中的源代码(注意:这里是按标签地址签出原代码, POM 中的版本还是发布版本 ) ,并在此基础上执行 mvn deploy 

2.为项目发布版本

    要为项目发布版本,首先需要为其添加正确的版本控制系统信息,Maven Release Plugin需要知道版本控制系统的主干、标签等地址信息后才能执行相关操作。

    1) 配置项目的SCM信息,告诉maven当前代码的位置(主干)。

<scm>  
  <connection>scm:svn:http://192.168.1.103/app/trunk</connection>  
  <developerConnection>scm:svn:https://192.168.1.103/app/trunk</developerConnection>  
  <url>http://192.168.1.103/account/trunk</url >  
</scm>

    Connection元素表示一个只读的scm地址。

    developerConnection元素表示可写的scm地址。

    url元素表示可以在浏览器中访问的scm地址。

    Connection和developerConnection为了能让maven识别,必须以scm打头,

    冒号之后代表版本控制工具类型(其他还有cvs、git等),接下来就是scm实际地址。

    2) 配置Maven Release Plugin,告诉其标签的基础目录。

<plugin>  
  <groupId>org.apache.maven.plugins</groupId>  
  <artifactId>maven-release-plugin</artifactId>  
  <version>2.0</version>  
  <configuration>  
    <tagBase>https://192.168.1.103/app/tags/</tagBase>  
  </configuration>  
</plugin>

    3执行 mvn release:prepare 命令

        执行该命令前,需注意:

            第一,系统必须要提供svn命令行工具;

            第二,POM必须配置了可用的部署仓库。

    在项目根目录执行命令:mvn release:prepare,如果项目有未提交的代码或者有快照版本依赖,则会提示出错。

    如果一切正确,则会提示用户输入发布版本号、标签名以及新的快照版本号。

    4) 执行mvn release:rollback回退发布

    执行该回退命令后,Maven Release Plugin会将POM中的配置回退到release:prepare之前的状态。但是,版本控制系统中的标签并不会被删除,用户需要手动删除该标签。

    5) 将所有模块的发布版本和新的快照版本都保持一致

    在多模板项目中执行mvn release:prepare时,默认会提示用户设定每个模块发布的版本号及新的开发版本号。但是很多情况下我们希望所有模块的发布版本以及新的SNAPSHOT开发版本都保持一致。

    运行以下命令,插件自动为所有子模块使用与父模块一致的发布版本和新的SNAPSHOT开发版本:

       mvn release:prepare -DautoVersionSubmodules=true

   如果坚持release:prepare的结果没问题,则执行如下发布命令:

       mvn release:perform

   该命令将标签中的代码签出,执行mvn deploy命令构建刚才准备的版本,并部署到仓库。

   至此,版本正式发布完成。

    6) 在超级POM中配置信息,使打包类型为jar的主构件的-sources.jar和-javadoc.jar也会生成并发布。

<profiles>  
  <profile>  
    <id>release-profile</id>  
    <activation>  
      <property>  
        <name>performRelease</name>  
        <value>true</value>  
      </property>  
    </activation>  
    <build>  
      <plugins>  
        <plugin>  
          <inherited>true</inherite>  
          <artifactId>maven-source-plugin</artifactId>  
          <executions>  
            <execution>  
              <id>attach-sources</id>  
              <goals>  
                <goal>jar</goal>  
              </goals>  
            </execution>  
          </executions>  
        </plugin>  
        <plugin>  
          <inherited>true</inherited>  
          <artifactId>maven-javadoc-plugin</artifactId>  
          <executions>  
            <execution>  
              <id>attach-javadocs</id>  
              <goals>  
                <goal>jar</goal>  
              </goals>  
            </execution>  
          </executions>  
        </plugin>  
        <plugin>  
          <inherited>true</inherited>  
          <artifactId>maven-deploy-plugin</artifactId>  
          <configuration>  
            <updateReleaseInfo>true</updateReleaseInfo>  
          </configuration>  
        </plugin>  
      </plugins>  
    </build>  
  </profile>  
</profiles>

    这个 profiler 配置了三个插件,分别用来为项目生成 -source.jar ,为项目生成 -javadoc.jar 以及更新仓库中的元数据,告诉仓库该版本是最新的发布版。每个插件中值为 true 的 interited 元素表示该插件配置可以被子 POM 继承。而这个 profile 的激活条件是运行环境中有名为 performRelease 属性且值为 true 。而 release:perform 会自动生成-DperformRelease=true 参数。由于这种隐式的配置十分令人费解,会在后面版本的 Maven 中去除,让用户自己在 POM 中显示配置这些插件。

一.自动化创建分支

    Maven Release Plugin  branch 目标会执行以下操作:

        1) 检查本地有无未提交代码

        2) 为分支更改 POM 的版本

        3) 将 POM 中的 SCM 信息更新为分支地址

        4) 提交以上更改

        5) 将主干的代码复制到分支中

        6) 修改本地代码使其回退到分支之前的版本(用户可以指定新的版本)

        7) 提交本地更改

    为此我们还需要在 POM 中配置为 Maven Release Plugin 用 <branchBase> 元素配置分支地址。

    执行 release:branch –DbranchName=1.1.1 –DupdateBranchVersions=true –DupdateWorkingCopyVersions=false 会提示用户输入新的 branch version 。

    最后一个参数表示不更新本地代码(即主干)版本。

二.GPG签名

1.GPG及其基本使用

    GnuPG(简称 GPG ,来自http://www.gnupg.org )是 PGP ( Pretty Good Privacy )标准的一个免费实现,无论类 UNIX 平台还是 Windows 平台都可使用它。 GPG 能帮助我们为文件生成签名、管理密钥以及验证签名等。

    使用 gpg –gen-key 生成 GPG 密钥对。使用 gpg –list-keys 可以查看本机的所有公钥。使用 gpg –list-secret-keys可以查看本机的所有私钥。

    使用 gpg –ab temp.java 可以为文件创建一个 ASCII 码的签名文件: temp.java.asc  -a 表示生成 ASCII 格式的输出, -b 表示创建一个独立的签名文件。将这两个文件及公钥一起给用户,用户可以用 gpg –verify temp.java.asc 来验证该文件。

    运行如下命令可以将公钥发布到公钥服务器中:

        gpg –keyserver hkp://pgp.mit.edu –send-keys C6EED57A

    这里 C6EED57A 就是用 —list-keys 看到的公钥 ID 。公钥会自动在各个服务器中被同步。

    可以用如下命令获得公钥:

        gpg –keyserver hkp://pgp.mit.edu –recv-keys C6EED57A

2.Maven GPG plugin

    可以在  POM  中配置  Maven GPG Plugin  (但命令行  gpg  需要自己安装):
<plugin>  
  <groupId>org.apache.maven.plugins</groupId>  
  <artifactId>maven-gpg-plugin</artifactId>  
  <version>1.0</version>  
  <executions>  
    <execution>  
       <id>sign-artifacts</id>  
      <phase>verify</phase>  
      <goals>  
        <goal>sign</goal>  
      <goals>  
    </execution>  
  </executions>  
</plugin>

    用命令行 mvn clean deploy –Dgpg.passphrase=yourpassphrasesk 可以对你发布的构件进行自动签名。Yourpassphrase 是你的私钥的密码(你在创建私钥的时候可以选择是否设一个密码。)

    用如下命令可以对已经发布的构件进行签名:

mvn gpg:sign-add-deploy-file –DpomFile=target/myapp-1.0.pom –Dfile=target/myapp-1.0.jar –Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=sonatype_oss

    该命令指定了要签名的 POM 及相关文件、 Maven 仓库的地址和 ID 

    只有在项目正式发布的时候才需要签名,对日常的 SNAPSHOT 构件签名只会增加耗时。所以可以在 settings.xml文件中新增一个 profile 来配置 GPG 插件,而 profile 的激活条件同样中 performRelease 为 true 。这样就能在执行release:perform 时自动执行 GPG 插件了。但由于一个已知的 Maven Release Plugin 的 Bug ,执行 release:perform过程中签名可能会 hung 住,所以需要为其在 confiuration 元素中增加:
    < mavenExecutorId >forked-path </ mavenExecutorId >  

你可能感兴趣的:(12,maven 版本管理)