CI踩坑记录

345 阅读2分钟

背景

很多问题在本地没遇到,一准备上线到CI上就遇到了,阻碍上线实在难受,记录下来踩过的坑。当然,有些问题和CI无关,只是在CI脚本里执行后failed后才发现的一些小问题,全记录下来。

问题记录

1. npm version报错

  • ci.yml如下:
stages:
  - build

before_script:
  - >
      VERSION=`date "+%m.%d"`.$CI_PIPELINE_ID;
      echo -e "${TXT_RED} ‼️ VERSION --> ${VERSION}";

build-test:
  stage: build
  image: xxxxxxx
  script:
    - echo -e "npm version $VERSION"
    - >
      npm version $VERSION
  • CI job log如下:
npm ERR! npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease [--preid=<prerelease-id>] | from-git]
npm ERR! (run in package dir)
npm ERR! 'npm -v' or 'npm --version' to print npm version (6.14.15)
npm ERR! 'npm view <pkg> version' to view a package's published version
npm ERR! 'npm ls' to inspect current package/dependency versions
ERROR: Job failed: command terminated with exit code 1
  • bug原因:想用日期+pipelineId作为版本号(如06.29.453615),使用npm version为6.14.15,要求版本号符合docs.npmjs.com/about-seman…; 直接echo -e "npm version $VERSION"不会报错

2. image镜像tag用年月日导致的ci部署乌龙

  • 问题描述:
# 开始运行之前的操作
before_script:
  - VERSION=`date "+%-y.%-m.%-d"`;
# ...
# 构建镜像的job
docker-build:
  stage: docker_build
  script:
    - docker build -t "$IMAGE_NAME:$VERSION" 
# 部署服务的job
deploy:
  stage: deploy
  script:
    - # 部署命令用到了 $IMAGE_NAME:$VERSION
  • 会出现第一天构建镜像时,打了镜像的tag为06.26.25,第二天想要部署服务时,version变为第二天日期06.26.26,导致部署服务失败;
  • 因此要合理设计version

3. webpack emit输出文件时failed

  • ci job log如下:
vendors~a.xxxxxxd7.js   34.8 KiB        [emitted] [immutable]         vendors~a
vendors~a.xxxxxd7.js.map   63.4 KiB               error Command failed with exit code 1.  [emitted] [dev] vendors~a

# ...很多输出
Uploading artifacts for failed job
Uploading artifacts...
# ...
ERROR: Job failed: command terminated with exit code 1
  • 排查过程:
    • 一开始以为是upload artifacts部分出错,后来全局log搜了一下failed字段,发现在webpack emit文件目录时,有个failed信息,感觉应该是map文件出了错;Uploading artifacts for failed job只是说job失败了,gitlab也上传了artifacts
  • bug原因:
    • 因为项目的线上环境要接sentry,需要build之后将.map资源上传到sentry服务,用于错误的源码定位;但刷cdn之前需要删掉map文件,防止源码泄漏,因此需要build之后删除map文件;
    • 之前删除map文件命令直接写在package.json的build script中(当然也是参考网上的,并且本地执行的时候没有报错),这么写应该是有异步的情况,比如删除了map文件,但build还没执行完
    // package.json
    "build:prod": "webpack --progress -p --config ./webpack-prod.js && rm -rf ./build/*.map",
    
  • 解决方法:
    • 删除build:prod里rm -rf ./build/*.map的命令
    • 在webpack plugin里使用CleanWebpackPlugin在build完成之后删除map文件,以保证顺序
    // webpack-prod.js
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    
    // ...
    new CleanWebpackPlugin({
        cleanAfterEveryBuildPatterns: ['**/*.map'],
        protectWebpackAssets: false,
    }),