GitHub 我编写的操作无权访问调用该操作的存储库文件
GitHub Action I wrote doesn't have access to repo's files that is calling the action
GitHub here 上有一个示例存储库,其中包含我正在处理的目录结构。要 运行 GitHub 操作,您只需转到存储库的“操作”选项卡并手动 运行 操作。
我有一个自定义 GitHub 动作,我也用 python
作为 Docker 容器中的基本图像编写,但希望 python
版本是GitHub 操作的输入。为此,我使用 python
版本输入参数为 运行 创建了第二个中间 Docker 容器。
我遇到的问题 运行 是我无法访问调用 GitHub 操作的原始存储库文件。例如,假设 repo 名为 python-sample-project
并具有文件夹结构:
python-sample-project
│ main.py
│ file1.py
│
└───folder1
│ │ file2.py
我在 entrypoint.sh
中看到 main.py
、file1.py
和 folder1/file2.py
。但是,在 docker-action/entrypoint.sh
中我只看到 linux 文件夹结构和在 docker-action/Dockerfile
中复制的 entrypoint.sh
文件。
在我使用的 Alpine 示例中,操作 entrypoint.sh
脚本如下所示:
#!/bin/sh -l
ALPINE_VERSION=
cd /docker-action
docker build -t docker-action --build-arg alpine_version="$ALPINE_VERSION" . && docker run docker-action
在docker-action/
中我有一个Dockerfile
和entrypoint.sh
脚本应该运行用于Alpine动态版本的内部容器(或Python )
docker-action/Dockerfile
如下:
# Container image that runs your code
ARG alpine_version
FROM alpine:${alpine_version}
# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]
在 docker-action/entrypoint
我 运行 ls
但我没有看到存储库文件。
是否可以在 docker-action/entrypoint.sh
中访问 entrypoint.sh
中的 main.py
、file1.py
和 folder1/file2.py
?
通常有两种方法可以从您的存储库中获取文件以供您构建的 docker 容器和 运行 使用。您可以 (1) 在构建映像时将文件添加到映像中,或者 (2) 在 运行 时将文件装载到容器中。还有其他一些方法,例如指定卷,但这可能超出了本例的范围。
Dockerfile docker-action/Dockerfile
不复制除 entrypoint.sh
脚本之外的任何文件。当 运行 连接容器时,您的 entrypoint.sh
也不提供任何挂载点。因此,您观察到的结果是基于这些事实的预期结果。
为了解决这个问题,您必须 (1) 添加 COPY
/ADD
语句到您的 Dockerfile 以将文件复制到映像中(并设置适当的构建上下文)或 (2)通过将 -v /source-path:/container-path
添加到 entrypoint.sh
.
中的 docker run
命令,在 运行 时将文件装载到容器中
参见参考资料:
不过,这种构建另一个容器只是为了获得用户提供的 python 版本的方法对于 GitHub 操作来说是一种非常值得怀疑的做法,应该避免。考虑改用 setup-python 操作。
docker-in-docker 问题
然而,如果您继续此路线并想要安装目录,您必须记住,在 docker 上的 docker 操作中调用 docker
时129=],挂载规范中的文件系统是指docker主机的文件系统,不是容器的文件系统。
它能在我的机器上运行吗?!
例如,与您在本地系统上 运行ning docker
可能遇到的情况相反,这在 GitHub 中不起作用 -- 工作目录未挂载:
docker run -v $(pwd):/opt/workspace \
--workdir /opt/workspace \
--entrypoint /bin/ls \
my-container "-R"
这也不行:
docker run -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE \
--workdir $GITHUB_WORKSPACE \
--entrypoint /bin/ls \
my-container "-R"
如果您在 运行ning docker 本地系统上尝试,这种东西会工作得很好。给出了什么?
与恶魔(守护进程)打交道
在 Actions 中,文件检出到 $GITHUB_WORKSPACE
的起始工作目录。在 docker 个操作中,即 /github/workspace
。当 你的 操作 运行 由 Actions 运行ner mounting 工作区时,工作区文件填充到工作区中docker 守护程序所在的主机 运行ning.
您可以在命令 运行 中看到当您的操作开始时:
/usr/bin/docker run --name f884202608aa2bfab75b6b7e1f87b3cd153444_f687df --label f88420 --workdir /github/workspace --rm -e INPUT_ALPINE-VERSION -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_RETENTION_DAYS -e GITHUB_RUN_ATTEMPT -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 GITHUB_ACTION_REPOSITORY -e GITHUB_ACTION_REF -e GITHUB_PATH -e GITHUB_ENV -e RUNNER_OS -e RUNNER_NAME -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/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/my-repo/my-repo":"/github/workspace" f88420:2608aa2bfab75b6b7e1f87b3cd153444 "3.9.5"
重要的部分是:
-v "/home/runner/work/my-repo/my-repo":"/github/workspace"
-v "/var/run/docker.sock":"/var/run/docker.sock"
/home/runner/work/my-repo/my-repo
是主机上的路径,存储库文件所在的位置。如前所述,第一行是当它获得 运行.
时将其安装到操作容器中的 /github/workspace
中的内容
第二行是将 docker 套接字从主机安装到操作容器。这意味着 任何时候你在你的操作中调用 docker
,你实际上是在与容器外的 docker 守护进程对话 。这很重要,因为这意味着当 you 在你的操作中使用 -v
参数 inside 时,参数需要反映存在于外部的目录容器。
所以,您实际上需要做的是:
docker run -v /home/runner/work/my-repo/my-repo:/opt/workspace \
--workdir /opt/workspace \
--entrypoint /bin/ls \
my-container "-R"
成为对他人有用的人
这行得通。如果你只将它用于项目本身。但是,如果您希望此操作可供其他项目使用,那么您(除其他外)还有一个问题。您如何知道工作区在主机上的位置?毕竟,每个存储库都会更改此路径。 GitHub 也不保证这些路径。它们在不同平台上可能不同,或者您的操作可能 运行ning 在自托管 运行ner 上。
那么你如何满足于这个问题?不幸的是,没有内置环境变量指向您特别需要的目录。但是,通过依赖实现细节,您可能能够使用 $RUNNER_WORKSPACE
变量,在本例中它将指向 /home/runner/work/your-project
。这与 $GITHUB_WORKSPACE
的起源地不同,但很接近。您可以使用 GITHUB_REPOSITORY
变量来构建路径,但不能保证总是如此 afaik:
PROJECT_NAME="$(basename ${GITHUB_REPOSITORY})"
WORKSPACE="${RUNNER_WORKSPACE}/${PROJECT_NAME}"
您还需要修复一些其他问题,例如您构建的工作目录表单。
TL;DR
当你运行它时,你需要在容器中挂载文件。在 GitHub 中,你 运行ning docker-in-docker,所以你需要用来挂载文件的路径不同,所以你需要找到正确的路径从您的操作容器中调用时传递给 docker
。
您链接的示例项目的最低工作解决方案是 entrypoint.sh
在 repo 的根目录中,如下所示:
#!/usr/bin/env sh
ALPINE_VERSION=
docker build -t docker-action \
-f ./docker-action/Dockerfile \
--build-arg alpine_version="$ALPINE_VERSION" \
./docker-action
PROJECT_NAME="$(basename ${GITHUB_REPOSITORY})"
WORKSPACE="${RUNNER_WORKSPACE}/${PROJECT_NAME}"
docker run --workdir=$GITHUB_WORKSPACE \
-v $WORKSPACE:$GITHUB_WORKSPACE \
docker-action "$@"
您的操作可能还有其他问题,具体取决于它的作用,例如为 'inner' 容器提供操作的所有默认和用户定义环境变量(如果这很重要)。
那么,这可能吗?当然。只得到动态版的alpine/python合理吗?我不这么认为。可能有更好的方法来完成你想做的事情,比如使用 setup-python
,但这听起来像是一个不同的问题。
GitHub here 上有一个示例存储库,其中包含我正在处理的目录结构。要 运行 GitHub 操作,您只需转到存储库的“操作”选项卡并手动 运行 操作。
我有一个自定义 GitHub 动作,我也用 python
作为 Docker 容器中的基本图像编写,但希望 python
版本是GitHub 操作的输入。为此,我使用 python
版本输入参数为 运行 创建了第二个中间 Docker 容器。
我遇到的问题 运行 是我无法访问调用 GitHub 操作的原始存储库文件。例如,假设 repo 名为 python-sample-project
并具有文件夹结构:
python-sample-project
│ main.py
│ file1.py
│
└───folder1
│ │ file2.py
我在 entrypoint.sh
中看到 main.py
、file1.py
和 folder1/file2.py
。但是,在 docker-action/entrypoint.sh
中我只看到 linux 文件夹结构和在 docker-action/Dockerfile
中复制的 entrypoint.sh
文件。
在我使用的 Alpine 示例中,操作 entrypoint.sh
脚本如下所示:
#!/bin/sh -l
ALPINE_VERSION=
cd /docker-action
docker build -t docker-action --build-arg alpine_version="$ALPINE_VERSION" . && docker run docker-action
在docker-action/
中我有一个Dockerfile
和entrypoint.sh
脚本应该运行用于Alpine动态版本的内部容器(或Python )
docker-action/Dockerfile
如下:
# Container image that runs your code
ARG alpine_version
FROM alpine:${alpine_version}
# Copies your code file from your action repository to the filesystem path `/` of the container
COPY entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
# Code file to execute when the docker container starts up (`entrypoint.sh`)
ENTRYPOINT ["/entrypoint.sh"]
在 docker-action/entrypoint
我 运行 ls
但我没有看到存储库文件。
是否可以在 docker-action/entrypoint.sh
中访问 entrypoint.sh
中的 main.py
、file1.py
和 folder1/file2.py
?
通常有两种方法可以从您的存储库中获取文件以供您构建的 docker 容器和 运行 使用。您可以 (1) 在构建映像时将文件添加到映像中,或者 (2) 在 运行 时将文件装载到容器中。还有其他一些方法,例如指定卷,但这可能超出了本例的范围。
Dockerfile docker-action/Dockerfile
不复制除 entrypoint.sh
脚本之外的任何文件。当 运行 连接容器时,您的 entrypoint.sh
也不提供任何挂载点。因此,您观察到的结果是基于这些事实的预期结果。
为了解决这个问题,您必须 (1) 添加 COPY
/ADD
语句到您的 Dockerfile 以将文件复制到映像中(并设置适当的构建上下文)或 (2)通过将 -v /source-path:/container-path
添加到 entrypoint.sh
.
docker run
命令,在 运行 时将文件装载到容器中
参见参考资料:
不过,这种构建另一个容器只是为了获得用户提供的 python 版本的方法对于 GitHub 操作来说是一种非常值得怀疑的做法,应该避免。考虑改用 setup-python 操作。
docker-in-docker 问题
然而,如果您继续此路线并想要安装目录,您必须记住,在 docker 上的 docker 操作中调用 docker
时129=],挂载规范中的文件系统是指docker主机的文件系统,不是容器的文件系统。
它能在我的机器上运行吗?!
例如,与您在本地系统上 运行ning docker
可能遇到的情况相反,这在 GitHub 中不起作用 -- 工作目录未挂载:
docker run -v $(pwd):/opt/workspace \
--workdir /opt/workspace \
--entrypoint /bin/ls \
my-container "-R"
这也不行:
docker run -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE \
--workdir $GITHUB_WORKSPACE \
--entrypoint /bin/ls \
my-container "-R"
如果您在 运行ning docker 本地系统上尝试,这种东西会工作得很好。给出了什么?
与恶魔(守护进程)打交道
在 Actions 中,文件检出到 $GITHUB_WORKSPACE
的起始工作目录。在 docker 个操作中,即 /github/workspace
。当 你的 操作 运行 由 Actions 运行ner mounting 工作区时,工作区文件填充到工作区中docker 守护程序所在的主机 运行ning.
您可以在命令 运行 中看到当您的操作开始时:
/usr/bin/docker run --name f884202608aa2bfab75b6b7e1f87b3cd153444_f687df --label f88420 --workdir /github/workspace --rm -e INPUT_ALPINE-VERSION -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_RETENTION_DAYS -e GITHUB_RUN_ATTEMPT -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 GITHUB_ACTION_REPOSITORY -e GITHUB_ACTION_REF -e GITHUB_PATH -e GITHUB_ENV -e RUNNER_OS -e RUNNER_NAME -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/_temp/_runner_file_commands":"/github/file_commands" -v "/home/runner/work/my-repo/my-repo":"/github/workspace" f88420:2608aa2bfab75b6b7e1f87b3cd153444 "3.9.5"
重要的部分是:
-v "/home/runner/work/my-repo/my-repo":"/github/workspace"
-v "/var/run/docker.sock":"/var/run/docker.sock"
/home/runner/work/my-repo/my-repo
是主机上的路径,存储库文件所在的位置。如前所述,第一行是当它获得 运行.
/github/workspace
中的内容
第二行是将 docker 套接字从主机安装到操作容器。这意味着 任何时候你在你的操作中调用 docker
,你实际上是在与容器外的 docker 守护进程对话 。这很重要,因为这意味着当 you 在你的操作中使用 -v
参数 inside 时,参数需要反映存在于外部的目录容器。
所以,您实际上需要做的是:
docker run -v /home/runner/work/my-repo/my-repo:/opt/workspace \
--workdir /opt/workspace \
--entrypoint /bin/ls \
my-container "-R"
成为对他人有用的人
这行得通。如果你只将它用于项目本身。但是,如果您希望此操作可供其他项目使用,那么您(除其他外)还有一个问题。您如何知道工作区在主机上的位置?毕竟,每个存储库都会更改此路径。 GitHub 也不保证这些路径。它们在不同平台上可能不同,或者您的操作可能 运行ning 在自托管 运行ner 上。
那么你如何满足于这个问题?不幸的是,没有内置环境变量指向您特别需要的目录。但是,通过依赖实现细节,您可能能够使用 $RUNNER_WORKSPACE
变量,在本例中它将指向 /home/runner/work/your-project
。这与 $GITHUB_WORKSPACE
的起源地不同,但很接近。您可以使用 GITHUB_REPOSITORY
变量来构建路径,但不能保证总是如此 afaik:
PROJECT_NAME="$(basename ${GITHUB_REPOSITORY})"
WORKSPACE="${RUNNER_WORKSPACE}/${PROJECT_NAME}"
您还需要修复一些其他问题,例如您构建的工作目录表单。
TL;DR
当你运行它时,你需要在容器中挂载文件。在 GitHub 中,你 运行ning docker-in-docker,所以你需要用来挂载文件的路径不同,所以你需要找到正确的路径从您的操作容器中调用时传递给 docker
。
您链接的示例项目的最低工作解决方案是 entrypoint.sh
在 repo 的根目录中,如下所示:
#!/usr/bin/env sh
ALPINE_VERSION=
docker build -t docker-action \
-f ./docker-action/Dockerfile \
--build-arg alpine_version="$ALPINE_VERSION" \
./docker-action
PROJECT_NAME="$(basename ${GITHUB_REPOSITORY})"
WORKSPACE="${RUNNER_WORKSPACE}/${PROJECT_NAME}"
docker run --workdir=$GITHUB_WORKSPACE \
-v $WORKSPACE:$GITHUB_WORKSPACE \
docker-action "$@"
您的操作可能还有其他问题,具体取决于它的作用,例如为 'inner' 容器提供操作的所有默认和用户定义环境变量(如果这很重要)。
那么,这可能吗?当然。只得到动态版的alpine/python合理吗?我不这么认为。可能有更好的方法来完成你想做的事情,比如使用 setup-python
,但这听起来像是一个不同的问题。