Github 操作在作业之间共享工作区/工件?

Posted

技术标签:

【中文标题】Github 操作在作业之间共享工作区/工件?【英文标题】:Github actions share workspace/artifacts between jobs? 【发布时间】:2019-12-21 05:48:13 【问题描述】:

尝试使用 Github 的 beta 操作,我有两份工作,一份负责构建代码,另一份负责部署代码。但是,我似乎无法在部署作业中获得构建工件。

我最近的尝试是为每个作业手动设置具有相同卷的容器映像,根据文档,这应该是解决方案: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) 有一个 build 目录,但是当第二个作业 (deploy) 运行时它没有并且只包含源代码。

这个项目是一个单声道存储库,我尝试部署的代码位于路径 server 下,因此所有 working-directory 标志。

【问题讨论】:

参见 ***.com/questions/57509118/… - Workflow syntax docs 说“每个作业都在由 runs-on 指定的虚拟环境的新实例中运行。”我的猜测(我不在测试版中,所以我只是在猜测)是您的部署工作要么需要成为 build 工作中的一个步骤,要么需要在新的工作中再次重现 build 步骤容器。 (也许减去yarn test 步骤,因为您已经知道它成功了)。 你找到答案了吗?我也在试图弄清楚如何做到这一点。从我读过的内容来看,作业应该共享工作区文件系统,但似乎并非如此。 @Joseph 不,我只是在运行一项工作并使用自定义 docker 映像。我相信问题出在 GitHub 上,很可能是由于从 HCL 到 YML 语法的转换。奇怪的是,他们计划在 9 月底放弃 HCL,而在工作之间共享人工制品的基本能力还没有起作用。希望在一个月内,它会得到解决。 “您可以使用卷在服务或作业中的其他步骤之间共享数据。”这意味着在步骤之间共享单个作业中的数据。它不适用于在步骤或工作流之间共享数据。 【参考方案1】:

您可以使用 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-artifacthttps://github.com/actions/download-artifact

【讨论】:

您现在还可以删除工件:github.com/marketplace/actions/delete-run-artifactsgithub.com/marketplace/actions/purge-artifacts @qmacro 我想做这样的事情,但我想构建一个 Docker 映像,我将在后续工作中使用它的services 而不是它的steps。看不出这是怎么可能的,因为只有在services 启动之后 才会完成工件下载。有什么建议吗?【参考方案2】:

如果您使用上传/下载 GitHub Actions,请注意工件的结构。

从 2020 年 1 月开始,请参阅“GitHub Actions: Changes to artifact download experience”:

我们更改了 GitHub Actions 中的工件下载体验,因此它不再向下载的存档添加额外的根目录

之前,如果您将以下文件和文件夹作为名为 foo 的工件上传,则下载的存档将包含以下结构:

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

现在,您将获得一个仅包含您上传的文件和文件夹的存档:

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

【讨论】:

【参考方案3】:

对于那些有兴趣在两个作业之间共享 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

【讨论】:

对于任何遇到此问题并想知道如何避免弄乱您的工件的人,因为 github 没有为此提供操作:有几个社区操作,例如github.com/marketplace/actions/delete-artifact @AlanPlum 说得好。我们现在使用参数retention-days 清理工件。我会更新我的答案。谢谢。【参考方案4】:

使用Cache or Artifacts Upload/Download

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

【讨论】:

以上是关于Github 操作在作业之间共享工作区/工件?的主要内容,如果未能解决你的问题,请参考以下文章

Jenkins QA部署

洛谷P1065 作业调度方案

NOIP2006作业调度方案 {语文难题}

Github 操作将 java 工件推送到 github repo

[NOIP2006] 提高组 洛谷P1065 作业调度方案

该作业依赖于具有过期/已擦除工件的其他作业