【问题标题】:Jenkins and gradle - build projects with latest versions of dependencies for CI, specific versions for productionJenkins 和 gradle - 使用最新版本的 CI 依赖项构建项目,用于生产的特定版本
【发布时间】:2019-06-29 06:21:47
【问题描述】:

我正在使用 Jenkins、Gradle 和我们的 Ivy 存储库。

我们的构建脚本指定要用于构建的依赖项的确切版本。这是生产的良好做法。

对于 CI,如果项目构建使用我们自己的库的最新版本会很有趣,这样我们不仅可以查看库更改是否“破坏了库的构建”,还可以查看它们是否破坏了使用它们的项目.这似乎是“整合”的重点!

我知道 gradle 将采用 "1.+" 而不是 "1.2.3" 所以我可以破解 CI 服务器上项目的 build.gradle 来实现这一点。但也许有一种更简洁的方法来做到这一点(构建脚本识别它处于 CI 模式并使用最新而不是特定版本,也许通过在 build.gradle 上运行 sed 脚本来更改它)。

我在 Jenkins 或 gradle 中遗漏了什么吗?是否有任何 gradle 插件可以实现这一目标,或者您用来实现这一目标的替代方法?

【问题讨论】:

    标签: jenkins gradle ivy


    【解决方案1】:

    类似的东西可能适用于 Jenkins:

    if(System.getenv("BUILD_EXPERIMENTAL") == null) {
    
        // known to be stable versions       
        apply from: "dependencies.gradle"
    
    } else {
    
        // bleeding edge versions 
        apply from: "experimental.gradle"
    
    }
    

    这只是需要将同一个项目设置两次,一次使用环境变量BUILD_EXPERIMENTAL,一次不使用环境变量BUILD_EXPERIMENTAL,用于控制应用哪个dependencies 块。

    如果您希望它被普遍应用,当使用 Jenkins 构建项目时,只需将 BUILD_EXPERIMENTAL 替换为 BUILD_NUMBER(默认情况下在该环境中设置)。

    【讨论】:

    • 这个想法将允许构建脚本在生产和 CI 中通用,这就是我所追求的。如果我们按照@cantSleepNow 在experimental.gradle 文件中的建议使用latest,那么该文件不需要任何更改即可进行微不足道的更新,并且会在Jenkins 构建中自动获取我们库的新版本,该版本可以启动为构建该库的结果。
    • @KevinSadler 一个也可以有一个dependencies 块,同时从两个不同的version.properties 文件加载版本号变量。我的意图只是在两个环境之间进行某种严格的分离,因此建议使用两个文件;这也可以与diff 进行比较。 latest 的缺点可能是缺乏控制,而对于静态版本号,IDE 会将过时的版本标记为黄色背景,以确保它可以随时重现 - 并且可以看到要更新的内容。适用于.gradle 而不是.properties
    • 甚至可以进一步扩展它,使用两个不同的applicationidSuffix,只是为了确保生成的包不会那么容易混淆,并且还可以更轻松地在同一设备上进行手动 A/B 测试- 或在本地运行export BUILD_EXPERIMENTAL=1,以构建实验版本。
    • 我接受了这个答案,因为逻辑和BUILD_NUMBER 提示构成了我自己的解决方案的基础。我自己的答案通过经过测试的示例代码解决了这个问题。谢谢!
    【解决方案2】:

    如果你想拥有最新的,你可以简单地使用latest,或者如果它更简单,比如[1.0,),它将匹配所有大于或等于 1.0 的版本(假设 1.0 是你的“最小版本”)看here 用于其他匹配模式,您也可以与statuses 结合使用。

    另一种方法是仅在 jenkins 从属设备上拥有一个本地文件系统 ivy 存储库,其中包含所有最新版本的库,关键是开发人员工作站/笔记本电脑/VM 无法访问此存储库。然后您只需以某种方式在 gradle 设置中使用它(例如,仅在 jenkins 从站上定义环境变量)。这意味着您无需更改build.gradle

    【讨论】:

    • 由于我不一定希望生产构建使用 latest 或其他非特定选项,因此第一个建议将强制 CI 和生产需要稍微不同的构建脚本。但是,如果这与@Martin Zeitler 的回答中的逻辑相结合 - 并在experimental.gradle 文件中使用latest,我们可能会有一些东西。
    【解决方案3】:

    我建议利用 Gradle dependency locking 来实现这一点。

    • 在构建中,您将使用 dynamic versions 作为您的依赖项,锁定到一个众所周知的状态。
    • 然后,开发人员和生产版本将解决这些锁定的版本。
    • 在 CI 上,您可以有一个(一组)专用作业运行,updates the lock state 一次用于一个或多个模块。根据该反馈,您甚至可以提交此依赖项升级或至少为其打开拉取请求。

    【讨论】:

      【解决方案4】:

      这是我自己的答案,灵感来自@Martin Zeitler 的回答。

      我们有一个通用的构建脚本,可以应用于所有项目build.gradle 设置常用选项、设置和任务。我们想添加这个逻辑,但是让它成为可选的并且不破坏现有的构建脚本。

      该逻辑将由属性project.ext.buildJenkinsWithLatesttruefalse)激活和控制。

      当逻辑处于活动状态时,将使用来自项目文件 dependencies-production.gradledependencies-jenkins.gradle 的依赖项。仅当属性为 true 并且通过存在 BUILD_NUMBER 环境变量检测到 CI 环境时,才会使用 Jenkins 依赖项。

      通用构建脚本包含以下内容:

      如果(project.ext.has('buildJenkinsWithLatest')){ println "使用条件依赖管理..." //如果这是 Jenkins 构建,BUILD_NUMBER 不为空 if(project.ext.buildJenkinsWithLatest == true && System.getenv("BUILD_NUMBER") != null) { println "--- 使用替代依赖..." 申请自:“dependencies-jenkins.gradle” } 别的 { println "--- 使用生产依赖..." 申请自:“dependencies-production.gradle” } } 别的 { println "条件依赖管理未激活" }

      现在任何项目的build.gradle 已经应用此脚本将在运行时打印:

      Conditional dependency management is not active

      要使用该功能,我们需要为我们的项目执行以下操作:

      1. 为我们要动态选择版本的库创建一个包含dependencies {} 子句的dependencies-jenkins.gradle
      2. 为这些库创建一个 dependencies-production.gradle,其中包含 dependencies {} 子句,但指定了特定版本。
      3. 从项目build.gradle 中保留的任何dependencies {} 中删除库。
      4. 将属性project.ext.buildJenkinsWithLatest 设置为truefalse
      5. 应用通用构建脚本(设置属性后!)。

      例如在dependencies-jenkins.gradle 使用最新的 2.x.x 版本:

      依赖{ 编译'示例:我的库:2+' }

      关于如何以动态方式指定版本,请参阅@CantSleepNow 的回答。

      并在dependencies-production.gradle 中使用特定版本:

      依赖{ 编译'示例:我的库:2.3.4' }

      然后在build.gradle 中设置属性并应用通用构建脚本:

      ... project.ext.buildJenkinsWithLatest = true; 申请自:'../bxgradle/bx-std.gradle' ...

      现在,当在 Jenkins 上运行构建时,将使用替代依赖项。如果希望在 Jenkins 上使用生产依赖项构建它,请将 project.ext.buildJenkinsWithLatest 设置为 false

      【讨论】:

        猜你喜欢
        • 2020-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        • 1970-01-01
        • 2012-05-09
        • 2010-09-05
        相关资源
        最近更新 更多