Gradle Artifactory插件能否发布非Maven格式的纯二进制文件?
我完全懂你的痛点——想上传无POM、无Maven坐标的纯二进制文件到Artifactory,不想被maven-publish插件绑定,自定义Publication又碰壁。确实,Gradle的publishing.publications容器只认内置的MavenPublication和IvyPublication,自定义接口根本不会被识别,这条路走不通。
下面给你两个可行的方案,完全避开Maven/Ivy的约束:
方案1:用Artifactory插件自带的uploadSpec(推荐)
Artifactory Gradle插件本身就支持直接上传任意文件,不用依赖Gradle的publishing系统。你可以直接在artifactory.publish块里用uploadSpec替代publications,示例代码如下:
artifactory { contextUrl = artifactoryConfig.context // 你的本地Artifactory地址,比如http://localhost:8081/artifactory publish { repository { repoKey = "generic-local" // 替换成你要上传的仓库Key,比如通用仓库generic-local username = artifactoryConfig.username password = artifactoryConfig.password } // 核心:用uploadSpec定义要上传的文件,完全不需要Publication uploadSpec { // 指定本地要上传的二进制文件 file(file("/absolute/path/to/your/binary/file.bin")) { // 设置文件在Artifactory中的目标路径(可选,不设就传到仓库根目录) targetPath = "my-custom-binaries/2024" // 可选:给文件加自定义属性,方便后续检索 properties = ["file.type": "binary", "project": "my-app"] } // 如果要传多个文件,直接加多个file块即可 // file(file("/another/path/another-file.exe")) { ... } } } }
为什么这个方案可行?
uploadSpec是Artifactory插件专门为任意文件上传设计的API,完全绕开了Gradle的publishing机制,不需要定义任何Maven/Ivy相关的坐标或配置,完美匹配你要上传纯二进制文件的需求。执行gradle artifactoryPublish就能完成上传。
方案2:直接用Gradle任务调用Artifactory HTTP API
如果你不想依赖Artifactory插件,也可以直接写一个Gradle任务,通过HTTP PUT请求上传文件,和你提到的命令行方法本质一样,但集成在Gradle构建流程里:
方法A:用curl命令(简单直接)
task uploadBinaryToArtifactory(type: Exec) { def targetUrl = "${artifactoryConfig.context}/generic-local/my-custom-binaries/file.bin" commandLine "curl", "-u", "${artifactoryConfig.username}:${artifactoryConfig.password}", "-T", "/path/to/your/file.bin", targetUrl }
执行gradle uploadBinaryToArtifactory即可,前提是系统里装了curl。
方法B:纯Groovy/Java实现(无需curl)
如果不想依赖外部工具,用Gradle自带的Java HTTP API实现:
import org.apache.commons.codec.binary.Base64 task uploadBinaryToArtifactory { doLast { def fileToUpload = file("/path/to/your/binary/file.bin") def artifactoryUrl = "${artifactoryConfig.context}/generic-local/my-custom-binaries/${fileToUpload.name}" def connection = new URL(artifactoryUrl).openConnection() as HttpURLConnection connection.requestMethod = "PUT" // 配置Basic认证 def auth = "${artifactoryConfig.username}:${artifactoryConfig.password}" def encodedAuth = Base64.encodeBase64String(auth.getBytes()) connection.setRequestProperty("Authorization", "Basic ${encodedAuth}") connection.doOutput = true // 写入文件内容到请求体 fileToUpload.withInputStream { inputStream -> connection.outputStream.withStream { outputStream -> inputStream.copyTo(outputStream) } } // 检查响应状态 if (connection.responseCode in 200..299) { println "✅ 文件上传成功!响应:${connection.responseMessage}" } else { throw new GradleException("❌ 上传失败,状态码:${connection.responseCode},消息:${connection.responseMessage}") } } }
为什么自定义FilePublication行不通?
Gradle的publishing.publications容器是一个强类型的注册中心,只有Gradle官方或插件主动注册的Publication类型才会被识别。你自定义的FilePublication接口没有被注册到这个容器里,所以会抛出Cannot create a FilePublication because this type is not known的错误,这条路确实走不通,不用再尝试了。
内容的提问来源于stack exchange,提问作者Nilzor

