本地生活服务网站怎么做,企业管理培训课程推荐,小说网站开发技术实现,教育网站集群建设申请Maven 版本管理 1️⃣ 版本管理的概念2️⃣ Maven 的版本号定义约定3️⃣ 主干、标签与分支4️⃣ 自动化版本发布5️⃣ 自动化创建分支6️⃣ GPG签名6.1 GPG 及其基本使用6.2 Maven GPG Plugin #x1f33e; 总结 一个健康的项目通常有一个长期、合理的版本演变过程。例如JUn… Maven · 版本管理 1️⃣ 版本管理的概念2️⃣ Maven 的版本号定义约定3️⃣ 主干、标签与分支4️⃣ 自动化版本发布5️⃣ 自动化创建分支6️⃣ GPG签名6.1 GPG 及其基本使用6.2 Maven GPG Plugin 总结 一个健康的项目通常有一个长期、合理的版本演变过程。例如JUnit有3.7、3.8、 3.8.1、3.8.2、4.0、4.1等版本。Maven本身的版本也比较多如最早的Maven1; Maven2有2.0.9、2.0.10、2.1.0、2.2.0、2.2.1等各种版本而最新的Maven3则拥有3.0-alpha-1、3.0-alpha-2、3.0-alpha-7、3.0-beta-1等版本。除了这些对外发布的版本之外前面还介绍了Maven特有的快照版本的概念。这些版本中的每个数字代表了什么? alpha、beta是什么意思? 快照版和发布版的区别是什么? 我们应该如何科学地管理自己的项目版本? 本文将会详细解答这些问题。
阅读本文的时候还需要分清版本管理 (Version Management) 和版本控制 (Version Control) 的区别。版本管理是指项目整体版本的演变过程管理如从 1.0-SNAPSHOT到1.0, 再到1.1-SNAPSHOT。版本控制是指借助版本控制工具(如 Subversion)追踪代码的每一个变更。本文重点讲述的是版本管理但是读者将会看到版本管理通常也会涉及一些版本控制系统的操作及概念。在阅读的时候应特别留意这两者的关系和区别。 1️⃣ 版本管理的概念
前面文章中谈到为了方便团队的合作在项目开发的过程中大家都应该使用快照版本Maven能够很智能地处理这种特殊的版本解析项目各个模块最新的“快照”。快照版本机制促进团队内部的交流但是当项目需要对外发布时我们显然需要提供非常稳定的版本使用该版本应当永远只能够定位到唯一的构件而不是像快照版本那样定位的构件随时可能发生变化。对应地我们称这类稳定的版本为发布版。项目发布了一个版本之后就进入下一个开发阶段项目也就自然转换到新的快照版本中。
版本管理关心的问题之一就是这种快照版和发布版之间的转换。项目经过了一段时间的1.0-SNAPSHOT的开发之后在某个时刻发布了1.0正式版然后项目又进入了1.1-SNAPSHOT的开发这个版本可能添加了一些有趣的特性然后在某个时刻发布1.1正式版。项目接着进入1.2-SNAPSHOT的开发。由于快照对应了项目的开发过程因此往往对应了很长的时间而正式版本对应了项目的发布因此仅仅代表某个时刻项目的状态如图所示。 理想的发布版本应当对应了项目某个时刻比较稳定的状态这包括源代码的状态以及 构建的状态因此这个时候项目的构建应当满足以下的条件
所有自动化测试应当全部通过。毫无疑问失败的测试代表了需要修复的问题因此发布版本之前应该确保所有测试都能得以正确执行。项目没有配置任何快照版本的依赖。快照版本的依赖意味着不同时间的构建可能会 引入不同内容的依赖这显然不能保证多次构建能够生成同样的结果。项目没有配置任何快照版本的插件。 快照版本的插件配置可能会在不同时间引入不 容内容的Maven 插件从而影响 Maven 的行为破坏构建的稳定性。项目所包含的代码已经全部提交到版本控制系统中。项目已经发布了可源代码却 不在版本控制系统中甚至丢失了。这意味着项目丢失了某个时刻的状态因此这 种情况必须避免版本发布的时候必须确保所有的源代码都已经提交了。
只有上述条件都满足之后才可以将快照版本更新为发布版本例如将1.0-SNAPSHOT 更新为1.0, 然后生成版本为1.0的项目构件。
不过这里还缺少一步关键的版本控制操作。如果你了解任何一种版本控制工具如 Subversion, 那就应该能想到项目发布与标签 (Tag) 的关系。版本控制系统记录代码的每一个变化通常这些变化都被维护在主干 (Trunk)中但是当项目发布的时候开发人员就应该使用标签记录这一特殊时刻项目的状态。以Subversion为例日常的变更维护在主干中包含各种源码版本r1 、r2 、… 、t284 、… 。 要找到某个时刻的项目状态会比较麻烦而使用标签就可以明确地将某个源码版本(也就是项目状态)从主干中标记出来放到单独的位置这样在之后的任何时刻我们都能够快速地得到发布版本的源代码从而能够比较各个版本的差异甚至重新构建一个同样版本的构件。
因此将项目的快照版本更新至发布版本之后应当再执行一次Maven 构建以确保项目状态是健康的。然后将这一变更提交到版本控制系统的主干中。接着再为当前主干的 状态打上标签。以 Subversion 为例这几个步骤对应的命令如下
$mvn clean install
$svn commit pom.xml -m prepare to release 1.0
$svn copy -m tag release 1.0\
https://svn.xiaoshan.com/project/trunk\
https://svn.xiaoshan.com/project/tags/1.0至此 一个版本发布的过程完成了。接下来要做的就是更新发布版本至新的快照版本 如从1.0到1.1-SNAPSHOT。 2️⃣ Maven 的版本号定义约定
到目前为止读者应该已经清楚了解了快照版和发布版的区别。现在再深入看一下 1.0、1.1、1.2.1、3.0-beta 这样的版本号后面又遵循了怎样的约定。了解了这样的约定之后就可以正确地为自己的产品或者项目定义版本号而你的用户也能了解到隐藏在版本号中的信息。
看一个实际的例子这里有一个版本
1.3.4-beta-2这往往表示了该项目或产品的第一个重大版本的第三个次要版本的第四次增量版本的beta-2里程碑。很拗口? 那一个个分开解释“1”表示了该版本是第一个重大版本“3” 表示这是基于重大版本的第三个次要版本“4”表示该次要版本的第四个增量最后的 “beta-2” 表示该增量的某一个里程碑。
也就是说Maven 的版本号定义约定是这样的
主版本 . 次版本 . 增量版本 - 里程碑版本主版本和次版本之间以及次版本和增量版本之间用点号分隔里程碑版本之前用连字号分隔。下面解释其中每一个部分的意义
主版本 表示了项目的重大架构变更。例如 Maven2 和 Maven1 相去甚远Struts 1和Struts2 采用了不同的架构JUnit 4 较 JUnit 3 增加了标注支持。次版本 表示较大范围的功能增加和变化及Bug 修复。例如 Nexus 1.5较 1 .4添加了 LDAP 的支持并修复了很多Bug, 但从总体架构来说没有什么变化。增量版本 一般表示重大 Bug 的修复例如项目发布了1.4.0版本之后发现了一 个影响功能的重大Bug, 则应该快速发布一个修复了Bug 的1.4.1版本。里程碑版本 顾名思义这往往指某一个版本的里程碑。例如Maven3 已经发布了 很多里程碑版本如3.0-alpha-1 、3.0-alpha-2 、3.0-beta-1 等。这样的版本与正式的 3.0相比往往表示不是非常稳定还需要很多测试。
需要注意的是不是每个版本号都必须拥有这四个部分。 一般来说主版本和次版本都会声明但增量版本和里程碑就不一定了。例如像3.8这样的版本没有增量和里程碑 2.0-beta-1 没有增量。但我们不会看到有人省略次版本简单地给出主版本显然是不够的。 当用户在声明依赖或插件未声明版本时 Maven 就会根据上述的版本号约定自动解析 最新版本。这个时候就需要对版本号进行排序。对于主版本、次版本和增量版本来说比较是基于数字的因此 1.51.41.3.111.3.9。而对于里程碑版本Maven 则只进行 简单的字符串比较因此会得到1.2-beta-31.2-beta-11 的结果。这一点需要留意。 3️⃣ 主干、标签与分支
使用版本控制工具时我们都会遇到主干 (trunk) 、 标签 (tag) 和 branch ( 分支) 的概念。前面文章已经涉及了主干与标签。这里再详细将这几个概念阐述一下因为理解它们是 理解 Maven 版本管理的基础。
主干项目开发代码的主体是从项目开始直到当前都处于活动的状态。从这里可以获得项目最新的源代码以及几乎所有的变更历史。分支从主干的某个点分离出来的代码拷贝通常可以在不影响主干的前提下在这里进行重大Bug 的修复或者做一些实验性质的开发。如果分支达到了预期的目的 通常发生在这里的变更会被合并 (merge) 到主干中。标签用来标识主干或者分支的某个点的状态以代表项目的某个稳定状态这通常就是版本发布时的状态。
本文采用 Subversion 作为版本控制系统如果对上述概念不清晰请参考开放的《Subversion 与版本控制》(http://svnbook.red-bean.com/) 一书。 使用Maven 管理项目版本的时候也涉及了很多的版本控制系统操作。下面就以一个实际的例子来介绍这些操作是如何执行的。 图下方最长的箭头表示项目的主干项目最初的版本是1.0.0-SNAPSHOT, 经过 一段时间的开发后1.0.0版本发布这个时候就需要打一个标签图中用一个长条表示。 然后项目进入1.1.0-SNAPSHOT 状态大量的开发工作都完成在主干中添加了 一些新特性并修复了很多Bug 之后项目1.1.0发布同样这时候需要打另一个标签。
发布过后项目进入1.2.0-SNAPSHOT 阶段可这个时候用户报告1.1.0 版本有一个重大的Bug, 需要尽快修复我们不能在主干中修Bug, 因为主干有太多的变化无法在短时间内测试完毕并发布我们也不能停止1.2.0-SNAPSHOT的开发 因此这时候可以基于1.1.0 创建一个 1.1.1-SNAPSHOT的分支在这里进行Bug修复然后为用户发布一个1.1.1增量版本同时打上标签。当然还不能忘了把Bug修复涉及的变更合并到1.2.0-SNAPSHOT的主干中。主干在开发一段时间之后发布1.2.0版本然后进入到新版本1.3.0-SNAPSHOT的开发过程中。
一个典型的项目版本变化过程涉及了快照版与发布版之间的切换、Maven版本号约定的应用以及版本控制系统主干、标签和分支的使用。这其实也是一个不成文的行业标准理解这个过程之后不仅能够更方便地学习开源项目也能对项目的版本管理更加标准和清晰。 4️⃣ 自动化版本发布
前几节已经详细介绍了版本发布时所需要完成的工作读者如果愿意则完全可以手动地执行这些操作检查是否有未提交代码、是否有快照依赖、更新快照版至发布版、 执 行Maven 构建以及为源代码打标签等。事实上如果对这一过程不是很熟悉那么还是 应该一步步地操作一遍以得到最直观的感受。
当熟悉了版本发布流程之后就会希望借助工具将这一流程自动化。Maven Release Pugin 就提供了这样的功能只要提供一些必要的信息它就能帮我们完成上述所有版本发布所涉及的操作。下面介绍如何使用 Maven Release Plugin 发布项目版本。 Maven Release Plugin 主要有三个目标它们分别为
release:prepare 准备版本发布依次执行下列操作 ■ 检查项目是否有未提交的代码。 ■ 检查项目是否有快照版本依赖。 ■ 根据用户的输入将快照版本升级为发布版。 ■ 将POM 中的 SCM 信息更新为标签地址。 ■ 基于修改后的 POM 执行 Maven 构建。 ■ 提交 POM 变更。 ■ 基于用户输入为代码打标签。 ■ 将代码从发布版升级为新的快照版。 ■ 提交POM 变更。release:rollback 回退 release:prepare 所执行的操作。将 POM回退至 release:prepare 之前的状态并提交。需要注意的是该步骤不会删除 release:prepare 生成的标签 因此用户需要手动删除。release:perform 执行版本发布。签出 release:prepare 生成的标签中的源代码并在此基础上执行 mvn deploy 命令打包并部署构件至仓库。 要为项目发布版本首先需要为其添加正确的版本控制系统信息这是因为Maven Release Plugin 需要知道版本控制系统的主干、标签等地址信息后才能执行相关的操作。 一般 配置项目的 SCM 信息如代码所示
projectscmconnectionscm:svn:http://192.168.1.103/app/trunk/connectiondeveloperConnectionscm:svn:https://192.168.1.103/app/trunk/developerConnectionurlhttp:// 192.168.1.103/account/trunk/url/scm...
/project代码中的 connection元素表示一个只读的 scm 地址而developerConnection 元素表示可写的scm 地址 url 则表示可以在浏览器中访问的scm 地址。为了能让 Maven识别 connection和 developerConnection 必须以 scm 开头冒号之后的部分表示版本控制工具类型(这里是 svn),Maven 还支持cvs、git 等。接下来才是实际的scm 地址该例中的connection 使用了http 协议而 developerConnection 则由于涉及写操作使用https 协议进行了保护。
该配置只告诉 Maven当前代码的位置(主干),而版本发布还要涉及标签操作。因此还需要配置 Maven Release Plugin 告诉其标签的基础目录如代码所示
plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-release-plugin/artifactIdversion2.0/versionconfigurationtagBasehttps://192.168.1.103/app/tags//tagBase/configuration
/plugin在执行 release:prepare 之前还有两个注意点第一系统必须要提供 svn 命令行工具 Maven 需要svn 命令行工具执行相关操作而无法使用图形化的工具如 TortoiseSVN; 第二 POM必须配置了可用的部署仓库因为 release:perform 会执行 deploy 操作将构件发布到仓库中。关于如何配置部署仓库可参考前面的文章 。
一切就绪之后在项目根目录下运行如下命令
$mvn release:prepareMaven Release Plugin 开始准备发布版本如果它检测到项目有未提交的代码或者项 目有快照版的依赖则会提示出错。如果一切都没问题则会提示用户输入想要发布的版本号、标签的名称以及新的快照版本号。例如
What is the release version for App?(com.xiaoshan.mvnbook:app)1.0.0::
What is scm release tag or label for App?(com.xiaoshan.mvnbook:app)app-1.0.0::
What is the new development version forApp?(com.xiaoshan.mvnbook:app)1.0.1- SNAPSHOT::1.1.0-SNAPSHOT如果项目的 arifactld 为 app, 发布前的版本为1.0.0-SNAPSHOT, 则 Maven Release Plugìn 会提示使用发布版本号1.0.0, 使用标签名称 app-1.0.0, 新的开发版本为1.0.1-SNAPSHOT。如果这些模式值正是你想要的直接按 Enter 键即可否则就输入想要的值再按 Enter 键如上例中为新的开发版本输入了值1.1.0-SNAPSHOT。
基于这些信息Maven Release Plugin会将版本从1.0.0-SNAPSHOT更新为1.0.0,并更新 SCM地址 http://192.168.1.103/app/trunk 至 http://192.168.1.103/app/tags/app-1.0.0 。 在此 基础上运行一次 Maven 构建以防止意外的错误出现然后将这两个变化提交并为该版本打上标签标签地址是 http://192.168.1.103/app/tags/app-1.0.0 。即 tagBase 路径加上标签名称。之后Maven Release Plugin 会将 POM中的版本信息从1.0.0升级到1.1.0-SNAPSHOT 并提交。
至此 release:prepare 的工作完成。如果这时你发现了一些问题例如将标签名称配置错了则可以使用 release:rollback 命令回退发布 Maven Release Plugin 会将 POM 的配置回 退到 release:prepare 之前的状态。但需要注意的是版本控制系统中的标签并不会被删除 也就是说用户需要手动执行版本控制系统命令删除该标签。
在多模块项目中执行 release:prepare 的时候。默认maven-release-plugin 会提示用户每个模块发布版本号及新的开发版本号。例如如果在 account-parent 模块中配置正确的 scm信息之后进行项目发布就会看到如下的输出
What is the release version for Account Parent?(com.xiaoshan.mvnbook.account: account-parent)1.0.0::
What is the release version for Account Persist?(com.xiaoshan.mvnbook.account: account-persist)1.0.0::
What is the release version for Account Captcha?(com.xiaoshan.mvnbook.account: account-captcha)1.0.0::
What is the release version for Account Service?(com.xiaoshan.mvnbook.account: account-service)1.0.0::
What is the release version for Account Web?
(com.xiaoshan.mvnbook.account: account-web)1.0.0::
What is ScM release tag or label for Account Parent?(com.xiaoshan.mvnbook.account: account-parent)account-parent-1.0.0::
What is the new development version for Account Parent?(cam.xiaoshan.mvnbook.account: account-parent)1.0.1-SNAPSHOT::
What is the new development version for Account Email?(com.xiaoshan.mvnbook.account: account-email)1.0.1-SNAPSHOT::
What is the new development version for Account Persist?(com.xiaoshan.mvnbook.account: account-persist)1.0.1-SNAPSHOT::
What is the new development version for Account Captcha?(com.xiaoshan.mmbook.account: account-captcha)1.0.1-SNAPSHOT::
What is the new development version for Account Service?(com.xiaoshan.mvnbook.account: account-service)1.0.1-SNAPSHOT::
What is the new development version for Account Web?
(com.xiaoshan.mvnbook.account account-web)1.0.1-SNAPSHOT::在很多情况下我们会希望所有模块的发布版本以及新的 SNAPSHOT 开发版本都保持 一致。为了避免重复确认maven-release-plugin 提供了autoVersionSubmodules 参数。例如运行下面的命令后maven-release-plugin 就会自动为所有子模块使用与父模块一致的发布版本和新的SNAPSHOT 版本
$mvn release:prepare DautoVersionSubmodulestrue如果检查下来release:prepare 的结果没有问题标签和新的开发版本都是正确的可以执行如下发布执行命令
$mvn release:perform该命令将标签中的代码签出执行 mvn deploy 命令构建刚才准备的1.0.0版本并部署到仓库中。至此版本1.0.0正式发布完成。由于它已经被部署到了 Maven 仓库中其 他人可以方便地配置对它的依赖。 细心的读者可能会发现如果你所发布项目的打包类型为 jar, 在执行 release:perform 之后不仅项目的主构件会被生成并发布到仓库中基于该主构件的-sources.jar 和-javadoc.jar也会生成并发布。对于你的用户来说这无疑是非常方便的他们不仅能够下载你的主构件还能够得到项目的源码和 Javadoc。那么 ,release:perform 是怎样生成 -sources.jar和-javadoc.jar 的呢?
前面介绍过所有Maven项目的 POM 都继承自超级POM, 而如果打开超级POM, 就能发现如代码所示内容
profilesprofileidrelease-profile/idactivationpropertynameperformRelease/namevaluetrue/value/property/activationbuildpluginsplugininheritedtrue/inheritedartifactIdmaven-source-plugin/artifactIdexecutionsexecutionidattach-sources/idgoalsgoaljar/goal/goals/executionexecutions/pluginplugininheritedtrue/inheritedartifactIdmaven-javadoc-plugin/artifactIdexecutionsexecutionidattach-javadocs/idgoalsgoaljar/goal/goals/execution/executions/pluginplugininheritedtrue/inheritedartifactIdmaven-deploy-plugin/artifactIdconfigurationupdateReleaseInfotrue/updateReleaseInfo/configuration/plugin/plugins/build/profile
/profiles超级POM中定义了一个名为release-profile 的 Maven Profile,Prolile 是指一段在特定情况 下被激活并更改 Maven行为的配置本书后续会有专门的章节详细阐述。这里看到 activate 元素下有一个名为 performRelease、值为 true 的属性配置这表示当 Maven 运行时如果运行环境中有 performRelease 属性且值为true 的时候该Profile 就被激活。也就是说该 Profile 下的配置会得到应用。那么, 什么情况下Maven运行环境中会有名为 performRelease、值为 true 的属性呢? 可以在命令行指定。例如
$mvn clean install -DperformReleasetrue但是大家可能已经猜到了在执行 release:perform 的 时 候 Maven Release Plugin 会自动生成值为 true 的 performRelease 属性。这时超级 POM 中的 release-profile 就会被激活。
这个 Profile配置了3 个Maven 插件 maven-sources-plugin 的 jar目标会为项目生成 -source.jar 文件 maven-javadoc-plugin 的 jar 目标会为项目生成 -javadoc.jar 文件而 maven- deploy-plugin 的 update-release-info 配置则会在部署的时候更新仓库中的元数据告诉仓库该版本是最新的发布版。每个插件配置中值为 true 的 inherited 元素则表示该插件配置可以被子POM 继承。
在日常的快照开发过程中往往没有必要每次都生成-source.jar 和-javadoc.jar, 但是当项 发布的时候这些文件就显得十分重要。超级 POM 中的 release-profile 就是为了这种情形而设计的。需要注意的是这种隐式的配置对于不熟悉 Maven 的用户来说可能会显得十分令人费解因此将来的 Maven 版本中可能会从超级POM中移除这段配置所以如果用户希望在发布版本时自动生成 -sources.jar 和 -javadoc.jar,最好还是在自己的POM 中显式地配置这些插件。
5️⃣ 自动化创建分支
上面介绍了如何使用Maven Release Plugin 自动化版本发布而分支创建的操作还没有具体涉及。本节就继续基于实际的样例讲解如何自动化创建分支。
在第二节的图中可以看到在正式发布版本1.1.0的同时还可以创建一个分支用来修复 将来这个版本可能遇到的重大 Bug。 这个过程可以手工完成例如使用svn copy 操作将主干代码复制到一个名为1.1.x 的分支中然后修改分支中的POM文件升级其版本为1.1.1-SNAPSHOT, 这会涉及很多Subversion 操作。
使用 Maven Release Plugin 的 branch 目标它能够帮我们自动化这些操作
检查本地有无未提交的代码。为分支更改 POM的版本例如从1.1.0-SNAPSHOT改变成1.1.1-SNAPSHOT。将POM中的 SCM 信息更新为分支地址。提交以上更改。将主干的代码复制到分支中。修改本地代码使其回退到分之前的版本(用户可以指定新的版本)。提交本地更改。
当然为了让Maven Release Plugin 为我们工作和版本发布一样必须在 POM 中提 供正确的SCM 信息。此外由于分支操作会涉及版本控制系统里的分支地址因此还要为 Maven Release Plugin 配置分支基础目录如代码
plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-release-plugin/artifactIdversion2.0/versionconfigurationtagBasehttps://192.168.1.103/app/tags//tagBasebranchBagehttps://192.168.1.103/app/branches//branchBase/configuration
/plugin然而 tagBase 和 branchBase 并非是一定要配置的。如果为版本控制仓库使用了标准的 Subversion 布局即在平行的 trunk/tags/branches 目录下分别放置项目主干代码、标签代码 和分支代码那么 Maven Release Plugin 就能够自动根据主干代码位置计算出标签及分支代码位置因此你就可以省略这两项配置。
理解了创建分支所将执行的实际行为后就可以在项目目录下运行如下命令以创建分支
$mvn release:branch -DbranchName1.1.x -DupdateBranchVersionstrue -DupdateworkingCopyVersionsfalse上述命令中使用了Maven Release Plugin 的 branch 目标 -DbranchName1.1.x 用来配置所要创建的分支的名称 -DupdateBranchVersionstrue 表示为分支使用新的版本 -DupdateWorkingCopyVersions false 表示不更新本地代码(即主干)的版本。运行上述命令之后 Maven 会提示输入分支项目的版本。例如
What is the branch version for app?(com.xiaoshan.mvnbook;app)1.1.1-SNAPSHOT::
用户根据自己的需要为分支输人新的版本后按 Enter 键 Maven 就会处理其余的操作。 最后用户就能在源码库中找到 Maven 创建的分支如 https://192.168.1.103/app/branches/1.1.x/ 。 在这里 POM 中的版本已经升级到了1.1.1-SNAPSHOT。
6️⃣ GPG签名
当从中央仓库下载第三方构件的时候你可能会想要验证这些文件的合法性例如它们是由开源项目官方发布的并且没有被篡改过。同样地当发布自己项目给客户使用的 时候你的客户也会想要验证这些文件是否是由你的项目组发布的且没有被恶意纂改过。 PGP(Pretty Good Privacy) 就是这样一个用来帮助提高安全性的技术。PGP 最常用来给电子 邮件进行加密、解密以及提供签名以提高电子邮件交流的安全性。本节介绍如何使用 PGP技术为发布的 Maven构件签名为项目增强安全性。
6.1 GPG 及其基本使用
GnuPG (简称 GPG, 来 自http://www.gnupg.org/) 是 PGP 标准的一个免费实现无论 是类 UNIX平台还是Windows平台都可以使用它。GPG 能够帮助我们为文件生成签名、管理密钥以及验证签名等。
首先访问 http://www.gnupg.org/download/ 并下载对应自己平台的 GPG 分发包按照官方的文档将 GPG 安装完毕运行如下命令检查安装
juvengjuven-ubuntu:~ $gpg --version
gpg(GnuPG) 1.4.9Copyright(C)2008 Free Software Foundation,Inc.
License GPLv3:GNU GPL version 3 or later在使用GPG 之前先得为自己准备一个密钥对即一个私钥和一个公钥。之后才可以使用私钥对文件进行签名并且将公钥分发到公钥服务器供其他用户下载用户可以使用 公钥对签名进行验证。 使用如下命令生成密钥对
juvenjuven-ubuntu:~$gpg --gen-keyGPG 会问你密钥的类型、大小和有效时间通常使用默认的值即可。GPG 还会要求你 输入自己的名称、电子邮件地址和对密钥的注释这些内容会被包含在公钥中并被你的用户看到因此务必正确填写。最后还可以提供一个密码来保护密钥这不是强制性的 但通常最好提供以防止别人得到你的密钥后恶意使用。你将来需要使用私钥和密码为文件 提供签名因此一定要认证保护它们。
现在已经有了密钥对就可以在命令行中查看它们(其他导入到本地机器的密钥也会被显示), 如下面的命令可用来列出所有公钥
juvenjuven-ubuntu: ~$gpg --list-keys
/home/juven/.gnupg/pubring.gpg
------------------------------
pub 1024D/C6EED57A 2010-01-13
uid Juven Xu(Juven Xu works at Sonatype)juvensonatype.com
sub 2048g/D704745C 2010-01-13这里的/home/juven/.gnupg/pubring.gpg表示公钥存储的位置。以 pub 开头的一行显示 公钥的长度(1024D) 、ID(C6EED57A) 以及创建日期(2010-01-13)。下一行显示了公钥 的UID, 也就是一个由名称、注释和邮件地址组成的字符串。最后一行显示的子钥不用关心。
类似地下面的命令用来列出本机私钥
juvenjuven-ubuntu: ~$gpg --list -secret-keys
/home/juven/.gnupg/secring.gpg
sec 1024D/C6EED57A 2010-01-13
uid Juven Xu(Juven Xu works at Sonatype)
ssb 2048g/D704745C 2010-01-13对 GPG 的公私钥有了基本的了解之后就可以使用如下命令为任意文件创建一个 ASCII格式的签名
juvenjuven-ubuntu: ~$gpg -ab temp.java这里的 -a 选项告诉GPG 创建ASCIⅡ 格式的输出而-b 选项则告诉GPG 创建一个独立的签名文件。如果你的私钥拥有密码这个时候就需要输入密码。如果私钥没有密码 那么只要他人获得了你的私钥就能够以你的名义对任何内容进行签名这是非常危险的。
在该例中 GPG 会创建一个名为 temp.java.asc 的签名文件这时就可以将这个后缀名 为 .ase 的签名文件连同原始文件一起分发给你的用户。如果你的用户已经导入了你的公 钥就可以运行如下命令验证原始文件
$gpg --verify temp.java.asc为了能让你的用户获取公钥并验证你分发的文件需要将公钥分发到公钥服务器中。 例 如 hkp://pgp.mit.edu 是美国麻省理工学院提供的公钥服务器运行如下命令可将公钥 分发到该服务器中
$gpg --keyserver hkp://pgp.mit.edu --send-keys C6EED57A这里的–keyserver 选项用来指定分发服务器的地址 --send-keys 用来指定想要分发公钥的 ID 。你可以罗列本地公钥来查看它们的ID 。需要注意的是公钥会在各个公钥服务器中被同步因此你不需要重复地往各个服务器分发同一公钥。 现在你的用户可以将服务器上的公钥导入到本地机器
$gpg --keyserver hkp://pgp.mit.edu --recv-keys C6EED57A上述就是一个基本的签名、分发并验证的流程在使用Maven 发布项目的时候可以 使 用GPG 为发布文件提供签名。现在读者应该已经知道如何手工完成这一步骤了下面介 绍如何使用 Maven GPG Plugin 自动化签名这一步骤。 6.2 Maven GPG Plugin
手动地对 Maven构件进行签名并将这些签名部署到 Maven 仓库中是一件耗时的体力活。 而使用Maven GPG Plugin 只需要提供几行简单的配置它就能够帮我们自动完成签名这一工作。 在使用 Maven GPG Plugin 之前首先需要确认命令行下的 gpg 是可用的然后如代码 所示配置 POM。
projectbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-gpg-plugin/artifactIdversion1.0/versionexecutionsexecutionidsign-artifacts/idphaseverify/phasegoalsgoalsign/goal/goals/execution/executions/plugin/plugins/build
/project然后就可以使用一般的 mvn命令签名并发布项目构件
$mvn clean deploy -Dgpg.passphraseyourpasephrase如果不提供-Dgpg.passphrase 参数运行时就会要求输入密码。 如果有一些已经发布了但没有被签名的文件你仍然想对其签名并发布到 Maven 仓库 中上述方式显然是行不通的因为POM已经不允许被修改。好在 Maven GPG Plugin 为此 提供了另外一个目标。例如
$mvn gpg:sign-and-deploy-file-DpomFiletarget/myapp-1.0.pom-Dfiletarget/myapp-1.0.jar-Durlhttp://oss.sonatype.org/service/local/staging/deploy/maven2/-DrepositoryIdsonatype_oss在这里可以指定要签名的POM 及相关文件、Maven 仓库的地址和 ID, Maven GPG Plugin 就会帮你签名文件并部署到仓库中。
读者可以想到 GPG 签名这一步骤只有在项目发布时才显得必要对日常的 SNAPSHOT构件进行签名不仅没有多大的意义反而会比较耗时。因此只需要配置 Maven PGP Plugin 在项目发布的时候运行那么如何判断项目发布呢? 回顾代码, 在超级 POM中有一个 release-profile, 该 Profile 只有在 Maven 属性 performRelease 为 true 的时候才被激活而 release:perform执行的时候就会将该属性置为 true, 这正是项目进行版本发布的时刻。因此类似地可以在 settings.xml 或者 POM 中创建如代码所示 Profile
profilesprofileidrelease-sign-artifacts/idactivationpropertynameperformRelease/namevaluetrue/value/property/activationbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-gpg-plugin/artifactIdversion1.0/versionexecutionsexecutionidsign-artifacts/idphaseverify/phasegoalsgoal/sign/goal/goals/execution/executions/plugin/plugins/build/profile
/profiles最后需要一提的是由于一个已知的Maven Release Plugin 的Bug, release:perform 执行过程中签名可能会导致进程永久挂起。为了避免该情况用户需要为 Maven Release Plugin 提供mavenExecutorld 配置如代码所示
plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-release-plugin/artifactIdversion2.0/versionconfigurationtagBasehttps://192.168.1.103/app/tags//tagBasebranchBasehttps://192.168.1.103/app/branches//branchBasemavenExecutorIdforked-path/mavenExecutorId/configuration
/plugin至此 一个较为规范的自动化签名配置就完成了。当执行 release:perform 发布项目版 本的时候maven-gpg-plugin 会被自动调用对构件进行签名。当然这个时候你需要根据命令行提示输入私钥密码。 总结
项目开发到一定阶段后就必然要面对版本发布的问题本文介绍了Maven 的版本管理方式包括快照版和发布版之间的转换、各种版本号的意义以及项目版本与版本控制系统 ( 如 Subversion) 之间的关系。理解了版本转换与SCM 操作的关系后就可以使用Maven Release Plugin 自动化版本发布和创建分支等操作。最后介绍了如何在版本发布的时候使用GPG 为构件提供签名以提供更强的安全性。 ⏪ 温习回顾上一篇点击跳转 《【Maven教程】十一使用 Maven 构建 Web应用 —— 使用 jetty-maven-plugin 进行测试、使用 Cargo 实现自动化部署~》 ⏩ 继续阅读下一篇点击跳转 《》