【问题标题】:How can I use pip cache in github actions?如何在 github 操作中使用 pip 缓存?
【发布时间】:2020-03-26 09:03:44
【问题描述】:

我在 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 install 的结果依赖于 python 版本

标签: continuous-integration github-actions


【解决方案1】:

你也可以缓存一个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/

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      如果您使用多个操作系统,您可以执行以下操作以矩阵形式获取 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

      【讨论】:

        【解决方案4】:

        我在为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

        【讨论】:

          猜你喜欢
          • 2019-08-02
          • 2021-09-23
          • 2021-05-27
          • 1970-01-01
          • 2021-01-21
          • 2020-12-19
          • 1970-01-01
          • 2021-04-15
          相关资源
          最近更新 更多