Azure DevOps 专用代理 - 如何使用 nvm 安装节点
Azure DevOps private agent - how to install node using nvm
我正尝试在 Ubuntu 上为 Azure DevOps 设置私有构建代理。我需要使用 npm 任务进行构建。
我尝试使用nvm安装最新的node,安装成功:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
nvm install 11.10.1
我可以检查 node -v
和 npm -v
。但是当从管道执行 npm 任务时 - 它失败并显示
Unable to locate executable file: 'npm'. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.
在我的 PATH 中有 /usr/local/nvm/versions/node/v11.10.1/bin
和 ls -l
显示:
lrwxrwxrwx 1 500 500 38 Feb 28 06:00 /usr/local/nvm/versions/node/v11.10.1/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js
我还为 npm-cli.js 添加了 777(只是为了尝试!),但仍然没有成功。
我也发现了这个类似的问题 - https://github.com/Microsoft/azure-pipelines-agent/issues/1862
如何在 Ubuntu Azure DevOps 代理上使用 nvm 正确安装节点和 npm?
作为临时解决方案,我安装了节点
curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
sudo apt-get install nodejs
而不是 nvm,它工作正常。
为了让它工作,我最终创建了一个代理到 nvm 的 bash 脚本,然后告诉代理将 PATH 变量更新为当前 NVM。
在 /usr/local/bin/nvm
创建一个包含以下内容的文件:
#!/usr/bin/env bash
# Store the current path so we can check to see if it changes
OLD_PATH=$PATH
# Normal NVM stuff
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
# Execute NVM and pass all the arguments
nvm $@
# Check to see if the path has changed, and if an azure agent is running the
# command by checking the existence of the $AGENT_VERSION variable.
if [[ "$OLD_PATH" != "$PATH" && ! -z ${AGENT_VERSION+x} ]]; then
# Grab the current node executable Something like:
# /Users/digitaldev/.nvm/versions/node/v10.16.3/bin
CURRENT_NODE=$(nvm which current)
# Resolve to directory of the node executable Something like
# /Users/digitaldev/.nvm/versions/node/v10.16.3
BIN_DIR=$(dirname "$CURRENT_NODE")
# Tell Azure Pipeline to update the PATH [1]
echo "##vso[task.prependpath]$BIN_DIR"
fi
使文件可执行:
chmod +x /usr/local/bin/nvm
现在,当 Azure Pipeline 运行时 nvm
它将更新路径以查找节点的 nvm 版本。
只有 nvm
我根据 nvm.sh 的说明创建了一个这样的模板,并相应地设置了 NVM_DIR 和路径。
steps:
- bash: |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install
nvm use
echo "##vso[task.setvariable variable=NVM_DIR;]$NVM_DIR"
echo "##vso[task.setvariable variable=PATH;]$PATH"
displayName: "Install Node.js"
我还添加了 .nvmrc
,如 nvm.sh 中所述,以便指定要使用的节点版本。
然后我在我的管道中使用它如下
steps:
- template: templates/install-node-js.yml
- bash: |
node --version
具有缓存和节点依赖性
这是我安装 node 的模板,也对 package-lock.json
中的包进行缓存。
steps:
- task: Cache@2
inputs:
key: 'nvm | "$(Agent.OS)" | .nvmrc'
path: $(Pipeline.Workspace)/.nvm
displayName: "Cache NVM"
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
path: $(Build.SourcesDirectory)/node_modules
displayName: "Cache node dependencies"
- bash: |
set -e
if [ $(System.Debug) ]
then
set -x
fi
if [ ! -s $NVM_DIR/nvm.sh ]
then
mkdir -p $NVM_DIR
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
fi
. $NVM_DIR/nvm.sh || true
nvm install
nvm use
npm ci
echo "##vso[task.setvariable variable=PATH;]$PATH"
env:
NVM_DIR: $(Pipeline.Workspace)/.nvm
displayName: Install Node and dependencies
Azure DevOps 已经在他们的 Linux 和 macOS 构建代理中包含 nvm
一段时间了。
如果您想利用他们所做的工作来创建您自己的代理,此存储库包含他们使用的所有代码。
https://github.com/actions/virtual-environments/
Ubuntu Linux 代理正在使用 Packer (https://packer.io) 来配置 VM。
https://github.com/actions/virtual-environments/tree/main/images/linux
我们使用 Azure 托管代理和类似的东西来设置 Node 项目(或 React Native/Cordova/Ionic 移动构建),最重要的部分是任何时候你想使用 nvm
或它安装的包(项目或全局范围)你需要 . ${NVM_DIR}/nvm.sh
.
steps:
- script: |
# Setup node using nvm
# NODE_VERSION=12 # or whatever your preferred version is
# We are using .nvmrc instead of specific version
npm config delete prefix # avoid a warning
. ${NVM_DIR}/nvm.sh # This is the most important bit to utilize nvm
nvm install # uses .nvmrc implicitly
nvm use
nvm alias default $(cat .nvmrc)
# nvm alias can understand eg. lts/erbium better than
# nvm_version_path which can't resolve the lts/* codenames
VERSION_PATH="$(nvm_version_path $(cat $(nvm_alias_path)/$(cat $(nvm_alias_path)/default)))"
which nvm
# This will inject the node version we told nvm was default to the $PATH
echo "##vso[task.prependPath]$VERSION_PATH"
# Optionally upgrade npm here or using `nvm install-latest-npm`
#npm install -g npm # upgrades to latest that supports lockfileVersion@2
npm install
我正尝试在 Ubuntu 上为 Azure DevOps 设置私有构建代理。我需要使用 npm 任务进行构建。
我尝试使用nvm安装最新的node,安装成功:
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
nvm install 11.10.1
我可以检查 node -v
和 npm -v
。但是当从管道执行 npm 任务时 - 它失败并显示
Unable to locate executable file: 'npm'. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.
在我的 PATH 中有 /usr/local/nvm/versions/node/v11.10.1/bin
和 ls -l
显示:
lrwxrwxrwx 1 500 500 38 Feb 28 06:00 /usr/local/nvm/versions/node/v11.10.1/bin/npm -> ../lib/node_modules/npm/bin/npm-cli.js
我还为 npm-cli.js 添加了 777(只是为了尝试!),但仍然没有成功。
我也发现了这个类似的问题 - https://github.com/Microsoft/azure-pipelines-agent/issues/1862
如何在 Ubuntu Azure DevOps 代理上使用 nvm 正确安装节点和 npm?
作为临时解决方案,我安装了节点
curl -sL https://deb.nodesource.com/setup_11.x | sudo -E bash -
sudo apt-get install nodejs
而不是 nvm,它工作正常。
为了让它工作,我最终创建了一个代理到 nvm 的 bash 脚本,然后告诉代理将 PATH 变量更新为当前 NVM。
在 /usr/local/bin/nvm
创建一个包含以下内容的文件:
#!/usr/bin/env bash
# Store the current path so we can check to see if it changes
OLD_PATH=$PATH
# Normal NVM stuff
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
# Execute NVM and pass all the arguments
nvm $@
# Check to see if the path has changed, and if an azure agent is running the
# command by checking the existence of the $AGENT_VERSION variable.
if [[ "$OLD_PATH" != "$PATH" && ! -z ${AGENT_VERSION+x} ]]; then
# Grab the current node executable Something like:
# /Users/digitaldev/.nvm/versions/node/v10.16.3/bin
CURRENT_NODE=$(nvm which current)
# Resolve to directory of the node executable Something like
# /Users/digitaldev/.nvm/versions/node/v10.16.3
BIN_DIR=$(dirname "$CURRENT_NODE")
# Tell Azure Pipeline to update the PATH [1]
echo "##vso[task.prependpath]$BIN_DIR"
fi
使文件可执行:
chmod +x /usr/local/bin/nvm
现在,当 Azure Pipeline 运行时 nvm
它将更新路径以查找节点的 nvm 版本。
只有 nvm
我根据 nvm.sh 的说明创建了一个这样的模板,并相应地设置了 NVM_DIR 和路径。
steps:
- bash: |
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install
nvm use
echo "##vso[task.setvariable variable=NVM_DIR;]$NVM_DIR"
echo "##vso[task.setvariable variable=PATH;]$PATH"
displayName: "Install Node.js"
我还添加了 .nvmrc
,如 nvm.sh 中所述,以便指定要使用的节点版本。
然后我在我的管道中使用它如下
steps:
- template: templates/install-node-js.yml
- bash: |
node --version
具有缓存和节点依赖性
这是我安装 node 的模板,也对 package-lock.json
中的包进行缓存。
steps:
- task: Cache@2
inputs:
key: 'nvm | "$(Agent.OS)" | .nvmrc'
path: $(Pipeline.Workspace)/.nvm
displayName: "Cache NVM"
- task: Cache@2
inputs:
key: 'npm | "$(Agent.OS)" | package-lock.json'
path: $(Build.SourcesDirectory)/node_modules
displayName: "Cache node dependencies"
- bash: |
set -e
if [ $(System.Debug) ]
then
set -x
fi
if [ ! -s $NVM_DIR/nvm.sh ]
then
mkdir -p $NVM_DIR
curl -so- https://raw.githubusercontent.com/nvm-sh/nvm/v0.36.0/install.sh | bash
fi
. $NVM_DIR/nvm.sh || true
nvm install
nvm use
npm ci
echo "##vso[task.setvariable variable=PATH;]$PATH"
env:
NVM_DIR: $(Pipeline.Workspace)/.nvm
displayName: Install Node and dependencies
Azure DevOps 已经在他们的 Linux 和 macOS 构建代理中包含 nvm
一段时间了。
如果您想利用他们所做的工作来创建您自己的代理,此存储库包含他们使用的所有代码。
https://github.com/actions/virtual-environments/
Ubuntu Linux 代理正在使用 Packer (https://packer.io) 来配置 VM。
https://github.com/actions/virtual-environments/tree/main/images/linux
我们使用 Azure 托管代理和类似的东西来设置 Node 项目(或 React Native/Cordova/Ionic 移动构建),最重要的部分是任何时候你想使用 nvm
或它安装的包(项目或全局范围)你需要 . ${NVM_DIR}/nvm.sh
.
steps:
- script: |
# Setup node using nvm
# NODE_VERSION=12 # or whatever your preferred version is
# We are using .nvmrc instead of specific version
npm config delete prefix # avoid a warning
. ${NVM_DIR}/nvm.sh # This is the most important bit to utilize nvm
nvm install # uses .nvmrc implicitly
nvm use
nvm alias default $(cat .nvmrc)
# nvm alias can understand eg. lts/erbium better than
# nvm_version_path which can't resolve the lts/* codenames
VERSION_PATH="$(nvm_version_path $(cat $(nvm_alias_path)/$(cat $(nvm_alias_path)/default)))"
which nvm
# This will inject the node version we told nvm was default to the $PATH
echo "##vso[task.prependPath]$VERSION_PATH"
# Optionally upgrade npm here or using `nvm install-latest-npm`
#npm install -g npm # upgrades to latest that supports lockfileVersion@2
npm install