gitlib ci 前端项目打包优化

394 阅读3分钟

如何避免在 Gitlab CI 中每个作业重新安装依赖项

 .gitlab-ci.yml 

  before_script:
     - npm install
  client_script:
     script: npm run test

这样写是可以的,但这意味着依赖项是在每个测试job之前独立安装的。对于具有许多依赖项的大型项目,这会增加相当大的开销。 由于国内网络下载 node_modules 包花费很长时间。

在 Jenkins 中,我会使用一个来安装依赖项,然后将它们 TAR 起来并创建一个构建工件,然后将其复制到下游作业。Gitlab CI 会有类似的东西吗?有推荐的方法吗?

解决方案1: 使用 shell 脚本实现缓存系统

before_script:
  # 设置唯一 hash
  - PACKAGE_HASH=($(md5sum package.json))
  # 缓存文件路径
  - DEPS_CACHE=/tmp/dependencies_${PACKAGE_HASH}.tar.gz
  # 检查缓存文件是否存在,如果不存在,就创建它
  - if [ -f $DEPS_CACHE ];
    then
      tar zxf $DEPS_CACHE;
    else
      npm install -q;
      tar zcf - ./node_modules > $DEPS_CACHE;
    fi

这样仅在更改package.json 或缓存文件丢失时 .gitlab-ci.yml  重新安装依赖项 (例如,首次运行或文件被手动删除)。请注意,如果您在不同的服务器上有多个运行器,它们将各自有自己的缓存文件。

如果希望定期清除缓存文件以获取最新的依赖项。我们使用以下计时程序执行此操作:

@daily  find /tmp/dependencies_* -mtime +1 -type f -delete

@daily是一个计时程序(cron)命令,指定任务执行的频率。在本例中,@daily表示以下命令应该每天运行一次。

命令本身find /tmp/ dependcies_ * -mtime +1 -type f -delete,搜索/tmp目录下名称以dependcies_开头且在过去24小时内未被修改过的文件。然后,它使用-delete选项删除符合这些条件的任何文件。

下面是find命令中使用的每个选项的解释:

/tmp/ dependcies_ :搜索文件的路径。星号()告诉find查找名称以依赖项_开头的文件。

-mtime +1:将查询结果限制为最近一次修改时间超过一天的文件。

-type f:将搜索限制为常规文件(而不是目录或其他类型的文件)。

-delete:删除通过上述选项找到的任何匹配文件。

总的来说,这个cron作业将每天删除一次/tmp中名称以dependes_开头且超过一天的所有文件。

解决方案2:

  1. 使用 artifacts 来指定需要保存为job artifacts的文件。job artifacts是一个文件目录列表,在job成功、失败或始终附加到job。

  2. 在作业完成后,工件被发送到GitLab。他们可以在GitLab UI下载。

  3. 默认情况下,后期阶段的作业会自动下载所创建的所有工件

  4. 通过早期阶段的工作。可以控制作业中的工件下载行为

在下面的示例中,一旦构建阶段成功完成,node_modules/目录就可以立即用于lint阶段。

build:
  stage: build
  script:
    - npm install -q
    - npm run build
  artifacts:
    paths:
      - node_modules/
  expire_in: 1 week
lint:
  stage: test
  script:
    - npm run lint

解决方案3:
使用cache 在GitLab 15.0中引入,缓存不会在受保护的分支和不受保护的分支之间共享。 当不需要更新缓存时(例如,在test job中构建文件夹),使用  policy: pull 
gitlib cache文档

image: node
stages:
 - init_cache
 - test
 - build
 
cache:
 key: node_modules
 paths:
  - node_modules/
  
init_cache:node_modules:
 stage: init_cache
 # 手动触发
 when: manual
 cache:
  key: node_modules
  paths:
    - node_modules/
  after_script:
   - node -v && npm -v
  script:
  - npm install
  
test:
 stage: test
 cache:
   key: node_modules
   paths:
     - node_modules/
   policy: pull
 before_script:
  - node -v && npm -v
 script:
- npm run test

build:
 stage: build
 cache:
 key: node_modules
 paths:
   - node_modules/
 policy: pull
 script:
  - npm run build