我最近与Gradle一起开始了一个新项目 ,并决定直接参加–没有Gradle经验,没有关于Groovy的线索,没有教程,只是继续尝试直到可行。 在我决定使用孵化式maven-publish插件将快照发布到Sonatype的Maven快照存储库之前,这一切进展得令人惊奇,这确实令人信服。
警告:正如我说的那样,我在Groovy和Gradle中都是菜鸟,所以不要相信我所说的话。 我为您写下来的一切。
最后(但仍是部分的)的build.gradle文件可以找到这里 ,我在我的项目中使用的实际变异这里 。
第一步,确保存在项目的组,ID和版本。 通常可以在build.gradle文件中找到第一个和最后一个,项目名称的ID会加倍,并在settings.gradle中定义。
激活
好了,走吧! 首先,我激活了插件:
apply plugin: 'maven-publish'
要开始发布内容,我需要以下内容:
publishing {publications {mavenJava(MavenPublication) {from components.java// more goes in here}}repositories {mavenLocal()}}
如您所见,我首先发布到本地仓库。 事实上,运行gradle
publish
现在应该创建一个JAR,并在一些一个基本POM。m2
个子文件夹。 从这里开始,我可以逐步添加更多功能。
填充POM
发布工件需要什么? 完整的Maven pom。 由于我没有pom.xml
,我在哪里可以得到它? 我用一些Gradle XML API创建它。 明显。 为什么不使用Maven直接获得pom? 如果我知道该死的...
因此,在mavenJava
里面mavenJava
东西(这是什么?我想是一个任务?),我创建了pom。 在解决以下语法之前,我花了一些时间尝试这种方式:
pom.withXml {asNode().with {appendNode('packaging', 'jar')appendNode('name', 'PROJECT_NAME')appendNode('description', 'PROJECT_DESCRIPTION')appendNode('url', 'PROJECT_URL')appendNode('scm').with {appendNode('url', 'SCM_URL_FOR_PEOPLE')appendNode('connection', 'SCM_URL_FOR_SCM')}appendNode('issueManagement').with {appendNode('url', 'ISSUE_TRACKER_URL')appendNode('system', 'ISSUE_TRACKER_NAME')}appendNode('licenses').with {appendNode('license').with {appendNode('name', 'LICENSE_NAME')appendNode('url', 'LICENSE_URL')}}appendNode('organization').with {appendNode('name', 'ORG_NAME')appendNode('url', 'ORG_URL')}appendNode('developers').with {appendNode('developer').with {appendNode('id', 'DEV_HANDLE')appendNode('name', 'DEV_NAME')appendNode('email', 'DEV_MAIL')appendNode('organization', 'ORG_NAME_AGAIN')appendNode('organizationUrl', 'ORG_URL_AGAIN')appendNode('timezone', 'UTC_OFFSET')}}}}
好,我们去。 比丑陋的XML好得多,对吧? 我在某处读到有更多美丽的API可以在这里使用,但我不想离开另一个切线。 随意提出一些建议。
您可能已经注意到,无需重复项目组,ID和版本。 现在,运行gradle publish
应该发布带有完整的pom的JAR,尽管它有点丑陋。
许可及更多
我想将项目的许可证添加到JAR的META-INF
文件夹中,因此在mavenJava
我告诉Gradle在每个JAR任务中都包含该文件(或者至少是我阅读的方式):
tasks.withType(Jar) {from(project.projectDir) {include 'LICENSE.md'into 'META-INF'}}
看起来不错,gradle publish
现在会创建一个完整的pom和一个带有项目许可证的JAR。
来源和Javadoc JAR
不过,大多数项目都希望发布的不仅仅是已编译的.class
文件,即源代码和Javadoc。 为此,我添加了两个任务,并从mavenJava
引用了它们:
publishing {publications {mavenJava(MavenPublication) {// ...artifact sourceJarartifact javadocJar}}// ...}task sourceJar(type: Jar, dependsOn: classes) {classifier 'sources'from sourceSets.main.allSource}task javadocJar(type: Jar, dependsOn: javadoc) {classifier = 'javadoc'from javadoc.destinationDir}
很好,现在我得到了一个完整的pom,一个用于项目的类和许可证的工件,以及用于源代码和Javadoc的JAR。 是时候采取最后一步了:发布到快照仓库!
为此,我将使用实际的存储库替换mavenLocal
。 除了URL,我还需要指定我的凭据:
repositories {maven {url '/content/repositories/snapshots/'credentials {username 'user'password '123456'}}}
当然,我并不打算将密码提交给源代码管理,所以我一直在寻找替代方法。 我找到了一个-不确定它是否是最好的,但是,嘿,它有用。
您可以使用-P选项在命令行上定义新的项目属性。 所以给这样的命令...
gradle publish -P snapshotRepoPass=123456
…然后我可以访问项目。 凭据中的snapshotRepoPass
:
credentials {username 'user'password project.snapshotRepoPass}
甜。
直到我意识到现在所有其他任务都失败了,因为始终创建credentials
对象,因此需要存在属性snapshotRepoPass
。 对于其他任务,除了发布之外,情况并非如此,因为我认为没有理由将回购密码传递给例如测试运行。 如此,我决定在构建文件中定义该属性(如果由于命令行选项而尚未定义):
ext {// the password needs to be specified via command linesnapshotRepoPass = project.hasProperty('snapshotRepoPass')? project.getProperty('snapshotRepoPass'): ''// it looks like the ternary operator can not actually be// split across lines; I do it here for artistic purposes}
我本可以将相同的hasProperty/ getProperty
检查放入凭据中,但决定在实现此行为的地方创建一个单独的位置。
完成所有这些操作后,我确实可以将项目的当前状态发布到Sonatype Maven快照存储库。 哇!
反射
总而言之,这实际上并不是那么糟糕。 该文档有点稀疏,并在API中构建了XML文件,这使它变得更加冗长,让人感到荒谬,但除此之外,它读起来也很简单。 当时不是,但是现在可以了,所以我应该停止抱怨了。
这是我所做的:
使用apply plugin
:'maven-publish
'激活插件,并向build.gradle
添加一个publishing
节点。 用漂亮的asNode.appendNode
调用填充pom 通过将复制步骤附加到每个与JAR相关的任务中来包括许可证 创建源和Javadoc JAR的任务,并从publications
节点引用它们。 指定存储库URL并添加您的凭据。
如前所述,您可以签出生成的build.gradle
文件的两个版本: 一个示例性的版本, 其中包括我们在此构建的内容和实际的交易 。
我还成功设置了Travis CI,以发布每个成功的版本,并将很快尝试发布实际版本。 我会写关于这两者的...
翻译自: //12/publishing-snapshots-gradles-maven-publish-plugin.html