我编写的 GitHub Action 无法访问调用该操作的存储库文件

Ale*_*x F 9 python github docker github-actions

GitHub上有一个示例存储库,其中包含我正在处理的目录结构。要运行 GitHub Action,您只需转到存储库的 Action 选项卡并手动运行 Action。

\n
\n

我有一个自定义的 GitHub Action,以及pythonDocker 容器中的基础映像,但希望该python版本成为 GitHub Action 的输入。为此,我创建了第二个中间 Docker 容器,以使用python版本输入参数运行。

\n

我遇到的问题是我无权访问调用 GitHub Action 的原始存储库文件。例如,假设存储库被调用python-sample-project并且具有文件夹结构:

\n
python-sample-project\n\xe2\x94\x82   main.py\n\xe2\x94\x82   file1.py    \n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80folder1\n\xe2\x94\x82   \xe2\x94\x82   file2.py\n
Run Code Online (Sandbox Code Playgroud)\n

我看到了main.py,,file1.py并且folder1/file2.pyentrypoint.sh。但是,docker-action/entrypoint.sh我只看到 linux 文件夹结构和entrypoint.shdocker-action/Dockerfile.

\n

在我使用的 Alpine 示例中,操作entrypoint.sh脚本如下所示:

\n
python-sample-project\n\xe2\x94\x82   main.py\n\xe2\x94\x82   file1.py    \n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80folder1\n\xe2\x94\x82   \xe2\x94\x82   file2.py\n
Run Code Online (Sandbox Code Playgroud)\n

docker-action/有一个Dockerfile脚本entrypoint.sh,应该使用 Alpine(或 Python)的动态版本为内部容器运行

\n

docker-action/Dockerfile情况如下:

\n
# Container image that runs your code\nARG alpine_version\nFROM alpine:${alpine_version}\n\n# Copies your code file from your action repository to the filesystem path `/` of the container\nCOPY entrypoint.sh /entrypoint.sh\n\nRUN ["chmod", "+x", "/entrypoint.sh"]\n\n# Code file to execute when the docker container starts up (`entrypoint.sh`)\nENTRYPOINT ["/entrypoint.sh"]\n
Run Code Online (Sandbox Code Playgroud)\n

docker-action/entrypoint我运行ls但我没有看到存储库文件。

\n

是否可以访问main.pyfile1.pyfolder1/file2.pyin entrypoint.shdocker-action/entrypoint.sh

\n

syt*_*ech 11

通常有两种方法可以从存储库中获取可供您构建和运行的 Docker 容器使用的文件。您可以 (1) 在构建映像时将文件添加到映像中,或者 (2) 在运行映像时将文件装载到容器中。还有其他一些方法,例如指定卷,但这可能超出了本例的范围。

Dockerfiledocker-action/Dockerfile不会复制除entrypoint.sh脚本之外的任何文件。运行容器时,您entrypoint.sh也不提供任何安装点。因此,您观察到的结果是基于这些事实的预期结果。

为了解决此问题,您必须 (1)在 Dockerfile 中添加COPY/语句以将文件复制到映像中(并设置适当的构建上下文),或者 (2) 在容器运行时通过添加以下命令将文件安装到容器中:你的。ADD-v /source-path:/container-pathdocker runentrypoint.sh

参见参考资料:

不过,这种构建另一个容器只是为了获取用户提供的 python 版本的方法对于 GitHub Actions 来说是一种非常值得怀疑的做法,应该避免。考虑改用setup-python操作。

docker-in-docker 问题

不过,如果您继续此路线并想要挂载目录,则必须记住,当docker从 GitHub 上的 docker 操作中调用时,挂载规范中的文件系统指的是 docker 主机的文件系统,而不是容器的文件系统。

它可以在我的机器上运行吗?

例如,与您在本地系统上运行时可能遇到的情况相反docker,这在 GitHub 中不起作用——工作目录未安装:

docker run -v $(pwd):/opt/workspace \
           --workdir /opt/workspace \ 
           --entrypoint /bin/ls \
           my-container "-R"
Run Code Online (Sandbox Code Playgroud)

这也不起作用:

docker run -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE \
           --workdir $GITHUB_WORKSPACE \ 
           --entrypoint /bin/ls \
           my-container "-R"
Run Code Online (Sandbox Code Playgroud)

如果你在本地运行 docker 的系统上尝试的话,这种事情会工作得很好。是什么赋予了?

对付恶魔(守护进程)

在操作中,将文件检出到 的起始工作目录$GITHUB_WORKSPACE。在 docker actions 中,就是/github/workspace. 当操作运行器从运行 docker 守护程序的主机安装工作区时,工作区文件将填充到工作区中

您可以在操作开始时运行的命令中看到:

/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"
Run Code Online (Sandbox Code Playgroud)

重要的是:

-v "/home/runner/work/my-repo/my-repo":"/github/workspace" 
-v "/var/run/docker.sock":"/var/run/docker.sock"
Run Code Online (Sandbox Code Playgroud)

/home/runner/work/my-repo/my-repo是主机上存储库文件所在的路径。如前所述,第一行是/github/workspace在运行时将其安装到操作容器中的内容。

第二行是将 docker 套接字从主机安装到操作容器。这意味着每当您docker在操作中调用时,您实际上是在与容器外部的 docker 守护进程进行通信。这很重要,因为这意味着当您在操作使用-v参数时,参数需要反映容器外部存在的目录。

所以,你实际上需要做的是:

docker run -v $(pwd):/opt/workspace \
           --workdir /opt/workspace \ 
           --entrypoint /bin/ls \
           my-container "-R"
Run Code Online (Sandbox Code Playgroud)

成为对别人有用的人

那行得通。如果您仅将其用于项目本身。但是,如果您希望其他项目可以使用此操作,那么您(除其他外)还有一个遗留问题。您如何知道工作区在主机上的位置?毕竟,每个存储库的该路径都会改变。GitHub 也不保证这些路径。它们在不同平台上可能有所不同,或者您的操作可能在自托管运行器上运行。

那么你对这个问题满意吗?不幸的是,没有内置的环境变量指向您特别需要的这个目录。但是,通过依赖实现细节,您可能能够摆脱使用该$RUNNER_WORKSPACE变量的麻烦,在本例中该变量将指向/home/runner/work/your-project. 这与原点不在同一个地方$GITHUB_WORKSPACE,但也很接近。您可以使用GITHUB_REPOSITORY变量来构建路径,尽管不能保证始终如此:

docker run -v $GITHUB_WORKSPACE:$GITHUB_WORKSPACE \
           --workdir $GITHUB_WORKSPACE \ 
           --entrypoint /bin/ls \
           my-container "-R"
Run Code Online (Sandbox Code Playgroud)

您还需要修复一些其他问题,例如您构建的工作目录形式。

长话短说

运行时需要在容器中挂载文件。在 GitHub 中,您正在运行 docker-in-docker,因此用于挂载文件的路径会有所不同,因此您需要找到docker从操作容器内调用时要传递到的正确路径。

您链接的示例项目的最低工作解决方案是entrypoint.sh在存储库的根目录中,如下所示:

/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"
Run Code Online (Sandbox Code Playgroud)

您的操作可能还有更多问题,具体取决于它的作用,例如为“内部”容器提供该操作的所有默认和用户定义的环境变量(如果这很重要)。

那么,这可能吗?当然。仅仅获得 alpine/python 的动态版本是否合理?我不这么认为。可能有更好的方法来完成您想做的事情,例如使用setup-python,但这听起来像是一个不同的问题。