问题说明
考虑在哈德森上使用maven的情况。
现在有人检查了一个项目,修改了一些文件,但意外地使用了相同的工件ID和版本号(非快照)。
然后,他/她在哈德森上构建了这个项目并做了maven安装。修改后的工件现在是hudson .m2。任何其他依赖它的项目都将使用经过修改的工件构建。如果编译没有失败,没有人发现这一点。即使正确的工件驻留在中央存储库中,它也永远不会被使用,因为当hudson开始构建时,会从.m2中选择修改过的工件。所以我正在寻找一种方法来防止这种意外的人为错误。
我已经检查过没有办法强制从中央存储库更新非快照版本,因为它们是不可变的。
清除中央存储库或为hudson上的每个作业使用单独的存储库将导致构建时间增加&磁盘空间分别使用。
任何帮助都将不胜感激。
答案 0 :(得分:1)
我认为你不会找到一种方法来阻止安装覆盖工件。存储库服务器应具有防止部署更新的发布工件的设置。例如,请参阅Nexus的"How do I disable artifact redeployment"。
答案 1 :(得分:1)
以下是我们如何管理项目中的版本:
我们处理SNAPSHOT
版本。在Jenkins上,我们有一个构建和测试此应用程序的 Fast Build 作业,但如果版本不 a SNAPSHOT
则会失败。这是由custom enforcer完成的(这与require release version enforcer相反)。
当我们想要发布时,我们使用Jenkins的工作。使用parameterized build和Maven release plugin,负责执行发布的人员只会指出发布的版本(稳定版本),下一个SNAPSHOT
版本作为SCM标记的名称。因此,只有Jenkins将定义一个稳定的版本,开发人员将始终使用SNAPSHOT
代码。
但是,当然,这并不妨碍开发人员在他的本地机器上做出他想要的东西。但我们总是考虑一个值得信赖的地方:Jenkins服务器。 它适用于我的机器永远不是一个问题的好答案; o)
答案 2 :(得分:1)
没有直接的方法可以解决这个问题,但我们通过编写一个每5分钟运行一次的cron-job来解决这个问题,并将所有NON-SNAPSHOT的罐子标记为只读在Hundson的本地存储库中。通过这种方式,当Hudson中的某个项目试图覆盖它时,我的mvn install或mvn deploy会因为只读它们而无法覆盖工件。
可以轻松编写任何要重新发布的新工件。一旦在接下来的五分钟内写入,脚本就会将它们标记为只读。
以下是unix脚本permission-handler.sh
的代码#!/bin/bash
cd ~/.m2
date 2>&1>> permission-handler.out
find . -name '*jar' -type f | grep -v 'SNAPSHOT' | xargs chmod -vc 444 2>&1>> permission-handler.out
chmod 777 permission-handler.out
还会处理日志记录,以查看哪些工件已标记为仅已发布。
答案 3 :(得分:0)
通过将Maven存储库(例如Nexus,Artifactory)配置为不允许覆盖发布存储库来解决此问题。在Nexus中,我们有一个SNAPSHOT的回购和一个用于发布的回购。 SNAPSHOT repo允许覆盖。但是发布回购不允许覆盖。这只是Nexus中针对该回购的简单复选框功能。一旦发布版本放入repo,它就不能被覆盖。效果很好。
答案 4 :(得分:0)
我有相同的要求。 可以通过gradle任务的REST请求来完成对工件的检查。
publish.dependsOn lookForArtifacts
task lookForArtifacts {
group "upload"
doLast {
def pomFileName = "${ARTIFACT_ID}-${ARTIFACT_VERSION}.pom"
def artifactPath = "${ARTIFACT_GROUP.replace(".", "/")}/${ARTIFACT_ID}/${ARTIFACT_VERSION}/${pomFileName}"
def repositoryUrl = "$MAVEN_SERVER/${artifactPath}"
println("# searching for existing artifact wit id ${ARTIFACT_VERSION}")
println("")
if (urlExists(repositoryUrl)) {
println("# Existing artifact found")
println("")
throw new RuntimeException("Artifact with version $ARTIFACT_VERSION already exist - increase the verion to publish")
} else {
println("# No existing artifact found. Preceding to publish")
println("")
}
}
}
def urlExists(String repositoryUrl) {
try {
def connection = (HttpURLConnection) new URL(repositoryUrl).openConnection()
connection.setRequestProperty("Authorization", "Basic " + getBase64EncodedCredentials())
connection.setConnectTimeout(10000)
connection.setReadTimeout(10000)
connection.setRequestMethod("HEAD")
def responseCode = connection.getResponseCode()
if (responseCode == 401) {
throw new RuntimeException("Unauthorized MavenUser user. Please provide valid username and password.")
}
return (200 == responseCode)
} catch (IOException ignored) {
println(ignored)
return false
}
}
def getBase64EncodedCredentials() {
def s = "$MAVEN_USERNAME" + ":" + "$MAVEN_PASSWORD"
return s.bytes.encodeBase64().toString()
}