node.js - Docker Jenkins Pipeline 安装全局 NPM 包

标签 node.js docker jenkins npm

我是 Docker/Jenkins 新手。

Jenkins 通过以下方式触发容器

docker run -t -d -u 995:315 -w /workspace/projectname -v /workspace/projectname:/workspace/projectname:rw,z -v /workspace/projectname@tmp:/workspace/projectname@tmp:rw,z  circleci/node:latest

我的管道

pipeline {
    agent {
        docker {
            image 'circleci/node:latest'
        }
    }
    environment { 
        HOME="."
        NPM_CONFIG_PREFIX="${pwd()}/.npm-global"
        PATH="$PATH:${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin"
    }
    stages {
        stage('NPM Config') {
            steps {
                sh 'npm install -g @angular/cli'
                echo "PATH is: $PATH"
                sh '.npm-global/bin/ng version'
                sh '/workspace/projectname/.npm-global/bin/ng version'
                sh 'ng version'
            }
        }
    }
}

echo "PATH is: $PATH" 打印出

PATH is: /sbin:/usr/sbin:/bin:/usr/bin;/usr/bin/;/etc/;/etc/ssh/ssh/:/workspace/projectname/.npm-global/bin:/workspace/projectname@tmp/.npm-global/bin

这两个

sh '.npm-global/bin/ng version'
sh '/workspace/projectname/.npm-global/bin/ng version'

做我期望sh 'ng version'做的事情。但是,sh 'ng version'给了我以下错误

ng version
/workspace/projectname@tmp/durable-9f9bc04a/script.sh: 2: /workspace/projectname@tmp/durable-9f9bc04a/script.sh: ng: not found

我试图避免建立自己的形象,下一步该怎么做?

此外,我只会使用 npx,但我需要更改很多存储库及其脚本才能使其正常工作,但我宁愿不这样做。

更新:看起来管道忽略了 PATH 环境变量的更改

environment { 
   HOME="."
   NPM_CONFIG_PREFIX="${pwd()}/.npm-global"
   PATH="/foo/bar"
}

是否有特殊的可能修改PATH?或者可能是权限问题?

最佳答案

在尝试用详细的文档整理内容之后,这是一个格式化的、希望有用的答案。

首先,environment block 声明 Jenkins 级别的键值对:

  • Jenkins 级别不是工作区级别,变量插值级别是根据引号类型选择的,所以如果我理解正确的话:

    echo '$PATH' would show the workspace PATH ("default", in your case)

    echo "$PATH" would be interpreted by Jenkins, hence showing the "modified" PATH

  • 仅键值对有效:即使它看起来像 shell 环境变量设置,您也可以编写 PATH = some= 周围的空格在 shell 中不起作用

人们似乎主要认为是在工作区不知道参数的情况下公开参数,就像用户以交互方式提供信息一样(他们谈论了很多有关凭据的信息)。

第二,仅列出steps的有限列表。进行有效调用,并且没有导出步骤。

但是有一个 withEnv 步骤可以完成这项工作。我在声明性 pipeline { ... } 中没有找到任何示例,仅在脚本化 node { ... } block 中,声明性版本的定义声明所有步骤都是有效的。我发现了一个包装 stage block 的步骤示例(尽管在 node 中),所以我们希望它对于 stages 是相同的(否则你必须在每个 stage 上指定 withEnv - 或者作为 stage 内的另一个包装器 - 这需要你的环境 mods:当然可行但很无聊)。

这样的东西应该有效,或者至少值得一试:

  pipeline {
    agent { ... }
    environment { 
      HOME="."
      NPM_CONFIG_PREFIX="${pwd()}/.npm-global"
      PATH="$PATH:${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin"
    }
    withEnv(["PATH=$PATH", /*or*/ "PATH=${PATH}", /*or*/ "PATH+NPM=${pwd()}/.npm-global/bin:${pwd tmp: true}/.npm-global/bin"]) {
      stages {
        stage('NPM Config') {
          steps { ... }
        }
        stage('something else that needs ng') { ... }
      }
    }
  }

好吧,你明白了。

最后,如果这个 PATH 东西不起作用并且比重写管道更让您烦恼,那么使用带有 node block 的脚本替代方案可能会更有趣并且更灵活。

我希望得到 OP 或周围任何 Jenkins 专家的一些反馈!

关于node.js - Docker Jenkins Pipeline 安装全局 NPM 包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54490999/

相关文章:

带有构建/运行/等的 Docker 命令。 "too many open files"

javascript - 如何在 Nuxt 中使用 Auth0 在后台更新授权 token

node.js - 将元数据添加到 mongoose 字段

docker - 根据联合文件系统,图像实际上包含另一个图像吗?

mysql - Spring 启动 mysql docker windows 7

hibernate - 为什么 gradle 不会从 jenkins 工作中运行

JavaScript Node.js 网页抓取 : How do I find specific elements on webpage table to scrape and push into an array of objects?

Node.JS 不查询本地 DNS

Jenkins 与 Amazon S3 持续集成 - 一切都上传到根目录?

jenkins - 文件操作插件 fileCopyOperation - Jenkins 管道