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

Jenkins流水线中替换JSON文件version字段值的问题

问题描述

我需要在Jenkins流水线中,将以下metadata.json文件里的"version"字段值替换为流水线中已定义的变量。

原metadata.json内容:

{
  "name": "new-relic",
  "version": "1.0.0",
  "author": "Tools",
  "summary": "A brief module description",
  "license": "Apache-2.0",
  "source": "https://github.com/DI-Test/puppet-newrelic",
  "dependencies": [

  ],
  "operatingsystem_support": [
    "RedHat based Linux"
  ],
  "requirements": [
    {
      "name": "puppet",
      "version_requirement": ">= 7.24 < 9.0.0"
    }
  ],
  "pdk-version": "3.0.0",
  "template-url": "pdk-default#3.0.0",
  "template-ref": "tags/3.0.0-0-g056e50d"
}

最初尝试用writeJSON工具时,执行以下代码会覆盖整个JSON文件,仅保留"version"字段:

writeJSON(  file: 'metadata.json',
            json: [
                version: "${puppet_module_version}-${BRANCH_NAME}",])

之后我编写了一段流水线代码,尝试先读取JSON内容、修改version字段后再写入文件,代码如下:

stage('Build Puppet Module Package') {    
    steps {
        script {
            def metadata = readJSON file: 'metadata.json'
            env.puppet_module_name = metadata["name"]
            env.puppet_module_version = metadata["version"]
            container('puppet') {
                if (env.BRANCH_NAME == 'master') {
                    sh label: 'Build Puppet Module', script: 'pdk build --force'
                } else {
                     
                    Map attributes = readJSON(file: 'metadata.json')
                    attributes['version'] = "${puppet_module_version}-${BRANCH_NAME}"
                    writeJSON(file: 'metadata.json', json: attributes)
                    
                    sh label: 'Build Puppet Module', script: 'pdk build --force'
                    sh label:   'Display metadata.json',
                        script: """
                            cat metadata.json
                        """
                }
                // // Build puppet module package using pdk
                // sh (label: 'PDK Build Module', script: 'pdk build --force')
            }
        }
    }
}

请问该代码是否能正确实现仅替换version字段的需求,或是否存在更优的实现方式?


回答

现有代码的有效性

你的这段代码可以正确实现仅替换version字段的需求。逻辑通顺:

  1. 读取完整JSON内容到Map对象
  2. 仅修改Map中的version字段值
  3. 将整个Map写回JSON文件,其他字段会完整保留,仅更新version

不过代码存在小冗余:script块开头已读取过一次metadata.json并将version存入环境变量,但else分支又重新读取了一次文件,可复用已读取的对象避免重复IO操作。

优化后的代码示例

stage('Build Puppet Module Package') {    
    steps {
        script {
            // 仅读取一次JSON文件
            def metadata = readJSON file: 'metadata.json'
            env.puppet_module_name = metadata["name"]
            def originalVersion = metadata["version"]
            
            container('puppet') {
                if (env.BRANCH_NAME == 'master') {
                    sh label: 'Build Puppet Module', script: 'pdk build --force'
                } else {
                    // 复用已读取的metadata对象修改version
                    metadata['version'] = "${originalVersion}-${BRANCH_NAME}"
                    // 添加pretty参数保证JSON格式化输出
                    writeJSON(file: 'metadata.json', json: metadata, pretty: 2)
                    
                    sh label: 'Build Puppet Module', script: 'pdk build --force'
                    sh label: 'Display metadata.json', script: 'cat metadata.json'
                }
            }
        }
    }
}

额外优化点

  1. 给writeJSON添加pretty: 2参数,让写入的JSON保持原文件的格式化风格,避免变成紧凑的单行格式
  2. 用局部变量originalVersion代替环境变量,仅在当前script块内使用的变量,局部变量更高效且不会污染环境变量空间
  3. 移除重复的文件读取操作,提升流水线执行效率

另外,若容器环境已安装jq工具,也可直接用shell命令修改JSON,适合简单字段修改场景:

sh label: 'Update version in metadata.json', 
   script: "jq --arg new_version '${originalVersion}-${BRANCH_NAME}' '.version = \$new_version' metadata.json > temp.json && mv temp.json metadata.json"

这种方式更简洁,但需确保容器内有jq工具可用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:57:14