如何在 github 操作中使用 pip 缓存?
How can I use pip cache in github actions?
我在 Github 操作中使用缓存 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 重新安装。
如何让它使用缓存?
您忘记在使用 actions/cache
的步骤中添加 id
。这是 Install
步骤中的条件起作用所必需的。
- uses: actions/cache@v1
id: cache
with:
...
你也可以缓存一个 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/
如果您使用多个操作系统,您可以执行以下操作以矩阵形式获取 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
我在为 Rikai 项目实现缓存时遇到了类似的问题。
最后,我找到了如果我只是按照 github actions cache
的文档中的示例,它不会像我预期的那样工作的原因
每个 pip install
执行实际上需要两个步骤。
- 下载pip包。
- 到 运行 安装脚本。
这些年网速提高了很多。所以今天,第二步可能比第一步花费更多的时间,尤其是当第二步包含编译 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
.
然后你可以非常有效地缓存必要的包。
中有一个完整的示例
我在 Github 操作中使用缓存 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 重新安装。
如何让它使用缓存?
您忘记在使用 actions/cache
的步骤中添加 id
。这是 Install
步骤中的条件起作用所必需的。
- uses: actions/cache@v1
id: cache
with:
...
你也可以缓存一个 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/
如果您使用多个操作系统,您可以执行以下操作以矩阵形式获取 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
我在为 Rikai 项目实现缓存时遇到了类似的问题。
最后,我找到了如果我只是按照 github actions cache
的文档中的示例,它不会像我预期的那样工作的原因每个 pip install
执行实际上需要两个步骤。
- 下载pip包。
- 到 运行 安装脚本。
这些年网速提高了很多。所以今天,第二步可能比第一步花费更多的时间,尤其是当第二步包含编译 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
.
然后你可以非常有效地缓存必要的包。
中有一个完整的示例