在同一个 gitlab CI 管道中重用 conda 环境?

Chr*_*yer 7 continuous-integration caching anaconda conda gitlab-ci

动机

我的主要目标是:在管道内,我希望尽可能多地重用(即,如果所有作业共享相同的环境,则不要多次构建 conda 环境)

在我的项目中,我使用 conda 作为依赖管理器,使用 gitlab ci/cd 进行持续集成。为了简单起见,假设我有一个构建工作和一个测试工作。最直接的方法是在任何工作中创建 conda 环境environment.yml,然后执行实际工作。这会给任何作业增加几分钟的开销。对我来说这似乎也是开销,因为我想在构建作业中构建一次环境,然后在我的测试作业中使用它(特别是在为不同的测试创建多个作业时)。

研究成果

我需要做的第一件事是将其设置CONDA_ENVS_PATH为项目目录中的某个位置。

我查看了 gitlab 的缓存机制,但发现它只对同一管道重复运行中的同一作业有帮助,但对管道内同一运行的不同作业没有帮助。

我还研究了 gitlab 的工件机制,但发现由于这些工件的上传和下载,它们并没有显着增加运行时间(基本上我只是通过不下载许多小包并且不必再次编译它们来节省时间,但通过压缩和解压它们可以节省时间)。

我还尝试通过在我的测试GIT_CLEAN_FLAGS工作中将它们设置为来利用它们。这样,从git获取最新数据时,conda环境就不会被删除。这确实会导致我的管道严重加速,但它并不总是有效。有些作业失败,是因为找不到 conda 环境。然而,简单的重新运行确实能神奇地发挥作用。当然,在 CI/CD 设置中,这种不确定性是不切实际的。none

作为原始问题的解决方法,我们提出了一个中间解决方案。我们引入了一个 docker 镜像,通过一个最小的 Dockerfile 和一些更改来保存我们的自定义环境.gitlab-ci.yml(请参阅下面的示例)。通过仅在 dockerfile 或环境发生更改时执行构建自定义 docker 映像的作业,我们可以在每次运行时节省宝贵的时间。同时,我们在环境定义中保持充分的灵活性,并且可以按照我们通常的方式进行调整:通过更改environment.yml.

问题

到目前为止尝试的所有解决方案都不是非常令人满意。因此我的问题是:我的测试作业如何重用与gitlab-ci 中的构建作业相同的 conda 环境?


如果其他人想使用类似的设置:这是我当前的方法:

# Dockerfile

FROM continuumio/miniconda3:latest

COPY environment.yml .

RUN conda env create -f environment.yml

ENTRYPOINT [""]
Run Code Online (Sandbox Code Playgroud)
# .gitlab-ci.yml

# Use the latest version of this project's docker file
# This will be the default image for all jobs unless specified otherwise
image: $CI_REGISTRY_IMAGE:latest


# Change cache directories to be inside the project directory since we can
# only cache local items.
variables:
  PRE_COMMIT_HOME: "${CI_PROJECT_DIR}/.cache/pre-commit"


stages:
  - build
  - test


# Make conda environment available to all jobs
# This expects the conda environment to have the same name as the gitlab project path
# Avoid dashes and other non-alphabetical characters
default:
  before_script:
    - source activate "${CI_PROJECT_NAME}"

# Build the docker image including the correct conda environment for subsequent jobs
# This assumes a docker image registry being configured for your gitlab instance
dockerimage:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  rules:
    - changes:
      - Dockerfile
      - environment.yml
  before_script: [ ]
  script:
    - mkdir -p /kaniko/.docker
    - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:latest


# Run pytest
pytest:
  stage: test
  script:
    - conda install pytest-cov
    - pytest tests --cov=src
Run Code Online (Sandbox Code Playgroud)

编辑:我用我们最新的方法替换了使用 GIT_CLEAN_FLAGS 的示例代码:使用自定义 docker 映像。


免责声明:我看到了这个这个问题,但它们都已过时,没有令人满意的答案,而且我只是在写完这个问题后才找到它们,所以我希望我的附加问题可以增加该主题的可发现性。