0%

github actions 简单使用

快速开始

如果你是一个前端项目,可以使用 Node.js 的模板,点击 Set up this workflow

v2-93f521330d963d903561c0575d2d8fac_720w

此时生成了一个文件 .github/workflows/nodejs.yaml,修改内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
name: Git Action Test
# on: 用来指定启动触发的事件,push 则表示在监听到 git push 到指定分支时触发。如此之外还可以是 pull_request。
on: [push]

#jobs:一个 CI/CD 的工作流有许多 jobs 组成,比如最典型的 job 是 lint,test,build 或者 deploy。
#所有的 job 都是并行的,如果想顺序执行,可以这样 build-job: needs: test-job。
jobs:
build:
#runs-on用来指定执行系统环境,不仅有常用的 Linux 发行版,还可以是 macOS 或 Windows。
runs-on: ubuntu-latest
# steps 表示每个 job 需要执行的步骤,比如这里我分成了四步:拉取分支 → 安装 Node 环境 → 构建项目 → 上传 COS。
steps:
#Action 是组成工作流最核心最基础的元素。每个 Action 可以看作封装的独立脚本,有自己的操作逻辑,我们只需要 uses 并通过 with 传入参数即可。
- uses: actions/checkout@v1
- name: Use Node.js 10.x
uses: actions/setup-node@v1
with:
node-version: 10.x
- name: npm install, build
run: |
npm install
npm run build --if-present
env:
CI: true

执行 git push 操作,此时可以在 githubActions 标签页看到执行结果

安全相关

如何在 github action 上访问敏感数据?如使用 ssh 登录时如何维护密码。

我们可以在 github repo 上依次点击 Settings -> Secrets 设置 secret

v2-51c0ee11b4bc61312d8e1af14d906432_720w

1
2
3
4
5
6
- name: setup aliyun oss
uses: manyuanrong/setup-ossutil@master
with:
endpoint: oss-cn-beijing.aliyuncs.com
access-key-id: ${{ secrets.OSS_KEY_ID }}
access-key-secret: ${{ secrets.OSS_KEY_SECRET }}

这里的 secret 就是一种 context,描述 CI/CD 一个 workflow 中的上下文信息,使用 $ 语法表示。除了 secret,还有

  • github: workflow 的信息,如 github.sha 可以获取当前的 commit SHA,我们可以利用它为 sentry 或者 docker image 打入版本号
  • env: 环境变量
  • job: 当前执行 job 的信息,如 job.status 表示当前 job 的执行状态
  • matrix: 描述一些构建信息,如 node 以及 os 版本号

更多 context 信息可以参考官方文档 Contexts and expression syntax for GitHub Actions[4]

自动创建项目Release

有些项目在发布新版本时,一般都会创建一个Github Release,并且把对应编译好之后的文件上传到Release的资源列表中,例如:
2659679572-62492fa02f19b6f9

如果这个使用手动操作的话,不仅步骤重复又繁琐(每次都要编译出各个操作系统对应的发行包再进行上传),而且最蛋疼的是对于国内的网络环境来说,上传文件速度简直不能忍,好不容易上传了一大半搞不好就因为网络原因又要重新上传,相信用过的人都深有体会。

我就在想如果能用Github Actions来创建Release,并且做对应的编译和上传,那上面的问题都可以迎刃而解了,于是在官方市场搜索了一下Release关键字,果然已经有提供对应的actions了:

接着创建一个Github仓库,我测试的仓库地址是https://github.com/monkeyWie/github-actions-demo,项目用 go 语言写的,代码非常简单就是两个 hello world 级别的代码,里面包含了普通的 go 程序和 cgo 程序。

项目的构建流程是在项目git push --tags的时候,触发 workflow,通过Github Actions编译出来Windows、Linux、macOS三个操作系统对应的 64 位可执行文件,再根据tag nametag message来创建对应的Github Release,并将编译好的文件上传。

同样的创建一个.github/workflows/main.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
name: CI

