如何将 Jenkins 中的特定工件部署到 Nexus 中?

Posted

技术标签:

【中文标题】如何将 Jenkins 中的特定工件部署到 Nexus 中?【英文标题】:How can you deploy a specific artifact from Jenkins into Nexus? 【发布时间】:2014-07-26 23:41:33 【问题描述】:

我有一个在 Jenkins 中运行的多模块 maven 项目。我想将最终工件(来自程序集构建的 RPM)部署到 Nexus 服务器。我认为没有理由部署中间工件(因此没有“mvn clean deploy”),因为这会在服务器上产生我不需要的额外垃圾。我们正在尝试建立一个持续交付管道,因此我们永远不会部署 SNAPSHOT 版本。 Jenkins 的各种插件似乎专注于部署所有工件。我怎样才能只部署我选择的那个?

编辑:

经过深思熟虑,如果部署发生在所有构建完成之后,我愿意将所有工件部署到 nexus。如果我走这条路,我想使用“将工件部署到 Maven 存储库”构建后操作。这个工具似乎坏了,因为它缺少指定用户名/密码的功能。我知道这可以在 settings.xml 中指定,但显然只有“.m2”中的那个。它似乎没有查看我为此构建指定的 settings.xml。

这似乎也因重新部署工件而损坏。在“Jenkins the Definitive Guide”中有一些verbage,但它谈到了“本地”settings.xml。我所有的构建都发生在 Jenkins 从属服务器上,所以这不是一个选择,甚至对 Jenkins 架构也没有任何意义。

【问题讨论】:

【参考方案1】:

您可以使用 Nexus Jenkins 插件 将特定工件从 Jenkins 部署到 Nexus: https://support.sonatype.com/hc/en-us/articles/227256688-How-do-I-configure-the-Nexus-Jenkins-Plugin

Jenkins 流水线示例:

stage('Publish') 
    def pom = readMavenPom file: 'pom.xml'
    nexusPublisher nexusInstanceId: 'your-nexus-instance-id', \
        nexusRepositoryId: 'your-nexus-repository-id', \
        packages: [[$class: 'MavenPackage', \
        mavenAssetList: [[classifier: '', extension: '', filePath: "target/$pom.artifactId-$pom.version.$pom.packaging"]], \
        mavenCoordinate: [artifactId: "$pom.artifactId", \
        groupId: "$pom.groupId", \
        packaging: "$pom.packaging", \
        version: "$pom.version"]]]

在这种情况下,Nexus Jenkins 插件只会将您的 target/$pom.artifactId-$pom.version.$pom.packagingpom.xml 文件部署到 Nexus 存储库。

【讨论】:

【参考方案2】:

如果你还需要通用的方式。

使用 Execute shell 选项并手动使用 mvn deploy 命令,您可以将您的版本和其他内容(例如 groupID 等)作为参数传递给作业,如果您维护单独的作业来构建和上传,这将解决。

例如:

导出 M2_HOME=/PATH/TO/softwares/apache-maven-3.0.4 PATH=$M2_HOME/bin:$JAVA_HOME/bin:$PATH 导出路径

mvn -v

mvn deploy:deploy-file -Durl=http://someorg:8081/nexus/content/repositories/t1.snapshot/ -DrepositoryId=t1.snapshot -DartifactId=artifactID -DgroupId=groupID -Dpackaging=zip -Dfile=$WORKSPACE/filename.zip -Dversion=1.0-TEST -SNAPSHOT -s "/path/to/.m2/settings.xml"

【讨论】:

【参考方案3】:

这是我想出的丑陋的 hack。如果有人有更好的主意,我很乐意为此给其他人“正确”的答案:

我意识到我需要同时部署父 pom.xml 和程序集。我在两个单独的后期构建步骤中做到了这一点。

首先,我选择了“调用*** Maven 目标”和“Maven”的 Maven 版本(我认为这使用了 Jenkins 版本的 Maven。我不想在系统上放置不同的版本)。我使用了以下目标:

-s svn-admin/settings.xml -N deploy

使用我指定的 settings.xml 仅将父 pom 部署到 nexus。

当我想部署 rpm 时,发生了真正的大黑客攻击。我尝试了“部署文件”目标,但没有变量我可以扩展为版本号,我无法指定确切的文件并且通配符不会扩展。相反,我做了一个“执行 shell”选项并使用 curl 我找到了 here:

env
UPLOAD_FILE=assembly/target/ips-$POM_VERSION-x.x86_64.rpm
DESTINATION=http://mvnrepo01/nexus/content/repositories/releases/com/bla/ips/assembly/$POM_VERSION/assembly-$POM_VERSION.rpm
sha1sum $UPLOAD_FILE | awk -F" " 'print $1' | curl -v -u admin:password --upload-file - $DESTINATION.sha1
md5sum $UPLOAD_FILE | awk -F" " 'print $1' | curl -v -u admin:password --upload-file - $DESTINATION.md5
curl -v -u admin:password --upload-file $UPLOAD_FILE $DESTINATION

UPLOAD_FILE=assembly/pom.xml
DESTINATION=http://mvnrepo01/nexus/content/repositories/releases/com/bla/ips/assembly/$POM_VERSION/assembly-$POM_VERSION.pom
sha1sum $UPLOAD_FILE | awk -F" " 'print $1' | curl -v -u admin:password --upload-file - $DESTINATION.sha1
md5sum $UPLOAD_FILE | awk -F" " 'print $1' | curl -v -u admin:password --upload-file - $DESTINATION.md5
curl -v -u admin:password --upload-file $UPLOAD_FILE $DESTINATION

就像我说的,这是一个丑陋的 hack。我很确定有些元数据文件没有更新,但是 rpm、它是 pom,并且它们的校验和正在上传。

【讨论】:

【参考方案4】:

您可以使用“构建后操作”下的“将工件部署到 Maven 存储库”。看看这个answer

【讨论】:

不会部署构建中的所有工件吗?那不是我想要的。我只想要最终的工件(一个 rpm),并且它是必要的父 pom。 而且显然只有使用具有用户名密码的 .m2/settings.xml 才能执行此操作(我正在从 svn 中检查 settings.xml)。

以上是关于如何将 Jenkins 中的特定工件部署到 Nexus 中?的主要内容,如果未能解决你的问题,请参考以下文章

没有使用 jenkins gradle artifactory 插件部署的工件

Jenkins - 在作业删除时删除已部署的工件

如何将 npm 包发布/部署到自定义工件

如何在将通用工件上传到jenkins管道中的JFrog Artifactory时重命名现有文件夹

如何部署和运行 Play! 2.1 通过 Jenkins 到 EC2

用于CI和CD部署的BlackDuck扫描集成