在参与多个项目的过程中,逐渐意识到DevOps和自动化的重要性。在之前的项目中,容器的构建和发布到DockerHub都是以日期作为标签。虽然这样不错,但很难区分哪些版本是“稳定”的,哪些版本是“进行中”的。
本文将介绍是如何为Docker项目构建一个持续集成和持续部署(CI/CD)解决方案的。所有的代码都托管在GitHub和Docker Hub上。分享旅程,希望其他人也能享受到这种自动化的便利,而不必花费周末的时间来构建它。
在构建完成后,将会有两个GitHub Actions来构建并发布应用程序的不同版本到DockerHub。
每当在GitHub上发布一个版本时,工作流就会被触发。它首先会检索“发布版本”,然后构建并标记容器,并最终发布(即推送)到Docker Hub。因为“发布”也是一个“稳定”版本,所以它也会更新容器标签latest。
让看看完整的YAML定义的GitHub Action,之后会详细解释。
name: Release Docker Image CI
on:
release:
types: [published]
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set outputs
id: vars
run: echo ::set-output name=RELEASE_VERSION::$(echo ${GITHUB_REF:10})
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: ${{ secrets.DOCKER_USER }}/cloudbot
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
tags: "latest,${{ steps.vars.outputs.RELEASE_VERSION }}"
为了限制工作流被触发的次数,使用了on: release和type: published,可以根据需要进行调整。
接下来有趣的部分是步骤vars中的几行。
- name: Set outputs
id: vars
run: echo ::set-output name=RELEASE_VERSION::$(echo ${GITHUB_REF:10})
在这里,使用环境变量GITHUB_REF(去掉前10个字符包含"refs/tags/")来初始化一个本地变量RELEASE_VERSION。该值可以从该步骤的输出中获取,就像YAML的最后一行一样。
tags: "latest,${{ steps.vars.outputs.RELEASE_VERSION }}"
从id为vars的步骤中,从outputs中检索了RELEASE_VERSION的值。
在这个GitHub Action中,使用了elgohr/Publish-Docker-Github-Action@master,因为它简单且满足需求。如果更喜欢,可以直接执行Docker命令,或者使用docker/github-actions。GitHub marketplace上有很多选项可供选择。
每次在GitHub上推送时,工作流都会被触发。它首先会检索最新发布的“发布版本”的草稿。工作流将发生-beta到检索到的版本,并使用这个来标记容器。最后,发布(即推送)到Docker Hub。
再次,这里是完整的YAML,之后会详细解释。
name: Build Docker Images
on:
- push
jobs:
build:
name: cloudbot-beta
runs-on: ubuntu-latest
steps:
- id: last_release
uses: InsonusK/get-latest-release@v1.0.1
with:
myToken: ${{ github.token }}
exclude_types: "release,prerelease"
view_top: 1
- uses: actions/checkout@v2
- name: Publish to Registry
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: ${{ secrets.DOCKER_USER }}/cloudbot
username: ${{ secrets.DOCKER_USER }}
password: ${{ secrets.DOCKER_PASSWORD }}
tags: "${{ steps.last_release.outputs.tag_name }}-beta"
这里的难点是想创建一个“未来”版本的标签。决定使用草稿发布,因为这些对所有人来说都是不可见的,因此它们看起来像是未来。
如果最后一个发布是版本1(v1.0),为了使这个工作流成为可能,需要创建一个新的发布并将其保存在草稿中。
就像在发布工作流中一样,需要检索版本。因为草稿只对某些人可见,所以需要获取访问权限。这可以通过使用github.token轻松完成。这些是在GitHub Action启动时自动创建的。
- id: last_release
uses: InsonusK/get-latest-release@v1.0.1
with:
myToken: ${{ github.token }}
exclude_types: "release,prerelease"
view_top: 1
这次在传递标签值时,将"-beta"附加到它上面。
tags: "${{ steps.last_release.outputs.tag_name }}-beta"