问题描述
GitHub Actions 是 GitHub 的持续集成服务,类似与 Jenkins、Travis CI、GOCD 等等工具,都是为了完成自动化任务。于 2018 年 10 月推出,正式版于 2019 年 11 月正式推出。
最近(04/09/2021)还火了一把:黑客用 GitHub Action 服务器挖矿,三天跑了 3 万个任务,代码惊现中文……啊哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
该笔记将记录:如何使用 GitHub Actions 服务来构建自己的应用,以及常见问题处理。
解决方案
快速入门
1)在项目目录中,创建 .github/workflows/example.yml 文件。
2)并将如下内容写入 example.yaml 文件(如下为官方示例,同时我们也进行简单补充):
name: learn-github-actions on: [push] jobs: check-bats-version: runs-on: ubuntu-latest steps: # 拉取代码(GitHub Action 不会自动拉取仓库代码,因此基本每个 Workflow 中都有该 Action) - uses: actions/checkout@v2 # 安装 NodeJS 环境(其他 Action 可以参考 Actions Marketplace 页面) - uses: actions/setup-node@v1 - run: npm install -g bats - run: bats -v
3)最后提交代码,然后就能够在仓库主页的 Actions 中看到 CI 的执行过程。
解释说明
1)runs-on: ubuntu-latest,表示使用 GitHub 提供的 ubuntu-latest 主机。目前(02/02/2021)指向 18.04 TLS 版本,预装 Docker-Moby 19.03.14、Pip3 9.0.1、Docker Compose 1.27.4、jq 1.5 等等很多应用。在安装必要应用前,建议阅读官方文档(参考 virtual-environments/Ubuntu1804-README.md at main 文档),因为多数常见应用已预装,无需我们再次安装。
2)指令 run 与 uses 不能出现在同个字典中,否则提示 a step cannot have both the `uses` and `run` keys 错误。
# 这是错误的写法 - uses: actions/checkout@v2 run: npm install -g bats
相关文档
快速入门,参考文档:Introduction to GitHub Actions – GitHub Docs(该文档足够用于快速入门)
全部指令,参考官方:Workflow syntax for GitHub Actions – GitHub Docs
Actions Marketplace:GitHub Marketplace · Actions to improve your workflow
定义 Job 执行顺序(依赖)
私密(Secret)信息管理,参考 Encrypted secrets – GitHub Docs 文档。如下为学习笔记:
功能说明
敏感信息可以保存在 Organization, Repository, Repository Environments 中。
在 Organization 中,定义 Secret 可以用于所有 Repository,还可以通过访问控制来允许特定 Repository 访问 Organization 的 Secret。
在 Repository 中,创建的 Secret 仅能在当前仓库中中使用。
在 Repository Environments 中,可以允许要求的 Reviewer 访问 Secret。但是,无法在 Workflow 的 Job 中使用,要经过同义后才能使用。
对于同名的 Secret,最低级的优先级最高,即:Repository Environments > Repository > Organization
创建 Secret 信息
如何在 GitHub 中创建,参考 Creating encrypted secrets for xxxx 文档,该已经文档描述如何在 Organization, Repository, Repository Environments 中创建 Secret 信息。
使用 Secret 信息
在 Workflow 中,可以如下方式引用 Secret 信息:
steps: - shell: bash env: SUPER_SECRET: ${{ secrets.SuperSecret }} run: | example-command "$SUPER_SECRET" - name: Hello world action with: # Set the secret as an input super_secret: ${{ secrets.SuperSecret }} env: # Or as an environment variable super_secret: ${{ secrets.SuperSecret }}
更多的使用方法,参考 Using encrypted secrets in a workflow 文档。
注意事项
1)官方不建议在 Secret 中使用结构化数据,比如 JSON,这是为了确保 GitHub 处理日志中的私密信息。
添加 Runner 主机
问题描述
最开始,我们使用 GitHub Action 提供的免费主机,来完成构建任务。但是,默认的 Linux 主机每月仅有 3000 分钟,这对于我们来说是不够的,我们需要完成更多的构建任务。
好在 GitHub Action 允许添加自己的主机。因此,我们能够将自己的主机作为 GitHub Action 节点,来完成构建任务。
该部分笔记将记录:如何完成该设置,以及常见问题处理方法(参考 About self-hosted runners – GitHub Docs 文档)。
解决方案
1)我们使用组织仓库,需要在组织内的项目能够使用该节点进行构建。因此:Organization => Settings => Actions => Self-hosted runners => Add new
2)此时,会显示添加 Runner 的命令,按照要求执行即可。注意,不能使用 Root 用户运行,否则提示 Must not run with sudo 信息;
3)然后,在 <workflow>.yml 中,通过 runs-on: [self-hosted, linux, ARM64] 来选择节点。
如果遇到 No runner matching the specified labels was found: self-hosted. 错误,则为如下原因:
1)通过 runs-on 标签,未能找到匹配的主机
2)受到设置的限制,某些仓库无法在该 Runner 中执行构建。需要进行如下设置:
服务开机自启动(Configuring the self-hosted runner application as a service – GitHub Docs):
1)sudo ./svc.sh install ,这将创建 .service 文件,该服务会以运行 sudo 的用户运行。
2)我们场景特殊:执行 CI 的 B 用户不能执行 sudo 命令,因此我们使用能够 sudo 的 A 用户导致 .service 文件将以 A 用户运行。因此需要修改 .service 文件:
# systemctl edit "actions.runner.<your node name>.service" [Service] User=user-b # systemctl daemon-realod # systemctl restart "actions.runner.<your node name>.service"
我们的 Workflow 脚本(仅供参考)
我们的需求比较简单:
1)在特定分支构建 Docker 镜像,并推送 DockerHub 仓库;
2)此外,我们使用 Docker Buildx 来构建多架构镜像;
下面是我们使用的 Workflow 脚本:
name: Build Docker Images on: push: branches: - master - main - 'v*' jobs: build: runs-on: [self-hosted, Linux] defaults: run: shell: bash steps: - name: "Checking out code" uses: actions/checkout@v2 with: submodules: recursive - name: "Login to DockerHub" uses: docker/login-action@v1 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: "Set up QEMU" uses: docker/setup-qemu-action@v1 with: image: tonistiigi/binfmt:master - name: "Set up Docker Buildx" uses: docker/setup-buildx-action@v1 - name: "Building docker images" run: | image="k4nzdroid/$(basename ${GITHUB_REPOSITORY})" tag=${GITHUB_REF#refs/heads/} if [ "$tag" = 'master' || "$tag" = 'main' ]; then tag=lable fi docker buildx build \ --output "type=image,push=true" \ --file "Dockerfile" \ --tag "${image}:${tag}" \ --platform "linux/amd64" \ "."
参考文献
博客园/你知道什么是 GitHub Action 么?
GitHub Actions 入门教程
virtual-environments/Ubuntu1804-README.md at main · actions/virtual-environments
Encrypted secrets – GitHub Docs
Adding self-hosted runners – GitHub Docs
Self-hosted runners are not visible to GitHub Actions workflows in public repositories by default: “No runner matching the specified labels was found:” – Code to Cloud / GitHub Actions – GitHub Support Community
Workflow syntax for GitHub Actions – GitHub Docs