记一次 CI 构建失败的排查过程

125 阅读3分钟

前言

春节期间对博客修修补补,在一次提交中,仅仅修改了一个字段名(date -> createDate),CI 构建突然失败。错误信息如下:

image.png

排查问题

1. 分析问题

因为只变更了字段名,没有变更配置文件,于是直接在 Github Action重新执行历史成功的CI,结果发现也失败。那么定位问题就集中在yml文件上。

2. 配置分析

frontend-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: "21"

      - name: Install Dependencies
        working-directory: ./frontend
        run: |
          rm -rf node_modules package-lock.json
          npm install

      - name: Build
        working-directory: ./frontend
        run: npm run build
  
      - name: Deploy to server
        uses: appleboy/scp-action@master
        with:

可以看到在Install Dependencies环节会删除package-lock.json在重新 npm install,结合package.json文件

"dependencies": {
    "@element-plus/icons-vue": "^2.3.1",
    "axios": "^1.6.2",
    "bignumber.js": "^9.1.2",
    "compressing": "^1.5.1",
    "core-js": "^3.35.0",
    "cors": "^2.8.5",
    "cross-env": "^7.0.3",
    "dotenv": "^16.3.1",
    "element-plus": "^2.4.4",
    "express": "^4.21.1",
    "normalize.css": "^8.0.1",
    "rxjs": "^7.8.0",
    "vite": "^5.0.10",
    "vue": "^3.4.3",
    "vue-router": "^4.2.5",
    "md-editor-v3": "5.2.1"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^6.16.0",
    "@typescript-eslint/parser": "^6.16.0",
    "@vitejs/plugin-vue": "^5.2.1",
    "eslint": "^8.56.0",
    "eslint-plugin-vue": "^9.19.2",
    "sass": "^1.69.5",
    "typescript": "^5.3.3",
    "unplugin-auto-import": "^0.17.3",
    "unplugin-vue-components": "^0.26.0"
  },

npm install + ^可能会存在依赖问题

  1. ^ 符号(兼容版本)
    • 正常版本(≥1.0.0):
      "vite": "^4.5.1"  // 允许 4.5.1 到 4.99.99
      
    • 0.x 版本:
      "pkg": "^0.5.1"   // 允许 0.5.1 到 0.5.99
      
    • 0.0.x 版本:
      "pkg": "^0.0.1"   // 严格锁定到 0.0.1
      

使用 npm ci 替代

image.png

npm ci 与 npm install有什么区别?

1. 依赖安装方式:

  • npm install

    • 根据 package.json 安装依赖
    • 如果有 package-lock.json,会尽量遵循,但可能更新
    • 可能更新 package-lock.json
  • npm ci

    • 严格根据 package-lock.json 安装依赖
    • 必须有 package-lock.json
    • 不会修改 package-lock.json

2. 使用场景:

  • npm install

    • 适用于开发环境
    • 当需要添加/更新依赖时使用
    • 允许版本范围和依赖更新
  • npm ci

    • 专门为 CI/CD 环境设计
    • 用于生产环境构建
    • 确保可重现的构建结果

3. 执行过程:

  • npm install

    • 可以单独安装包
    • 增量更新 node_modules
    • 运行速度相对较慢
  • npm ci

    • 总是删除现有的 node_modules
    • 全新安装所有依赖
    • 通常比 npm install 快

4. 版本处理:

  • npm install

    {
      "dependencies": {
        "vite": "^5.0.10"  // 可能安装 5.0.11 或更高版本
      }
    }
    
  • npm ci

    // package-lock.json
    {
      "dependencies": {
        "vite": {
          "version": "5.0.10"  // 严格安装这个版本
        }
      }
    }
    

新的错误

重新提交,新的错误如下

npm ERR! `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.

这个错误说明 package.json 和 package-lock.json 不同步。

解决措施

1. 清理环境
rm -rf node_modules package-lock.json

2. 重新安装并生成 package-lock.json
npm install

重新push问题解决,CI成功。

image.png

总结

其实排查这个问题花费了不少时间,绕了几个弯子

  1. 当时在Github Action上看到这个错误日志时,主要去分析了这个问题
Cannot read properties of null (reading 'render')
at ConditionalExpression.render

造成这个问题原因可能有以下几种

  1. rollup的版本不对,因为将这个问题在Google搜索到的github时基本都是在说rollup的版本不对,原帖关于rollup版本4.16导致render的报错,但检查了我的package.json其实没有用到rollup,但vite内部依赖了rollup,检查了依赖下的rollup版本
 npm ls rollup
image.png

大于4.17,然后就怀疑是 vite 的版本不对,降级到4.x.x时 CI 也成功了,但我感觉解决的方式偏了,因为之前一直成功的程序,突然说要变更配置文件,这不合理。

  1. ConditionalExpression.render表示条件渲染的时候出的错,搜索发现说v-if可能存在空值导致的,但我只更改了一个字段名并没有涉及到条件语句的更改,但也尝试修改了一下,果然无效。

最后吸取这次教训,有时候已经有“解决方案”了得思考一下这个解决方案是否合理的。欢迎大家访问我的博客,也提出宝贵的建议