问题

有个前端项目在 gitlab 使用 SSH Executor 执行部署,现在项目升级了 nodejs 版本,由原来的 14 升级到了 20,nodejs 原来用 apt 安装的,现在参考官网使用 nvm 安装。

安装完 20 版本的 node 之后,gitlab 的 ci/cd 一直执行不成功,报错如下

$ npm run build:stage
> ruoyi@3.3.0 build:stage /root/builds/yQzvez-x/0/xxxx/gs-mes-ui
> vite build --mode staging
(node:19320) UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token '??='
    at Loader.moduleStrategy (internal/modules/esm/translators.js:149:18)
......

排查

先是修改流水线打印了 node 版本,还是之前的 14 版本

$ node -v
v14.21.3
$ npm -v
6.14.18

但是使用 ssh 连接,node 版本是正确的

root@dev:~# node -v
v20.13.1
root@dev:~# npm -v
10.5.2

后来想起来看一下环境变量 path,流水线中的 path 和自己 ssh 连接的 path 不一样,mvn 安装的 nodejs bin 目录不在流水线的 path 中

// 流水线中的 path
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

// 自己 ssh 连接的path
root@dev:~# echo $PATH
/root/.nvm/versions/node/v20.13.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

经过查找,发现 gitlab 的 SSH Executor 用的是非交互式 shell 来执行命令,这会导致某些初始化脚本(如 ~/.bashrc)不会被执行。

而 mvn 安装 nodejs 之后是在 ~/.bashrc 文件中配置 path 的,所以只要把 nodejs 的 bin 目录添加到 path 中去即可

解决方法

在 script 中修改 path

    - export PATH=/root/.nvm/versions/node/v20.13.1/bin:$PATH