我在我的 Hudson 服务器中配置了一个 Maven 3 作业。
当 Hudson 服务器成功构建 Maven jar 时,我将该 jar 部署到另一台服务器上的 SCP 存储库。
我想在远程主机上执行 relink.sh 脚本,其中一个参数是新交付的 jar 文件的名称(例如 /usr/bin/relink.sh myproject-0.0.2-SNAPSHOT.jar)。
如何将基于 Maven 的文件/版本名称放入变量中,然后在 Hudson 调用中使用该变量来执行远程脚本?
答案1
我不确定您是否可以传递变量,但一种解决方法是先将文件复制到暂存目录,而不是直接复制到您希望它去的地方。然后让您的脚本在暂存目录中查找文件并移动它:
STAGE_DIR=/path/to/stage
DEST_DIR=/path/to/dest
LINK=/path/to/link.jar
while read file; do
mv $file $DEST_DIR
ln -s -f $DEST_DIR/$(basename $file) $LINK
done < <( find $STAGE_DIR -name "myproject*SNAPSHOT.jar" )
您可能需要进行一些错误检查,如果有多个匹配的文件、没有文件等,则以非 0 退出。您解决这个问题了吗?
答案2
就像 @zerodiff 建议的那样,似乎有很多方法可以通过 Hudson 来实现这一点,但在管理大量项目时,这些方法似乎都很脆弱且难以维护。我改用 Maven 的 wagon 插件通过 Maven 而不是 Hudson 来实现部署。
我在maven项目中使用的配置:
<properties>
<!-- Deploy -->
<dev.server.hostname>192.168.1.1</dev.server.hostname>
<application.name>test-application</application.name>
<!-- Deploy -->
</properties>
<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>1.0</version>
</extension>
</extensions>
</build>
<profiles>
<profile>
<id>hudson</id>
<activation>
<property>
<name>env</name>
<value>hudson</value>
</property>
</activation>
<build>
<filters>
<filter>src/main/filters/${env}-linux.properties</filter>
<filter>src/main/filters/${env}.properties</filter>
</filters>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>wagon-maven-plugin</artifactId>
<version>1.0-beta-5</version>
<executions>
<execution>
<id>dev-deploy</id>
<phase>deploy</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<fromDir>${project.build.directory}</fromDir>
<includes>${project.build.finalName}.jar</includes>
<url>scp://${dev.server.hostname}/</url>
<toDir>/opt/${application.name}</toDir>
<serverId>dev-deploy-server</serverId>
</configuration>
</execution>
<execution>
<id>execute-dev-deploy-commands</id>
<phase>deploy</phase>
<goals>
<goal>sshexec</goal>
</goals>
<configuration>
<url>scp://${dev.server.hostname}/</url>
<serverId>dev-deploy-server</serverId>
<commands>
<command>sudo /etc/init.d/${application.name} stop</command>
<command>sleep 2</command>
<command>sudo /opt/${application.name}/relink.sh ${project.build.finalName}.jar</command>
<command>sudo /etc/init.d/${application.name} start</command>
</commands>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
在我的 maven settings.xml 中,我有 dev-deploy-server 的凭证:
<server>
<id>dev-deploy-server</id>
<username>hudson_bot</username>
</server>
使用 Hudson 中的 Maven 插件,我添加了“Invoke Maven 3”构建指令并:
- 目标:清洁部署
- 属性:env=hudson
最后,我在两台服务器之间设置了安全性,以便“hudson_bot”可以 scp 到 dev-deploy-server,并授予 hudson_bot sudoer NO_PASSWD 权限给 ssh 执行元素中提到的两个脚本。
答案3
您希望从 Maven 本身获取 jar 工件名称,以防止在开发人员更改工件的 ID 或版本时调整脚本。扫描*.jar
文件并不优雅,因为它会匹配超过主工件(例如*-javadoc.jar
)。因此,要从 Maven 获取主工件版本,我依赖 2 个事实:
- 默认情况下,jar 插件使用工件的 id 和版本作为最终的 jar 工件,例如
target/the-service-0.0.1-SNAPSHOT.jar
工件的 ID、组和版本存储在
pom.properties
$ cat target/maven-archiver/pom.properties #Generated by Apache Maven #Fri Jul 06 15:10:03 CEST 2018 version=0.0.1-SNAPSHOT groupId=net.company artifactId=the-service
请注意,java 开发人员仍然可以更改默认构建文件夹target
并破坏您的 hudson 作业。