如何在 gitlab 作业中从 docker 图像执行命令?

How to execute a command from a docker image in a gitlab job?

我创建了一个 docker 图像,它为 CI/CD 存储了一个 npm project. The npm project has an npm script which runs tests. I use Gitlab,我想在其中定义一个将拉取我的图像和 运行 npm 脚本的作业。这是 .gitlab.yml:

stages:
  - test

.test-api:
  image: $CI_REGISTRY_IMAGE
  stage: test
  script:
    - cd packages/mypackage && npm run test:ci
  artifacts:
    paths:
      - packages/mypackage/test-report.html
    expire_in: 1 week

test-api-beta:
  extends: .test-api
  environment:
    name: some-env
  variables:
    CI_REGISTRY_IMAGE: my_image_name

git实验室作业失败并出现错误:

> mypackage@1.0.0 test:ci /builds/my-organization/my-project/packages/mypackage
> DEBUG=jest-mongodb:* NODE_ENV=test ts-node --transpile-only --log-error node_modules/.bin/jest --watchAll=false --detectOpenHandles --bail
sh: 1: ts-node: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! mypackage@1.0.0 test:ci: `DEBUG=jest-mongodb:* NODE_ENV=test ts-node --transpile-only --log-error node_modules/.bin/jest --watchAll=false --detectOpenHandles --bail`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the mypackage@1.0.0 test:ci script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2021-04-28T09_05_39_023Z-debug.log

主要问题是错误 npm WARN Local package.json exists, but node_modules missing, did you mean to install?。这意味着 gitlab script 在我项目的实际 git 存储库上执行,而不是在 docker 图像上执行。事实上,我的存储库不包含 node_modules,所以作业失败了。但为什么 gitlab 不在实际图像上执行 script

docker 图像有一个 CMD 指令: CMD ["npm", "run", "start"]

也许 CMD 以某种方式干扰了 git 实验室 script

P.S。手动拉取 docker 图像并在本地执行 npm 脚本是可行的。

这是我的 Dockerfile:

FROM node:14.15.1
COPY ./package.json /src/package.json

WORKDIR /src
RUN npm install
COPY ./lerna.json /src/lerna.json
COPY ./packages/mypackage/package.json /src/packages/mypackage/package.json
RUN npm run clean
COPY . /src
EXPOSE 8082
CMD ["npm" , "run", "start"]

编辑: 根据 M.Iduoad 如果脚本更改如下:

.test-api:
  image: $CI_REGISTRY_IMAGE
  stage: test
  script:
    - cd /src/packages/mypackage && npm run test:ci
  artifacts:
    paths:
      - packages/mypackage/test-report.html
    expire_in: 1 week

npm 脚本有效。我们需要 cd /src/packages/mypackage 因为这是脚本在 Dockerfile 中的位置。

Gitlab 总是克隆你的 repo 并检查你触发管道的分支和 运行 你对该代码的命令(同一文件夹 CI_PROJECT_DIR

因此,为了使用您的代码版本,您应该移动到它在您的 docker 图像中所在的文件夹。

.test-api:
  image: $CI_REGISTRY_IMAGE
  stage: test
  script:
    - cd /the/absolute/path/of/the/project/ && npm run test:ci

这样做违背了 gitlab-ci 的做事方式。由于每次 git 实验室作业 运行 时,您的作业总是 运行 使用相同的代码(图中的代码)。当 gitlab-ci 是一个 CI 系统并且旨在 运行 您根据 git 存储库中的代码工作。

总而言之,我建议您添加一个安装依赖项的阶段cies (node_modules)

stages:
  - install
  - test

install-deps:
  image: node:latest # or the version you are using
  stage: install
  script: 
    - npm install
  cache:
    key: some-key
    paths:
      - $CI_PROJECT_DIR/node_modules
.test-api:
  image: $CI_REGISTRY_IMAGE
  stage: test
  script:
    - npm run test:ci
  cache:
    key: some-key
    paths:
      - $CI_PROJECT_DIR/node_modules
  artifacts:
    paths:
      - packages/mypackage/test-report.html
    expire_in: 1 week

这将使用 gitlab-ci 的缓存功能,在您的作业和管道中存储 node_module。 您可以通过更改密钥来控制如何跨管道和作业使用和共享缓存。 (在 gitlab's docs 上阅读有关缓存的更多信息)