「JENKINS-PIPELINE」- 构建工具管理:NodeJS Maven NPM

该笔记将记录:在 Jenkins 中,如何维护管理和使用各种工具,以及常见问题的解决办法;

在 Jenkins 中,Job 将在各个 Agent 中运行,同时这些 Job 又依赖于各种构建工具及命令,这就要求我们在 Agent 中安装各种工具。但是,如果 Jenkins Agent 较多,则在各个 Agent 中进程安装是不现实的,而且不同 Job 又依赖于不同版本的工具(增加节点维护难度)。

在 Jenkins 中,其提供针对该问题的解决方案:

  1. 其提供 Manage Jenkins / Tools 功能,使得我们能够配置各种工具;
  2. 而后,在 Job 中,选择需要使用的工具及版本,当构建时 Jenkins 将自动在节点上进行工具的安装及配置;

NodeJS | 配置多版本 NodeJS 构建环境

前端开发人员使用多种版本 NodeJS 环境进行开发,并使用 NVM 自如切换版本。在使用 Jenkins 构建时,也应该使用对应版本进行构建。该部分将介绍在 Jenkins Pipeline 中,如何使用不同 NodeJS 版本进行构建任务;

通过 Jenkins NodeJS 插件

插件:https://plugins.jenkins.io/nodejs/

第一步、安装插件
通过使用 NodeJS 插件,网络教程详尽,不再赘述;

第二步、配置版本

或,通过 NodeJS 站点:

Manage Jenkins => Global Tool Configuration => NodeJS => NodeJS installations… => Add NodeJS

记住Name字段,它用于标识 NodeJS 环境,需要在流水脚本中使用。其他字段按照提示填写信息即可,不再赘述;

或,通过 NodeJS 在线镜像站点:

Install from nodejs.org mirror

Mirror URL: https://mirrors.tuna.tsinghua.edu.cn/nodejs-release/v20.17.0/

Version: x.x.x

在 Pipeline 中,如果使用 tool 步骤,则其返回目录为 NodeJS 的根目录,需要追加 bin/ 目录,才能使用 tools 命令。如果使用 tools 步骤,则其将自动添加到 PATH 环境变量中。

第三步、(可选)定义 npmrc 文件
Manage Jenkins => Managed files => Add a new Config => Npm config file
记住ID字段(可自定义),它用于标识配置文件,需要在流水脚本中使用。其他字段按照提示填写即可,不再赘述;

第四步、在流水中使用

nodejs(nodeJSInstallationName: '<Name>', configId: '<ID>') {
    sh 'npm config ls'
}

通过 nvm-wrapper 插件

也可以使用 nvm-wrapper 插件,使用方法可以参考插件主页;
我们并没有成功,后来我们使用 NodeJS 插件。可能是因为我们全局设置 PATH 环境变量,导致无法加载 NVM 设置的 PATH 变量;
相比之下,我们还是选用 NodeJS 插件:(1)可以加载任意 npmrc 文件;(2)与 Jenkins 结合紧密,封装少,项目相对活跃;(3)功能丰富,可全局安装模块;

Maven

Pipeline Maven Integration Plugin

Pipeline Maven Integration Plugin
maven – Jenkins Declarative Pipeline with custom settings.xml

该插件用于 Maven 环境管理;

使用案例:

...
    withMaven(maven: 'M3', mavenSettingsConfig: 'mvn-setting-xml') {
        sh "mvn clean install "
    }
...

通过 Custom Tools 插件

除了常见工具(NodeJS、Maven、NPM、Grade、……)之外,我们还需要安装使用其他工具(例如 kubectl、helm、terraform、……)。针对该类工具,其并无相关的 Jenkins 插件。

针对该问题,安装 Jenkins plugin/Custom Tools 插件,来支持用户自定义工具,其用来安装其他“非常规”工具。

配置位置:Manage Jenkins / Global Tool Configuration / Custom tool

常用配置参数

Subdirectory of extracted archive

当其压缩文件包含子目录时,并且命令包含在该子目录中时,需要指定该参数,其值为命令所在路径。否则 Jenkins Pipeline / tool 仅能返回工具所解压的目录。

Exported paths

根据文档(Custom Tools),该参数用于指定添加到 PATH 变量的额外路径。例如,rust-1.74.0-x86_64-unknown-linux-gnu.tar.gz 同时包含 rustc/ 和 cargo/ 两个程序,但其位于不同的目录中。则,在 Exported paths 中,填写 rust-1.74.0-x86_64-unknown-linux-gnu/rustc/bin,rust-1.74.0-x86_64-unknown-linux-gnu/cargo/bin 两个相对路径,既可添加到 PATH 中,然后便可以使用 cargo 和 rustc 命令。

注意,在 Freestyle Job 中,经过验证,通过正确配置,则能够使得命令路径自动加载到 PATH 环境变量中,

注意,在 Pipeline 中,工具路径并没有添加到 PATH 路径(或许是我们配置的不对,所以我们才使用 environment 来手动添加);

另外,当执行构建时,Jenkins 将会自行检查配置路径是否存在,我们根据错误信息进行调整即可。

常用工具配置

Helm

if [ ! -e linux-amd64/helm ]
then
    rm -rf ./helm-v3.13.3-linux-amd64.tar.gz ./linux-amd64/

    wget https://mirrors.huaweicloud.com/helm/v3.13.3/helm-v3.13.3-linux-amd64.tar.gz
    tar -xf ./helm-v3.13.3-linux-amd64.tar.gz
    chmod u+x ./linux-amd64/helm
fi

if helm cm-push 1>/dev/null 2>&1
then
    ./linux-amd64/helm plugin install https://github.com/chartmuseum/helm-push
fi

NodeJS

加载特定工具 | 在 Declarative Pipeline 中

Declarative pipeline support for tools: CMake, custom tools
[JENKINS-50718] append tool HOME to PATH in declarative Pipeline

在 Jenkins Pipeline 中,我们发现 Custom tool 并未自动添加到 PATH 环境变量中(获取是我们配置不对)。

我们尝试使用 tools 命令来加载工具,虽然能够安装,但是命令并不在 PATH 路径中:

pipeline {
    agent any
	tools {
		com.cloudbees.jenkins.plugins.customtools.CustomTool "helm 3.9.x"
	}
    stages {
        stage('deploy') {
            steps {
                sh 'helm version'
            }
        }
    }
}

经过查阅,我们尝试使用如下方式来手动处理:

pipeline {
    agent any
    environment {
        HELM_PATH = tool name: 'helm 3.9.x', type: 'com.cloudbees.jenkins.plugins.customtools.CustomTool'
        PATH = "${HELM_PATH}:${PATH}"
        // PATH = "${jx_path};${PATH}" // on windows
    }
    stages {
        stage('deploy') {
            steps {
                sh 'helm version'
            }
        }
    }
}

加载特定工具 | 在 Scripted Pipeline 中

Pipeline: Basic Steps/withEnv

node {
    def KUBECTL_PATH = tool "kubernetes-client-linux-amd64-v1.22.15"
    withEnv(["PATH+KUBECTL=${KUBECTL_PATH}"]) {
        sh "kubectl version"
    }
}