如何在 GitHub Actions 中使用 pip 缓存?

25

我在使用Github Actions的缓存pip时遇到了一些问题。我的工作流设置如下:

name: tests

on: [push, pull_request]

jobs:
  linux:

    runs-on: ubuntu-18.04
    strategy:
      max-parallel: 4
      matrix:
        python-version: [3.6, 3.7, 3.8]

    steps:
    - uses: actions/checkout@v1
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v1
      with:
        python-version: ${{ matrix.python-version }}
    - uses: actions/cache@v1
      with:
        path: ~/.cache/pip
        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
        restore-keys: |
          ${{ runner.os }}-pip-
    - name: Install
      if: steps.cache.outputs.cache-hit != 'true'
      run: |
        pip install pytest pytest-cov bandit sphinx recommonmark
        python -m pip install --upgrade pip
        pip install .
    - name: Test with pytest
      run: |
        pytest --disable-pytest-warnings --cov-report=xml --cov=chepy --cov-config=.coveragerc tests/
        coverage report -m
    - name: Test with bandit
      run: |
        bandit --recursive chepy/ --ignore-nosec --skip B101,B413,B303,B310,B112,B304,B320,B410,B404
    - name: Test docs
      run: |
        make -C docs/ clean html
    - name: Upload to codecov
      uses: codecov/codecov-action@v1.0.3
      with:
        token: ${{secrets.CODECOV_TOKEN}}
        file: ./coverage.xml

我遇到的问题是,后续触发的操作不会使用缓存,而是重新从pip安装。

我该如何让它使用缓存?


我会让缓存通常依赖于Python版本,因为一些Python软件包的pip安装结果取决于Python版本。 - Maarten Derickx
6个回答

25
您可以像这样缓存virtualenv:
    - uses: actions/cache@v2
      id: cache-venv  # name for referring later
      with:
        path: ./.venv/  # what we cache: the virtualenv
        # The cache key depends on requirements.txt
        key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements*.txt') }}
        restore-keys: |
          ${{ runner.os }}-venv-
    # Build a virtualenv, but only if it doesn't already exist
    - run: python -m venv ./.venv && . ./.venv/bin/activate && 
           pip install -r requirements.txt
      if: steps.cache-venv.outputs.cache-hit != 'true'
    # Run tests
    # Note that you have to activate the virtualenv in every step
    # because GitHub actions doesn't preserve the environment
    - run: . ./.venv/bin/activate && nosetests tests/

17

你忘记在使用actions/cache的步骤中添加id。这是Install步骤中所需的条件。

- uses: actions/cache@v1
  id:   cache
  with:
   ...

5

在实现Rikai项目的缓存时,我遇到了类似的问题。

最终,我发现如果只按照github actions cache文档中的示例进行操作,它将无法按照我的预期工作。

每个pip install执行实际上需要两个步骤:

  1. 下载pip包。
  2. 运行安装脚本。

这些年来,互联网速度提高了很多。因此,今天第二步可能比第一步花费更长的时间,特别是当第二步包含复杂的行为(如编译C/C++项目)时。但是~/.cache/pip仅缓存已下载的软件包,而不是已安装的软件包。从Github下载缓存的软件包也需要时间,与从PyPI下载相比可能没有太大区别。因此,您对缓存没有明显的感觉。

现在有一个解决方案。那就是缓存已安装的软件包,而不是下载的软件包。要知道已安装的软件包在哪里,请再次运行pip install,您将看到类似以下的内容。
Requirement already satisfied: scipy>=1.1.0 in /.../site-packages (from scikit-learn->rikai==0.0.19.dev0) (1.7.3)

"/.../site-packages 是你的包最终安装的位置。该目录因环境而异,因此您必须自行尝试以了解其位置。

在我尝试了新目录后,我发现它确实有效,每个安装命令都会显示一个日志。"

Requirement already satisfied: xxx>=xx in xxx/site-packages (from xxx) 

还有一件事

默认的site-packages目录也包含Python解释器的标准库,实际上你不需要缓存它,因为它已经被actions/setup-python包含了。我能找到的最好的方法是将包安装到用户命名空间中,通过pip install --user,并缓存用户的site-packages目录。如果您不确定它在哪里,可以使用环境变量PYTHONUSERBASE

然后,您可以以非常高效的方式缓存必要的软件包。

一个完整可行的示例在this file中。


2

如果您正在使用多个操作系统,可以按照以下步骤在矩阵中获取pip缓存:

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        include:
        - os: ubuntu-latest
          path: ~/.cache/pip
        - os: macos-latest
          path: ~/Library/Caches/pip
        - os: windows-latest
          path: ~\AppData\Local\pip\Cache
    steps:
    - uses: actions/cache@v2
      with:
        path: ${{ matrix.path }}
        key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
        restore-keys: ${{ runner.os }}-pip-

从pip 20.1+版本开始,您还可以使用pip自动获取矩阵中的缓存目录:

- name: Get pip cache dir
  id: pip-cache
  run: |
    echo "::set-output name=dir::$(pip cache dir)"

- name: pip cache
  uses: actions/cache@v2
  with:
    path: ${{ steps.pip-cache.outputs.dir }}
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

来源:https://github.com/actions/cache/blob/main/examples.md#python---pip

这个链接提供了如何在GitHub Actions中使用缓存来加速Python包的安装步骤的示例。缓存可以保存已下载的依赖项,以避免重复下载,并且可以节省时间和资源。为了使用缓存,您需要在GitHub Actions工作流程中定义一个缓存条目,并在相应的步骤中使用它。此示例还提供了如何在Windows,MacOS和Ubuntu上构建Python应用程序的不同示例。


2

看起来 actions/setup-python@v4 自带缓存功能。

steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
  with:
    python-version: '3.9'
    cache: 'pip' # caching pip dependencies
- run: pip install -r requirements.txt

请参考此页面获取更多详细信息: https://github.com/actions/setup-python#caching-packages-dependencies


0
...
      - name: set PIP_CACHE
        shell: python
        run: |
          import os
          import platform
          from os.path import expanduser

          home = expanduser("~")
          cache_path = {
            "Linux": f"{home}/.cache/pip",
            "Darwin": f"{home}Library/Caches/pip",
            "Windows": f"{home}\\AppData\\Local\\pip\\Cache"
          }[platform.system()]

          os.system(f"echo PIP_CACHE={cache_path} >> {os.environ['GITHUB_ENV']}")

      - uses: actions/cache@v3
        with:
          path: ${{ env.PIP_CACHE }}
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
          restore-keys: ${{ runner.os }}-pip-
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接