如何在 GitHub 动作中使用 pipenv?
How do you use pipenv in a GitHub action?
我正在使用 pipenv 为 GitHub 操作安装 python 依赖项。这是我的 pipfile 的样子:
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
pylint = "*"
[packages]
pandas = "*"
pygithub = "*"
matplotlib = "*"
[requires]
python_version = "3.8"
Dockerfile 如下所示:
FROM python:3
COPY main.py /
COPY Pipfile /
COPY Pipfile.lock /
COPY views.csv /
# https://github.com/pypa/pipenv/issues/4273
RUN pip install 'pipenv==2018.11.26'
RUN pipenv install --deploy --ignore-pipfile
ENTRYPOINT ["pipenv", "run", "python", "./main.py"
我可以 运行 在我的机器上本地 docker 图像,一切都按预期工作,但是当我将它推送到 GitHub 时,它失败了:
Virtualenv location: /github/home/.local/share/virtualenvs/workspace-0SZQOxG8
Traceback (most recent call last):
File "./main.py", line 1, in <module>
from github import Github
ModuleNotFoundError: No module named 'github'
出于某种原因,当 docker 图像在 GitHub 虚拟机上 运行 时,它没有获取任何依赖项。
编辑 2020 年 7 月 28 日:
这是触发操作的工作流的main.yml。
on:
push:
branches:
- master
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "insights_job"
insights_job:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: GitHub insights
id: insights
uses: ./
简短版
只需将此添加到 Docker 文件的顶部:
# Tells pipenv to create virtualenvs in /root rather than $HOME/.local/share.
# We do this because GitHub modifies the HOME variable between `docker build` and
# `docker run`
ENV WORKON_HOME /root
# Tells pipenv to use this specific Pipfile rather than the Pipfile in the
# current working directory (the working directory changes between `docker build`
# and `docker run`, this ensures we always use the same Pipfile)
ENV PIPENV_PIPFILE /Pipfile
长版
可以看出here,Github actions定义HOME
环境变量为/github/home
.
我们可以看到此变量随后通过操作步骤日志中可见的 run
命令传递到 docker 容器:
/usr/bin/docker run --name c201c6ad6ba986775dbb96d3c072d294f3c8_a057c6 --label 87c201 --workdir /github/workspace --rm -e HOME -e GITHUB_JOB -e GITHUB_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_ACTOR -e GITHUB_WORKFLOW -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GITHUB_EVENT_NAME -e GITHUB_SERVER_URL -e GITHUB_API_URL -e GITHUB_GRAPHQL_URL -e GITHUB_WORKSPACE -e GITHUB_ACTION -e GITHUB_EVENT_PATH -e RUNNER_OS -e RUNNER_TOOL_CACHE -e RUNNER_TEMP -e RUNNER_WORKSPACE -e ACTIONS_RUNTIME_URL -e ACTIONS_RUNTIME_TOKEN -e ACTIONS_CACHE_URL -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/j/j":"/github/workspace" 87c201:c6ad6ba986775dbb96d3c072d294f3c8
(注意 -e home
标志)
pipenv install
在 $HOME/.local/share/virtualenvs
中创建一个 virtualenv 并在该目录中安装所有依赖项。 pipenv run ...
然后使用相同的路径找到 virtualenv 运行 所需的命令。
在 Docker 映像 (docker build
) 的构建阶段,$HOME
具有默认值 /root
(因为那是 root 用户的主目录),所以 virtualenv 在 /root/.local/share/virtualenvs
.
中创建
但是,在 docker run
阶段,HOME
设置为 /github/home
(如上所述)。因此,virtualenv 在 /github/home/.local/share/virtualenvs
.
中创建
总结一下-
pipenv install
使用 /root/.local/share/virtualenvs
pipenv run
使用 /github/home/.local/share/virtualenvs
这意味着依赖项安装在一个地方,但当脚本实际 运行.
时预计会在不同的地方
为了克服这个问题,我们可以使用 ENV
语句在 Docker 文件中设置 WORKON_HOME
。
WORKON_HOME
变量受到 pipenv
的尊重,它更愿意将其虚拟环境放置在 WORKON_HOME
中定义的路径中,而不是 HOME
中定义的路径中.
所以解决方案是添加
ENV WORKON_HOME /root
到Dockerfile
.
然而,这还不够,因为 pipenv 根据 pipenv
文件的位置选择 virtualenv。 --workdir
被 Github 设置为 /github/workspace
然后整个项目源代码被挂载到那个文件夹中,所以当我们 pipenv run
我们实际上使用 Pipenv
文件在 /github/workspace
中。这是一个与 docker build
阶段复制到 /
并用于 pipenv install
的文件不同的 Pipenv
文件。由于使用了两个不同的 Pipenv 位置,因此将使用两个不同的 virtualenvs。
要解决这个问题,我们可以使用 PIPENV_PIPEFILE
环境变量。此变量告诉 pipenv
在该变量指定的位置而不是在当前工作目录中查找 Pipfile
。
我们也将其添加到我们的 Docker 文件中:
ENV PIPENV_PIPFILE /Pipfile
我正在使用 pipenv 为 GitHub 操作安装 python 依赖项。这是我的 pipfile 的样子:
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
pylint = "*"
[packages]
pandas = "*"
pygithub = "*"
matplotlib = "*"
[requires]
python_version = "3.8"
Dockerfile 如下所示:
FROM python:3
COPY main.py /
COPY Pipfile /
COPY Pipfile.lock /
COPY views.csv /
# https://github.com/pypa/pipenv/issues/4273
RUN pip install 'pipenv==2018.11.26'
RUN pipenv install --deploy --ignore-pipfile
ENTRYPOINT ["pipenv", "run", "python", "./main.py"
我可以 运行 在我的机器上本地 docker 图像,一切都按预期工作,但是当我将它推送到 GitHub 时,它失败了:
Virtualenv location: /github/home/.local/share/virtualenvs/workspace-0SZQOxG8
Traceback (most recent call last):
File "./main.py", line 1, in <module>
from github import Github
ModuleNotFoundError: No module named 'github'
出于某种原因,当 docker 图像在 GitHub 虚拟机上 运行 时,它没有获取任何依赖项。
编辑 2020 年 7 月 28 日:
这是触发操作的工作流的main.yml。
on:
push:
branches:
- master
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "insights_job"
insights_job:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: GitHub insights
id: insights
uses: ./
简短版
只需将此添加到 Docker 文件的顶部:
# Tells pipenv to create virtualenvs in /root rather than $HOME/.local/share.
# We do this because GitHub modifies the HOME variable between `docker build` and
# `docker run`
ENV WORKON_HOME /root
# Tells pipenv to use this specific Pipfile rather than the Pipfile in the
# current working directory (the working directory changes between `docker build`
# and `docker run`, this ensures we always use the same Pipfile)
ENV PIPENV_PIPFILE /Pipfile
长版
可以看出here,Github actions定义HOME
环境变量为/github/home
.
我们可以看到此变量随后通过操作步骤日志中可见的 run
命令传递到 docker 容器:
/usr/bin/docker run --name c201c6ad6ba986775dbb96d3c072d294f3c8_a057c6 --label 87c201 --workdir /github/workspace --rm -e HOME -e GITHUB_JOB -e GITHUB_REF -e GITHUB_SHA -e GITHUB_REPOSITORY -e GITHUB_REPOSITORY_OWNER -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_ACTOR -e GITHUB_WORKFLOW -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GITHUB_EVENT_NAME -e GITHUB_SERVER_URL -e GITHUB_API_URL -e GITHUB_GRAPHQL_URL -e GITHUB_WORKSPACE -e GITHUB_ACTION -e GITHUB_EVENT_PATH -e RUNNER_OS -e RUNNER_TOOL_CACHE -e RUNNER_TEMP -e RUNNER_WORKSPACE -e ACTIONS_RUNTIME_URL -e ACTIONS_RUNTIME_TOKEN -e ACTIONS_CACHE_URL -e GITHUB_ACTIONS=true -e CI=true -v "/var/run/docker.sock":"/var/run/docker.sock" -v "/home/runner/work/_temp/_github_home":"/github/home" -v "/home/runner/work/_temp/_github_workflow":"/github/workflow" -v "/home/runner/work/j/j":"/github/workspace" 87c201:c6ad6ba986775dbb96d3c072d294f3c8
(注意 -e home
标志)
pipenv install
在 $HOME/.local/share/virtualenvs
中创建一个 virtualenv 并在该目录中安装所有依赖项。 pipenv run ...
然后使用相同的路径找到 virtualenv 运行 所需的命令。
在 Docker 映像 (docker build
) 的构建阶段,$HOME
具有默认值 /root
(因为那是 root 用户的主目录),所以 virtualenv 在 /root/.local/share/virtualenvs
.
但是,在 docker run
阶段,HOME
设置为 /github/home
(如上所述)。因此,virtualenv 在 /github/home/.local/share/virtualenvs
.
总结一下-
pipenv install
使用 /root/.local/share/virtualenvs
pipenv run
使用 /github/home/.local/share/virtualenvs
这意味着依赖项安装在一个地方,但当脚本实际 运行.
时预计会在不同的地方为了克服这个问题,我们可以使用 ENV
语句在 Docker 文件中设置 WORKON_HOME
。
WORKON_HOME
变量受到 pipenv
的尊重,它更愿意将其虚拟环境放置在 WORKON_HOME
中定义的路径中,而不是 HOME
中定义的路径中.
所以解决方案是添加
ENV WORKON_HOME /root
到Dockerfile
.
然而,这还不够,因为 pipenv 根据 pipenv
文件的位置选择 virtualenv。 --workdir
被 Github 设置为 /github/workspace
然后整个项目源代码被挂载到那个文件夹中,所以当我们 pipenv run
我们实际上使用 Pipenv
文件在 /github/workspace
中。这是一个与 docker build
阶段复制到 /
并用于 pipenv install
的文件不同的 Pipenv
文件。由于使用了两个不同的 Pipenv 位置,因此将使用两个不同的 virtualenvs。
要解决这个问题,我们可以使用 PIPENV_PIPEFILE
环境变量。此变量告诉 pipenv
在该变量指定的位置而不是在当前工作目录中查找 Pipfile
。
我们也将其添加到我们的 Docker 文件中:
ENV PIPENV_PIPFILE /Pipfile