GitHub Actions 简单使用

GitHub Actions 是什么

官方文档 是这么介绍的

在 GitHub Actions 的仓库中自动化、自定义和执行软件开发工作流程。 您可以发现、创建和共享操作以执行您喜欢的任何作业(包括 CI/CD),并将操作合并到完全自定义的工作流程中。

我的理解

可以理解为一个有条件(比如push事件,也可以是 cron 表达式定义的一个定时任务)触发的工作流任务。而这个工作流任务是可以由我们开发者自定义的,执行这些任务的环境由 GitHub 提供,一般是 ubuntu 环境。通过这个环境,我们可以执行一些自定义脚本,亦或是调用其他开发者发布的插件来实现一些开发者想要的功能

GitHub Actions 可以做什么

传统 CI/CD 能做的编译,打包,发布,使用 GitHub Actions 肯定也是能实现的

这里,我想使用两个我自己的案例来演示说明,我使用 GitHub Actions 做了些什么

  1. 个人博客编译,打包,发布
  2. 作为拉取 docker-hub 官方镜像的中转工具

前置准备工作

如何自定义工作流任务

只需要在仓库存在 .github/workflows/*.yml,在满足触发条件之后,就会被自动执行

这个配置文件可以有多个,执行的时候是并行的,但也可以定义工作流的依赖关系实现串行化

关于执行环境

可以自定义选择 Linux,Windows 和 macOS,具体的版本可以访问这里查看

Linux 环境已经自带了 Docker 环境,无需重复安装

关于插件

GitHub Actions 的插件分为官方和非官方的,其中官方的插件地址都是 https://github.com/actions 开头的

比如检出仓库代码的插件 checkout

比如第三方部署到 GitHub Pages 的插件 peaceiris/actions-gh-pages

可以在 GitHub 市场 中寻找符合自己需求的插件

个人博客编译,打包,发布

.github/workflows/deploy.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
name: Deploy My Hexo Blog

on:
push:
branches:
- main

jobs:
build:
runs-on: ubuntu-latest
# 权限控制
permissions:
contents: read
pages: write
id-token: write
steps:
# 检出仓库代码
- name: Checkout Repository
uses: actions/checkout@v4

# 设置 Node.js 版本
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.9.0'

# 缓存 npm 依赖
- name: Cache npm dependencies
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-v2
restore-keys: |
${{ runner.os }}-node-

# 安装 Hexo CLI
- name: Install Hexo CLI
run: npm install hexo-cli -g

# 安装 npm 依赖
- name: Install npm dependencies
run: |
npm install --prefix themes/icarus
npm install

# 生成静态文件
- name: Generate static files
run: |
hexo clean
hexo g

# 部署到云服务器
- name: Deploy to Cloud Server
uses: easingthemes/ssh-deploy@main
with:
SSH_PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
ARGS: "-avz --delete"
SOURCE: ${{ secrets.SOURCE }}
REMOTE_HOST: ${{ secrets.HOST }}
REMOTE_PORT: ${{ secrets.PORT }}
REMOTE_USER: ${{ secrets.USER }}
TARGET: ${{ secrets.TARGET }}

# 部署到 wuhunyu.github.io
- name: Deploy to Github Pages
uses: peaceiris/actions-gh-pages@v4
with:
personal_token: ${{ secrets.ACCESS_TOKEN }}
external_repository: ${{ secrets.PAGE_REPO }}
publish_branch: ${{ secrets.PAGE_BRAN }}
publish_dir: ${{ secrets.SOURCE }}
commit_message: ${{ github.event.head_commit.message }}

简单说明一下这个 actions 的内容

  1. actions 的名称是 Deploy My Hexo Blog
  2. 当仓库的 main 分支有 push 事件发生时自动触发
  3. 工作流的执行环境是 ubuntu-latest
  4. 其次是关于权限控制的说明
  5. 最后按 steps 的声明顺序,任务会被依次执行,如果中途出现了错误,则会直接中断后续的任务。每个任务的作用在注释中已经写了,就不再多说明了。值得注意的是,其中有 ${{ }} 的符号,这是从当前上下文取值的占位符,其中 secrets 是由开发者自定义的环境变量,具体可以在每个仓库的 settings/secrets/actions 进行设置

image-20240630185544912

action 运行的控制台像这样,按执行顺序列出了每个任务的日志

image-20240630185756456

作为拉取 docker-hub 官方镜像的中转工具

前些天在掘金上看到了有人已经实现了,功能要比我这个更加健壮,地址如下

docker_image_pusher

下面展示的这个工具是我个人使用,每次拉取镜像也不会太大,像是磁盘不够的情况暂时还不需要考虑

.github/workflows/docker-hub.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
name: Pull and Push Docker Images
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# 检出仓库代码
- name: Checkout Repository
uses: actions/checkout@v4

# 安装 jq 以处理 JSON 文件
- name: Install jq
run: sudo apt-get install -y jq

# 登录到阿里云容器镜像服务
- name: Log in to Alibaba Cloud Registry
run: echo "${{ secrets.ALIYUN_REGISTRY_PASSWORD }}" | docker login -u "${{ secrets.ALIYUN_REGISTRY_USERNAME }}" registry.cn-guangzhou.aliyuncs.com --password-stdin

# 拉取和推送 Docker 镜像
- name: Pull and Push Docker images
env:
ALIYUN_NAMESPACE: ${{ secrets.ALIYUN_REGISTRY_NAMESPACE }}
run: |
for image in $(jq -r '.[]' images.json); do
echo "Processing image: ${image}"
docker pull ${image}
aliyun_image="registry.cn-guangzhou.aliyuncs.com/${{ env.ALIYUN_NAMESPACE }}/${image##*/}"
docker tag ${image} $aliyun_image
docker push ${aliyun_image}
done
  1. 同样也是当仓库的 main 分支有 push 事件发生时自动触发

  2. 之后登陆阿里云的 docker hub 镜像

  3. 读取仓库中的 images.json 配置文件,形如

1
2
3
4
[
"redis",
"nginx:latest"
]
  1. 在容器内 pull 镜像之后再 push 给阿里云的 docker hub

    • 这里利用 actions 的容器可访问外网的能力将 docker 镜像中转到内网可访问的镜像站

其他

除了以上两个案例,GitHub 有一个叫 Releases 的概念,也可以借由 GitHub Actions 来打包

.github/workflows/buildAndRelease.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
name: Build And Release

on:
push:
tags:
- 'v*.*.*'

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Set Up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'adopt'

- name: Build with Maven
run: mvn clean package -DskipTests

- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: Upload JAR to Release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ${{ secrets.ASSET_PATH }}
asset_name: ${{ secrets.ASSET_NAME }}
asset_content_type: application/java-archive

Releases 基于 tag,所以需要 actions 的触发条件可以设置为 tag 被 push 时

效果如下

image-20240630220015641

总结

  1. GitHub Actions 是 GitHub 免费开放给开发者的自动化工作流
  2. 基于 GitHub Actions,可以解放部分项目本地编译,部署的服务器资源。我借用这个功能实现了几个小功能,包括个人博客的编译部署,docker hub 镜像中转工具

最后

如果借用 GitHub Actions 的容器资源来做爬虫节点是不是也挺好,官方给的服务器资源配置也还不错,可以查看这个

image-20240630221848905

引用资源

GitHub Actions 文档

用于公共存储库的 GitHub 托管的标准运行器

checkout

peaceiris/actions-gh-pages

GitHub 市场

docker-hub

docker_image_pusher

starter

作者

wuhunyu

发布于

2024-06-30

更新于

2024-09-05

许可协议