Github Actions是否可以在作业之间共享工作区/构件?

186

我试图使用Github的beta actions,有两个任务,一个构建代码,另一个部署代码。然而,在部署工作中似乎无法获取构建工件。

我最新的尝试是手动设置具有相同卷的容器映像,根据文档,这应该是解决方案:https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobsjob_idcontainervolumes

设置容器要使用的卷数组。您可以使用卷在服务或作业中的其他步骤之间共享数据。您可以指定命名的Docker卷、匿名的Docker卷或主机上的绑定挂载点。

工作流程

name: CI
on:
  push:
    branches:
    - master
    paths:
    - .github/workflows/server.yml
    - server/*
jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: docker://node:10
      volumes:
      - /workspace:/github/workspace
    steps:
    - uses: actions/checkout@master
    - run: yarn install
      working-directory: server
    - run: yarn build
      working-directory: server
    - run: yarn test
      working-directory: server
    - run: ls
      working-directory: server
  deploy:
    needs: build
    runs-on: ubuntu-latest
    container:
      image: docker://google/cloud-sdk:latest
      volumes:
      - /workspace:/github/workspace
    steps:
      - uses: actions/checkout@master
      - run: ls
        working-directory: server
      - run: gcloud --version
第一个工作(build)有一个构建目录,但当第二个工作(deploy)运行时它没有,只包含源代码。 这个项目是一个单一的版本库,我正在尝试部署的代码位于路径server下,因此所有的working-directory标志。

4
请参考 https://dev59.com/YrXna4cB1Zd3GeqPPrvg。[Workflow syntax docs](https://help.github.com/en/articles/workflow-syntax-for-github-actions#jobs)中写道:“每个作业在由runs-on指定的新虚拟环境实例中运行。” 我的猜测(我不在beta中,只是猜测)是您的deploy作业要么需要成为build作业中的一个步骤,要么需要在新容器中再次复制build步骤(也许除了yarn test步骤,因为您已经知道它成功了)。 - rmunn
2
你有没有找到这个问题的答案?我也在尝试弄清楚如何做这件事...从我所读的内容来看,工作应该共享工作区文件系统,但似乎并非如此。 - Joseph
1
@Joseph 不是的,我只运行一个作业并使用自定义的Docker镜像。我相信问题出在GitHub上,很可能是由于从HCL语法过渡到YML语法。奇怪的是,他们计划在九月底放弃HCL,但基本的在作业之间共享工件的能力还没有实现。希望在一个月的时间里,这个问题会得到解决。 - Labithiotis
您可以使用卷共享服务或作业中其他步骤之间的数据。这意味着在单个作业的步骤之间共享数据,而不是用于在步骤或工作流之间共享数据。 - thisismydesign
1
三年五个月过去了,仍然无法在不使用工件或缓存的情况下实现这一点。 如果您能看到这条消息,GitHub,一个简单的关键字after: <job_id>将是惊人的。 - Eduardo Pignatelli
Github Actions是我本周的烦恼源,我不相信他们有意为人类创建它。最有趣的事情是,我们可以找到许多美丽的工作流程图像,但没有实现这样的管道的真正示例,而不使用ducktape。 - ZuzEL
5个回答

160
您可以使用Github Actions的upload-artifact和download-artifact来在作业之间共享数据。 在作业1中:
steps:
- uses: actions/checkout@v1

- run: mkdir -p path/to/artifact

- run: echo hello > path/to/artifact/world.txt

- uses: actions/upload-artifact@master
  with:
    name: my-artifact
    path: path/to/artifact

还有工作2:

steps:
- uses: actions/checkout@master

- uses: actions/download-artifact@master
  with:
    name: my-artifact
    path: path/to/artifact
    
- run: cat path/to/artifact/world.txt

https://github.com/actions/upload-artifact
https://github.com/actions/download-artifact


3
现在你也可以删除工件: https://github.com/marketplace/actions/delete-run-artifacts https://github.com/marketplace/actions/purge-artifacts - Chris
@qmacro 我想做类似这样的事情,但我想构建一个 Docker 镜像,然后在接下来的作业的 services 中使用它,而不是在 steps 中使用。不知道这是否可能,因为只有在启动 services 后才会进行工件下载。有什么建议吗? - Robert P. Goldman
1
虽然这确实是一个选项,但对于任何严重的事情(想象一下共享50个docker映像),使用这种方法需要几十分钟。由于GitHub没有提供适当的解决方案,我们转向CircleCI,至少可以将构建时间缩短1小时。不拥有这样的选项真的非常奇怪。 - Eugene
第二个任务中步骤的顺序非常重要。checkout 操作会删除一切 :) - Anton Krosnev

40

如果您想在两个作业之间共享Docker镜像,以下是我的做法:

jobs:
  docker-build:
    name: Docker build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Build Docker image
        run: |
          docker build -t foo/bar:$GITHUB_SHA
          mkdir -p path/to/artifacts
          docker save foo/bar:$GITHUB_SHA > path/to/artifacts/docker-image.tar
          
      - name: Temporarily save Docker image
        uses: actions/upload-artifact@v2
        with:
          name: docker-artifact
          path: path/to/artifacts
          retention-days: 1

  docker-deploy:
    name: Deploy to Docker Hub
    runs-on: ubuntu-latest
    needs: docker-build
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Retrieve saved Docker image
        uses: actions/download-artifact@v2
        with:
          name: docker-artifact
          path: path/to/artifacts

      - name: Docker load
        run: |
          cd path/to/artifacts
          docker load < docker-image.tar
          # docker_build_push.sh

受到https://github.com/unfor19/install-aws-cli-action/actions/runs/400601222/workflow的启发,非常感谢@unfor19。


1
对于任何人来说,如果你正在寻找如何避免在 GitHub 上混乱你的构件,因为 GitHub 没有提供相应的操作:有几个社区操作,例如 https://github.com/marketplace/actions/delete-artifact。 - Alan Plum
4
@AlanPlum 说得好。我们现在使用参数 retention-days 来清除工件。我会更新我的回答。谢谢。 - Thomas
这确实是一个选项,但如果你有很多图片,这将是一个非常痛苦和缓慢的选项。其他CI/CD框架默认具备此功能,但Github没有。 - Eugene
1
retention-days 是关键!否则 Github 会浪费你的钱。 - orkenstein

25

使用缓存或工件上传/下载

缓存用于在作业或工作流之间重复使用数据/文件,而工件用于保存工作流结束后的文件。


23
如果您使用上传/下载GitHub Actions,请注意artifact的结构。
从2020年1月开始,请参阅“GitHub Actions: Changes to artifact download experience”。

We have changed the artifact download experience in GitHub Actions so it no longer adds an extra root directory to the downloaded archive.

Previously, if you uploaded the following files and folders as an artifact named foo, the downloaded archive would contain the following structure:

foo/
 |-- file1.txt
 |-- dir1/
 |    |-- dir1-file1.txt

Now, you will get an archive that only contains the files and folders you uploaded:

file1.txt
dir1/
|-- dir1-file1.txt

1
每个作业在单独的运行器上运行。 上传工件操作实现 Github Action "actions/upload-artifact@v3" 将提供路径中的文件上传到存储容器位置。
在下一个作业中,当您运行动作 "actions/download-artifact@v3" 时,它会从“存储容器位置”下载工件,其中前一个作业将工件上传到提供的路径。 下载工件并显示下载路径的实现 有关更多信息,请参考以下链接, Github 上传工件的操作 Github 下载工件的操作

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接