on:
push:
# Sequence of patterns matched against refs/tags
tags:
- "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout source
uses: actions/checkout@v1
- name: Use Golang
uses: actions/setup-go@v1
with:
go-version: "1.13.x"
- name: Build normal
run: |
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o normal-windows-x64.exe cmd/normal/main.go
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o normal-linux-x64 cmd/normal/main.go
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o normal-darwin-x64 cmd/normal/main.go
zip normal-windows-x64.zip normal-windows-x64.exe
zip normal-linux-x64.zip normal-linux-x64
zip normal-darwin-x64.zip normal-darwin-x64
- name: Build cgo
run: |
go get github.com/monkeyWie/xgo
~/go/bin/xgo -targets=windows/amd64,linux/amd64,darwin/amd64 -ldflags="-w -s" -pkg=cmd/cgo/main.go -out=cgo .
mv cgo-windows-* cgo-windows-x64.exe
mv cgo-linux-* cgo-linux-x64
mv cgo-darwin-* cgo-darwin-x64
zip cgo-windows-x64.zip cgo-windows-x64.exe
zip cgo-linux-x64.zip cgo-linux-x64
zip cgo-darwin-x64.zip cgo-darwin-x64
- name: Create Release
id: create_release
uses: monkeyWie/create-release@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
draft: false
prerelease: false

- name: Upload Release normal windows
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./normal-windows-x64.zip
asset_name: normal-${{ steps.create_release.outputs.tag }}-windows-x64.zip
asset_content_type: application/zip
- name: Upload Release normal linux
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./normal-linux-x64.zip
asset_name: normal-${{ steps.create_release.outputs.tag }}-linux-x64.zip
asset_content_type: application/zip
- name: Upload Release normal darwin
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./normal-darwin-x64.zip
asset_name: normal-${{ steps.create_release.outputs.tag }}-darwin-x64.zip
asset_content_type: application/zip

- name: Upload Release cgo windows
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./cgo-windows-x64.zip
asset_name: cgo-${{ steps.create_release.outputs.tag }}-windows-x64.zip
asset_content_type: application/zip
- name: Upload Release cgo linux
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./cgo-linux-x64.zip
asset_name: cgo-${{ steps.create_release.outputs.tag }}-linux-x64.zip
asset_content_type: application/zip
- name: Upload Release cgo darwin
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
asset_path: ./cgo-darwin-x64.zip
asset_name: cgo-${{ steps.create_release.outputs.tag }}-darwin-x64.zip
asset_content_type: application/zip

构建流程如下:

  1. 监听 tag name 为v开头的 push
  2. 运行一个 job,在ubuntu虚拟机环境下
  3. 拉取源码,安装golang 1.13.x环境
  4. 使用go build交叉编译出不同操作系统下 64 位可执行文件,并使用 zip 压缩
  5. 使用xgo交叉编译出不同操作系统下 64 位可执行文件,并使用 zip 压缩
  6. 使用monkeyWie/create-release@master创建 Release,其中会用到$,这是Github Actions内置的一个秘钥,用于授权访问你自己的 github 存储库,原理就是使用这个TOKEN调用Github API来进行创建 release,还有一个$也是Github Actions内置的一个变量,然后通过 action 的with进行参数传递。
  7. 使用actions/upload-release-asset@v1.0.1上传文件,这里使用了两个表达式$$,可以获取到指定action的输出,第一个是获取创建好的 release 对应的上传地址,第二个是获取对应的 tag(例如:v1.0.0),这样就可以在把上传的文件带上版本号。因为这个action不支持多个文件上传,所以就写了多个 action 进行上传。

ssh命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
name: Publish
on: [push]
jobs:
build:
name: SSH command
runs-on: ubuntu-latest
steps:
- name: git fetch
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USERNAME }}
password: ${{ secrets.SERVER_PASSWORD }}
command_timeout: 10m
script: |
git fetch --all
git reset --hard origin/master
build:
name: ...
runs-on: ...
...

市场

https://github.com/marketplace

https://docs.github.com/cn/actions/configuring-and-managing-workflows/using-environment-variables