DevOps架构师是如何看待Github Actions的共享制品解决方案的?
前言 Github Actions是Github提供的一个CICD Pipeline服务。除了Pipeline,它还提供Secret和简单的配置管理。 本文并不是它的一个完整介绍和知识的罗列。而是我在实际使用Github Actions后,对Github Actions的“共享问题”的解决方案的总结。 不要小看这个问题,它是所有的Pipeline平台(包括Gitlab CI)都会遇到的问题。只要对这一问题深入理解,所有的平台一通百通。 提示1:下文可能会是Workflows和Pipeline两个术语共用。因为它们本质上就是同一个东西,只是不同平台不同的叫法。 提示2:下文可能会共用DevOps平台和Pipeline平台,虽然它们可能是完全不同的平台,但是在本文中,它们都是能提供Pipeline的平台。 共享问题 只要是Pipeline平台,都会遇到共享问题。那么,什么是共享问题? 共享问题就是Pipeline中不同的位置之间共享资源,以实现不重复执行、生成准确结果的目标。 定义听起来有些枯燥。我们列举一个有共享的场景,就比较好理解了: 比如对于一个单仓库,它同时包含多个前端工程,这些前端工程同时依赖于一个common模板。其它前端工程只有等它构建完成,并取得构建,才能开始自己的构建。如果common模板的构建结果不能被其它工程构建共享使用,就会存在构建结果不一致、重复构建的问题; 比如一个Pipeline中,版本号是有特定格式的,需要在第一步骤计算出来后,其它步骤取得这个版本号,进行打包工作。如果没有实现版本号在多个步骤之间共享,很可能会导致版本号不一致问题。 我们稍微对共享问题进行抽象和理解,根据共享的范围,共享问题,可以分为: Workflows之间进行共享; Workflow内的Jobs之间进行共享; Job内的Step之间进行共享。 根据共享的内容,可以分为: 共享源码; 共享制品; 共享变量。 Github Actionsr制品的定义 在Github Actions中的制品(Artifact)的概念和我们平时所说的“制品”有一定的区别。在Github Actions中,制品指的是Job生成的文件或者文件夹。 我们平时所说的,更广意的“制品”,在Github Actions叫Packages。 Workflows之间的共享制品 一般只有在大型项目才会存在Workflows之间的共享。而我个人是不建议将依赖Pipeline实现大型项目的构建的,而是依赖构建工具本身的能力。 由于笔者时间有限,不再亲身做实验,本节内容,请读者自行测试。 如果Workflow是由workflow_run事件触发的情况下,它们就可以直接使用actions/upload-artifact和actions/download-artifact两个actions来实现制品的共享。相关文档:https://docs.github.com/en/actions/using-workflows/storing-workflow-data-as-artifacts#downloading-artifacts-during-a-workflow-run 有趣的是Github Actions提供了一种reusable的Workflow概念。说到底是一种模板化Workflow的方式。但是这种方式不适合用来实现共享制品。因为它并不是共享制品。相关文档:https://docs.github.com/en/actions/using-workflows/reusing-workflows#using-outputs-from-a-reusable-workflow Jobs之间共享制品 在同一个Workflow中,多个Job进行制品共享。如下代码: jobs: // 生成制品的job build: runs-on: ubuntu-latest steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Build and export uses: docker/build-push-action@v5 with: context: . tags: myimage:latest outputs: type=docker,dest=/tmp/myimage.tar - name: Upload artifact uses: actions/upload-artifact@v3 with: name: myimage path: /tmp/myimage.tar // 使用制品的job use: runs-on: ubuntu-latest needs: build steps: - name: Download artifact uses: actions/download-artifact@v3 with: name: myimage path: /tmp - name: Load image run: | docker load --input /tmp/myimage.tar docker image ls -a 以上案例来自:https://docs.docker.com/build/ci/github-actions/share-image-jobs/ ...