
Butter Knife 版本发布流程全解析基于 Gradle 与 Sonatype Nexus 的 Android 开源库发布指南【免费下载链接】butterknifeBind Android views and callbacks to fields and methods.项目地址: https://gitcode.com/gh_mirrors/bu/butterknife导读本文以 Butter Knife 仓库根目录下的 RELEASING.md 为骨架完整还原一个多模块 Android 开源库从开发中快照版本到正式发布版本再到下一个开发版本的全生命周期操作流程。文中每一步均结合仓库内的真实配置文件如 gradle.properties、gradle/gradle-mvn-push.gradle与示例模块sample/app/build.gradle、sample/library/build.gradle给出可验证的底层原理读者学完后可以完整掌握 Butter Knife 自身的发布操作也能将同样的发布模型迁移到自己的 Android 开源项目中。一、发布流程总览从 SNAPSHOT 到正式版本Butter Knife 的发布策略遵循经典的主版本号 快照双状态模式日常开发阶段gradle.properties中的版本号是X.Y.Z-SNAPSHOT只有在真正发版时才临时把版本号切换为非 SNAPSHOT 的正式版本号构建上传后打 tag再立刻改回下一个 SNAPSHOT 版本让主干永远保持可发布的连续状态。当前仓库的 gradle.properties 中记录了发布所需的全部元数据GROUPcom.jakewharton VERSION_NAME10.2.4-SNAPSHOT POM_DESCRIPTIONField and method binding for Android views. POM_URLhttps://github.com/JakeWharton/butterknife/ POM_SCM_URLhttps://github.com/JakeWharton/butterknife/ POM_SCM_CONNECTIONscm:git:git://github.com/JakeWharton/butterknife.git POM_SCM_DEV_CONNECTIONscm:git:ssh://gitgithub.com/JakeWharton/butterknife.git POM_LICENCE_NAMEThe Apache Software License, Version 2.0 POM_LICENCE_URLhttp://www.apache.org/licenses/LICENSE-2.0.txt POM_LICENCE_DISTrepo POM_DEVELOPER_IDjakewharton POM_DEVELOPER_NAMEJake Wharton其中GROUP决定所有构件artifact的 Maven 坐标组名VERSION_NAME是本次要发布或正在开发的版本号其余POM_*属性会被注入到生成的 POM 文件中供 Sonatype Nexus 审核与使用者解析依赖时读取。结合 CHANGELOG.md 可见最近一次正式发布为 10.2.32020-08-12当前仓库正处于向 10.2.4 版本开发的 SNAPSHOT 阶段与发布文档的流程完全吻合。发布涉及哪些构件Butter Knife 是一个多模块工程settings.gradle 中注册了 8 个模块butterknife、butterknife-annotations、butterknife-compiler、butterknife-gradle-plugin、butterknife-integration-test、butterknife-lint、butterknife-reflect、butterknife-runtime。其中butterknife-integration-test是纯测试模块不会发布其余模块在发布时会被一起构建并上传到 Maven 仓库。根 build.gradle 中通过subprojects为所有子项目统一设置了group GROUP与version VERSION_NAME因此一次uploadArchives即完成全部分发模块的发布。二、发布前的准备工作步骤 1-31. 修改版本号为非 SNAPSHOT 版本将 gradle.properties 中的VERSION_NAME从10.2.4-SNAPSHOT改为正式版本号例如VERSION_NAME10.2.4这一步的意义在于根 build.gradle 会把VERSION_NAME同步到所有子项目的version属性同时 gradle/gradle-mvn-push.gradle 中的isReleaseBuild()判断决定了上传路径与签名行为def isReleaseBuild() { return VERSION_NAME.contains(SNAPSHOT) false }版本号不含SNAPSHOT属于发布构建uploadArchives会上传到 Release 仓库并触发 POM 签名signing版本号包含SNAPSHOT属于开发构建上传到 Snapshot 仓库不进行签名。2. 更新 CHANGELOG.md发布前需要在 CHANGELOG.md 顶部为该版本新增一段变更记录格式参照既有条目例如Version 10.2.3 *(2020-08-12)* ----------------------------- * Fix: Support receiving MotionEvent in an OnTouch callback when using butterknife-reflect.变更记录应如实覆盖该版本的所有 New / Fix / 破坏性变更这是发布后使用者在升级时最主要的参考依据。3. 更新 README.md 中的版本号README.md 的依赖示例中硬编码了版本号dependencies { implementation com.jakewharton:butterknife:10.2.3 annotationProcessor com.jakewharton:butterknife-compiler:10.2.3 }发布新版本时需要把这些示例中的版本号同步更新为本次发布的新版本确保文档与 Maven 仓库实际可用版本一致。注意 README 中同时涉及butterknife-gradle-plugin库工程使用与butterknife-reflectIDE 构建使用的版本引用也应一并核对。三、提交发布准备并构建上传步骤 4-54. 提交发布准备git commit -am Prepare for release X.Y.Z.将上述对gradle.properties、CHANGELOG.md、README.md的修改作为一次独立的发布准备提交便于日后回滚与审计。5. 执行 clean uploadArchives./gradlew clean uploadArchivesclean确保所有模块从零构建排除脏产物uploadArchives是 gradle/gradle-mvn-push.gradle 中为每个模块统一配置的发布任务。该脚本的核心逻辑如下afterEvaluate { project - uploadArchives { repositories { mavenDeployer { beforeDeployment { MavenDeployment deployment - signing.signPom(deployment) } repository(url: getReleaseRepositoryUrl()) { authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) } snapshotRepository(url: getSnapshotRepositoryUrl()) { authentication(userName: getRepositoryUsername(), password: getRepositoryPassword()) } configurePom(pom) } } } ... }从中可以提取出几个关键机制双仓库路由getReleaseRepositoryUrl()默认指向 Sonatype Nexus 的 staging deploy 地址getSnapshotRepositoryUrl()默认指向 snapshots 仓库两者都支持通过RELEASE_REPOSITORY_URL/SNAPSHOT_REPOSITORY_URL属性覆盖例如发布到内部私有仓库认证信息通过SONATYPE_NEXUS_USERNAME与SONATYPE_NEXUS_PASSWORD两个 Gradle 属性注入通常放在~/.gradle/gradle.properties中避免把账号密码提交进仓库POM 生成configurePom(pom)会把 gradle.properties 中的GROUP、POM_*系列属性写入 POM 的 groupId、description、SCM、license、developer 等节点签名规则signing { required { isReleaseBuild() gradle.taskGraph.hasTask(uploadArchives) } sign configurations.archives }只有发布构建非 SNAPSHOT且确实在执行uploadArchives时才要求 GPG 签名签名对象是configurations.archives中的全部构件。该脚本还为每个模块生成了源码包与 Javadoc 包Android 模块使用androidSourcesJar/androidJavadocsJar普通 Java 模块使用sourcesJar/javadocJar并统一挂载到archives配置中因此执行uploadArchives时 POM、源码 jar、Javadoc jar、主 jar 会一并上传这也是通过 Sonatype 审核的必要条件。此外脚本还提供了installLocally任务可将构件安装到本地build/localMaven目录用于联调验证。四、在 Sonatype Nexus 提升构件步骤 6# 上传成功后登录 Sonatype Nexus 管理界面oss.sonatype.org # 在 Staging Repositories 中找到本次上传的 staging repo # 点击 Close 关闭仓库触发校验确认无误后点击 Release 正式发布构建上传成功后构件并不会立即出现在 Maven Central 中而是停留在 Sonatype Nexus 的 staging 区域需要人工登录 Nexus 完成Close关闭→ Release发布两步操作Close对 staging 仓库执行校验如 POM 完整性、签名有效性、源码/Javadoc 是否齐全校验通过后仓库变为 closed 状态构件可从临时 staging 地址被拉取验证Release确认无误后执行 release构件才会被同步到 Maven Central 并最终对全球开发者可见。这一步与步骤 5 一样是整个发布流程中唯一不能完全自动化的环节也是发布文档要求人工关注的原因。五、打版本标签步骤 7git tag -a X.Y.Z -m Version X.Y.Z发布成功后在当前提交上打带注释的标签annotated tag记录版本号与发布说明。标签名与版本号保持一致如10.2.4它是后续追溯某个版本源码快照的唯一锚点。注意原文档此步的 tag 命令中写的是X.Y.X结合上下文与第 4、7 步的注释where X.Y.Z is the new version可以判断这是文档笔误实际打 tag 时应使用与版本号一致的X.Y.Z。六、准备下一个开发版本步骤 8-98. 更新到下一个 SNAPSHOT 版本再次修改 gradle.properties把版本号推进为下一个开发版本VERSION_NAME10.2.5-SNAPSHOT9. 提交开发版本切换git commit -am Prepare next development version.通过发布完立即切回 SNAPSHOT的方式主干的版本号始终处于可继续开发的状态同时避免两个版本号混用导致依赖解析歧义。七、推送代码与标签步骤 10git push git push --tagsgit push推送提交到远程主干git push --tags单独推送步骤 7 创建的标签。两个推送必须都成功远程仓库才与本地发布状态完全一致。八、更新两个示例模块步骤 11Butter Knife 仓库内置了两个示例模块sample/app 与 sample/library它们不直接依赖 SNAPSHOT而是通过根 build.gradle 中的deps.release引用已发布的正式版本release: [ runtime: com.jakewharton:butterknife:${versions.release}, compiler: com.jakewharton:butterknife-compiler:${versions.release} ],其中versions.release 8.8.1。因此每次发布新版本后需要将根 build.gradle 中的versions.release更新为刚发布的新版本号由于 sample/library/build.gradle 通过classpath com.jakewharton:butterknife-gradle-plugin:${versions.release}引用插件示例库工程同时验证了butterknife-gradle-plugin的可用性更新后重新构建 sample确认示例工程能在新版本下正常编译运行起到发布冒烟测试的作用。九、失败处理与回滚文档补充条款RELEASING.md 末尾明确给出了失败处理约定如果步骤 5 或 6 失败drop 掉 Sonatype 上的 staging 仓库修复问题提交然后从步骤 5 重新开始。也就是说若./gradlew clean uploadArchives失败构建错误、认证失败、签名失败直接修复代码或配置后重新执行即可尚未进入 Nexus 的 stage无需清理若在 Nexus 的 Close / Release 阶段失败如 POM 校验不通过、签名缺失需要先在 Nexus 界面Drop掉对应的 staging 仓库把发布状态重置干净修复后再从步骤 5重新构建上传开始而不是在残留的半成品 staging 仓库上继续操作。这条约定保证了要么不发布要么发布出完整可用的版本避免 Maven Central 上出现残缺构件。十、发布流程的源码级依据小结整个发布流程可以从仓库中找到一一对应的实现证据发布环节仓库依据版本号与坐标gradle.properties 中的GROUP、VERSION_NAME版本分发到各模块build.gradle 中subprojects { group GROUP; version VERSION_NAME }上传任务与仓库地址gradle/gradle-mvn-push.gradle 中的uploadArchives、getReleaseRepositoryUrl()、getSnapshotRepositoryUrl()发布/快照区分与签名同一脚本中的isReleaseBuild()与signing { required { ... } }POM 元数据同一脚本中的configurePom(pom)配合POM_*属性源码/Javadoc 包同一脚本中的sourcesJar/javadocJar/androidSourcesJar/androidJavadocsJar版本历史CHANGELOG.md 中每次发布对应的变更条目示例模块版本同步build.gradle 的versions.release与两个 sample 模块的依赖声明需要注意的是本仓库的 Gradle Wrapper 版本为 4.10.3见 gradle/wrapper/gradle-wrapper.properties且根 gradle.properties 中设置了android.enableAapt2false以规避旧版 AGP 的已知问题。这意味着上述发布流程是围绕该历史版本的工具链设计的若要在现代环境新版 AGP / Gradle下复刻应关注maven插件已被maven-publish取代、android.enableAapt2弃用等兼容性差异并基于实际环境调整命令与配置。结语Butter Knife 的发布流程虽然只有短短十余步却完整覆盖了版本切换—变更记录—构建签名—Nexus 提升—打标—切回快照—示例验证—失败回滚的闭环其背后的 gradle-mvn-push.gradle 更是浓缩了一套可复用的多模块 Android 开源库发布模板。无论是作为 Butter Knife 的维护者还是想为自己的库搭建类似发布管线的开发者都可以直接以本仓库为参照逐行对照 RELEASING.md 与构建脚本快速落地一套同样规范的发布流程。【免费下载链接】butterknifeBind Android views and callbacks to fields and methods.项目地址: https://gitcode.com/gh_mirrors/bu/butterknife创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考