【问题标题】:Gradle publish attemps to upload RPM to Artifactory YUM repo twice, second time fails with 403Gradle 发布尝试将 RPM 上传到 Artifactory YUM repo 两次,第二次失败,出现 403
【发布时间】:2018-02-06 00:08:48
【问题描述】:

我正在尝试使用 gradle 和 ivy-publish 插件将 RPM 工件发布到 Artifactory 上的本地 YUM 存储库。我遇到的问题是发布任务似乎尝试上传工件两次,第二次尝试失败(正确),HTTP 状态代码为 403。我进行身份验证的工件用户具有部署/缓存权限但不删除.

我的问题是为什么发布任务会尝试两次上传工件?

我在下面包含了我的 gradle 配置和工件日志文件的摘录。请注意,RPM 是使用 netflix os-package 构建的

Gradle Config 发布配置:

apply plugin: "ivy-publish"

publishing {
    publications {
        rpm(IvyPublication) {
            artifact  buildRpm.outputs.getFiles().getSingleFile()
            /* Ivy plugin forces an organisation to be set. Set it to anything
               as the pattern layout later supresses it from appearing in the filename */
            organisation 'dummy'
        }
    }
    repositories {
        ivy {
            credentials {
                username 'username'
                password 'password'
            }
            url 'http://my.artifactory.com/artifactory/yum-dev-local/'
            layout "pattern", {
                artifact "${buildRpm.outputs.getFiles().getSingleFile().getName()}"
            }
        }
    }
}

为了构建和发布工件,我执行以下操作(工件上有一个空的 yum-local repo)

./gradlew clean buildRpm publish

产生以下内容:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':my-artifact-service:publishRpmPublicationToIvyRepository'.
> Failed to publish publication 'rpm' to repository 'ivy'
> java.io.IOException: Could not PUT   'http://my.artifactory.com/artifactory/yum-dev-local/my-artifact-service-0.0.1-1.el7.x86_64.rpm'. Received status code 403 from server: Forbidden

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Artifactory 日志显示:

2016-10-12 15:41:41,828 [http-nio-8081-exec-92] [INFO ] (o.a.e.UploadServiceImpl:453) - Deploy to 'yum-dev-local:my-artifact-service-0.0.1-1.el7.x86_64.rpm' Content-Length: 4420
2016-10-12 15:41:41,842 [http-nio-8081-exec-64] [INFO ] (o.a.e.UploadServiceImpl:299) - Deploy to 'yum-dev-local:my-artifact-service-0.0.1-1.el7.x86_64.rpm.sha1' Content-Length: 40
2016-10-12 15:41:41,850 [http-nio-8081-exec-90] [WARN ] (o.a.r.ArtifactoryResponseBase:105) - Sending HTTP error code 403: Not enough permissions to overwrite artifact 'yum-dev-local:my-artifact-service-0.0.1-1.el7.x86_64.rpm' (user 'username' needs DELETE permission).

最后的日志行表明请求再次 PUT 工件。当我检查 repo 时,工件确实已成功上传,但是发布任务失败。有人能指出这里发生了什么吗?

版本:

------------------------------------------------------------
Gradle 2.14.1
------------------------------------------------------------

Build time:   2016-07-18 06:38:37 UTC
Revision:     d9e2113d9fb05a5caabba61798bdb8dfdca83719

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_73 (Oracle Corporation 25.73-b02)
OS:           Linux 4.3.5-300.fc23.x86_64 amd64

【问题讨论】:

  • 您解决了这个问题吗?我也一样
  • 与您的问题无关的评论。运行“gradle clean ”是一种反模式。可能这是您在使用 Maven 时学到的东西,对吧?与 Maven 不同,Gradle 在确定何时需要重建工件以及何时通过不重建工件可以节省时间方面非常好。如果您始终将“干净”应用为构建的一部分,那么您就会否定这一优势,并且构建速度会变慢。
  • @Jolta 感谢您的提示,是的,您说得对,这可能是我从使用 Maven 继承下来的习惯

标签: java gradle artifactory gradlew


【解决方案1】:

这是因为 Gradle Ivy 发布插件会推送,除了您的工件之外,3 个额外文件,它们是:

  • 一个 .sha1 文件,其中包含您的工件的校验和
  • .xml Ivy 包文件,其中包含有关工件的信息
  • 前一个 xml 的 .sha1 文件

问题出在第一个 .sha1 文件上。上传这个的时候,Artifactory / JFrog 会认为你要覆盖之前上传的同名神器,因此报错。

您可能认为仅授予 DELETE 权限就可以解决问题,但事实并非如此。这样做只会用校验和 .sha1 文件替换您之前上传的软件包,并且由于这种文件不是有效的 .deb 文件(在我的情况下,在您的 .rpm 中),因此在解压缩和生成 Debian 存储库结构时,它只会清除您的原始工件,因此您将无法正常下载。

不幸的是,没有办法解决这个问题,因为我知道 (https://github.com/gradle/gradle/blob/master/subprojects/dependency-management/src/main/java/org/gradle/api/internal/artifacts/repositories/resolver/ExternalResourceResolver.java#L266)

最后,我采用的解决方案是直接使用 curl 直接 PUT 到 Artifactory / JFrog,这实际上减少了代码,但增加了操作系统依赖 (curl)。如果您担心这一点,您可以使用 Gradle HTTP 库来做同样的事情:

task uploadArtifactory(type: Exec) {

    def artifact = buildDeb.outputs.getFiles().filter {
        it.getAbsolutePath().endsWith ".deb"
    }.getSingleFile()

    commandLine "curl",
        "-X",
        "PUT",
        "https://$artifactoryUser:$artifactoryPassword@$artifactoryAccount.jfrog.io/$artifactoryAccount/$artifactoryRepo/pool/${project.name}_${version}_all.deb;deb.distribution={...};deb.component=main;deb.architecture=all",
        "--upload-file",
        artifact
}

【讨论】:

    【解决方案2】:

    我也有类似的问题。

    使用 Gradle Artifactory 插件解决。

    其他答案中提供的示例配置:

    https://stackoverflow.com/a/41238443/575350

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 1970-01-01
      • 2012-05-25
      • 1970-01-01
      • 2020-08-31
      • 2022-08-15
      • 2013-07-20
      • 1970-01-01
      • 2014-05-27
      相关资源
      最近更新 更多