You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle配置:避免发布已存在的重复构件

解决Gradle maven-publish重复发布相同构件失败的问题

核心思路

Gradle的maven-publish插件默认不会校验远程仓库中已存在构件的校验和,我们需要自定义前置检查逻辑:生成本地构件的校验和,远程查询对应构件的校验和,若两者一致则禁用publish任务,避免触发仓库的覆盖限制导致流水线失败。

具体实现步骤

1. 添加校验依赖

在构建脚本中引入计算文件校验和的依赖(使用Apache Commons Codec):

buildscript {
    dependencies {
        classpath("commons-codec:commons-codec:1.15")
    }
}

2. 自定义远程校验任务

注册一个前置任务,用于对比本地与远程构件的校验和:

tasks.register("checkRemoteArtifact") {
    // 确保本地jar构件已生成
    dependsOn(tasks.jar)

    doLast {
        val jarTask = tasks.jar.get()
        val localJar = jarTask.archiveFile.get().asFile
        // 计算本地jar的SHA-1校验和(可替换为SHA-256/MD5)
        val localSha1 = localJar.inputStream().use { 
            org.apache.commons.codec.digest.DigestUtils.sha1Hex(it) 
        }

        // 动态获取当前要发布的正式仓库URL(根据你的分支/参数配置逻辑调整)
        val targetRepo = publishing.repositories.filterIsInstance<MavenArtifactRepository>()
            .first { it.url.toString().contains("release") } // 替换为你的正式仓库标识
        val repoUrl = targetRepo.url.toString().trimEnd('/')
        
        // 拼接远程构件的SHA-1文件路径(遵循Maven仓库标准布局)
        val artifactGroupPath = project.group.toString().replace('.', '/')
        val artifactFileName = "${jarTask.archiveBaseName.get()}-${project.version}.jar"
        val remoteSha1Url = "$repoUrl/$artifactGroupPath/${project.name}/${project.version}/$artifactFileName.sha1"

        try {
            // 读取远程校验和文件内容
            val remoteSha1 = java.net.URL(remoteSha1Url).readText().trim()
            if (remoteSha1 == localSha1) {
                println("✅ 远程构件校验和匹配,跳过发布任务")
                tasks.publish.get().enabled = false
            } else {
                println("⚠️ 远程构件校验和不匹配,执行发布")
            }
        } catch (e: java.io.FileNotFoundException) {
            println("ℹ️ 远程构件不存在,执行发布")
        } catch (e: Exception) {
            // 网络异常等情况默认继续发布,避免误阻断正常流程
            println("⚠️ 检查远程构件时出错:${e.message},继续执行发布")
        }
    }
}

// 让publish任务依赖这个校验任务
tasks.publish.configure {
    dependsOn("checkRemoteArtifact")
}

3. 适配你的仓库配置

  • 调整targetRepo的过滤逻辑:根据你当前分支/命令参数选择正式仓库的规则,替换contains("release")为实际的判断条件(比如仓库URL包含特定关键词)。
  • 如果使用其他校验算法,替换DigestUtils.sha1Hex为sha256Hex或md5Hex,同时修改远程URL的后缀为.sha256或.md5。

多模块项目适配

如果是多模块项目,将上述配置放在根项目的build.gradle.kts中,通过subprojects块统一配置:

subprojects {
    apply(plugin = "maven-publish")
    // 在此添加子模块的publish配置及checkRemoteArtifact任务
}

关键注意事项

  • 依赖你已配置的可复现归档任务:isPreserveFileTimestamps = false和isReproducibleFileOrder = true确保本地构件校验和稳定,对比结果可信。
  • 异常处理逻辑:网络错误等场景下默认继续发布,避免因非构件本身的问题中断流水线。
  • 仓库权限:确保执行Gradle任务的CI/CD账号有读取远程仓库校验和文件的权限。

内容的提问来源于stack exchange,提问作者Quinteger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:34:51