Github Actions是 github 官方推出的一款 CI(持续集成)工具,目前还处于Beta
版本,须要申请内测资格才能使用,申请成功以后在本身的代码仓库就能够看到Actions
了。node
这里简单介绍下 Github Actions
中的概念,具体能够参考官方文档。linux
每一个 job 均可以指定对应的操做系统,支持Windows、Linux、macOS
,github 会提供一个虚拟机来执行对应的 job。git
硬件规格:github
使用限制:golang
能够看到这个配置下,普通的项目持续集成确定没什么问题的。docker
经过仓库中的Actions
选项卡,能够看到项目中的 workflow 构建记录:express
点击一条记录能够进入详情页面,能够实时
查看每个action
的控制台输出,方便调试:npm
前面大概介绍了一下基本的概念,下面就直接经过几个实例看看 Github Actions
是如何使用的。ubuntu
首先第一个想到能用到Github Actions
的就是个人博客了,项目托管在https://github.com/monkeyWie/monkeywie.github.io,目前项目有两个分支,master
分支用于存放 hexo 编译以后的静态文件,另外一个hexo
分支用于存放 hexo 项目环境和 markdown 文章,master
分支经过Github Page
配置以后能够经过monkeywie.github.io
域名访问。windows
以前写完博客以后都是须要手动执行一遍命令进行部署:
hexo clean&&hexo d
而后再把hexo
分支代码推送到 github 上
git push
在使用Github Actions
以后,只须要把hexo
分支代码推送到 github 上,剩下的所有交给Github Actions
便可,在此以前咱们须要生成一对公私钥
个用于 hexo 的部署操做,由于 hexo 自带的部署命令hexo d
须要有 git 远程仓库读写权限。
ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:XG1vkchp5b27tteZASx6ZrPRtTayGYmacRdjjRxR1Y0 root@8fe85d51123b The key's randomart image is: +---[RSA 2048]----+ | .+o=| | o *Eoo| | . X B .| | . . + X +.| | S . = O..| | o O B =.| | O = *.*| | o . o ++| | .oo| +----[SHA256]-----+
先把~/.ssh/id_rsa.pub
中的公钥添加到 Github 对应仓库的Deploye keys
中:
再将~/.ssh/id_rsa
中的私钥添加到 Github 对应仓库的Secrets
中,Name 定义为ACTION_DEPLOY_KEY
,目的是在构建的时候能够读取该私钥并配添加到虚拟机中,以获取 git 仓库访问权限:
准备工做完成后,接着就按照教程,在hexo
分支建立.github/workflows/main.yaml
文件用于配置 hexo 部署。
name: CI on: push: branches: - hexo jobs: build: runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v1 with: ref: hexo - name: Use Node.js ${{ matrix.node_version }} uses: actions/setup-node@v1 with: version: ${{ matrix.node_version }} - name: Setup hexo env: ACTION_DEPLOY_KEY: ${{ secrets.ACTION_DEPLOY_KEY }} run: | mkdir -p ~/.ssh/ echo "$ACTION_DEPLOY_KEY" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan github.com >> ~/.ssh/known_hosts git config --global user.email "liwei2633@163.com" git config --global user.name "monkeyWie" npm install hexo-cli -g npm install - name: Hexo deploy run: | hexo clean hexo d
具体的配置语法这里就不详细说明了,能够自行在官方文档中查阅。
构建流程以下:
hexo
分支的 push 操做ubuntu
虚拟机环境下${{ secrets.ACTION_DEPLOY_KEY }}
读取刚刚生成的私钥,并设置成环境变量,${{ exp }}
写法为 actions 内置的表达式语法,详细文档参考:contexts-and-expression-syntax-for-github-actions ~/.ssh/id_rsa
文件中,并把github.com
域名加入到~/.ssh/known_hosts
文件中,以避免第一次 ssh 访问时弹出交互式命令。把hexo
分支代码推到 github 上触发 workflow ,经过Actions
选项卡进入就能够看到项目的构建状况了。
至此改造完成,之后只须要写完文章直接提交代码就能够自动部署了,甚至均可以不装 node 环境进行写做简直不要太方便。
有些项目在发布新版本时,通常都会建立一个Github Release
,而且把对应编译好以后的文件上传到Release
的资源列表中,例如:
若是这个使用手动操做的话,不只步骤重复又繁琐(每次都要编译出各个操做系统对应的发行包再进行上传),并且最蛋疼的是对于国内的网络环境来讲,上传文件速度简直不能忍,好不容易上传了一大半搞很差就由于网络缘由又要从新上传,相信用过的人都深有体会。
我就在想若是能用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 name
和tag message
来建立对应的Github Release
,并将编译好的文件上传。
一样的建立一个.github/workflows/main.yml
文件,内容以下:
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
构建流程以下:
v
开头的 pushubuntu
虚拟机环境下golang 1.13.x
环境go build
交叉编译出不一样操做系统下 64 位可执行文件,并使用 zip 压缩xgo
交叉编译出不一样操做系统下 64 位可执行文件,并使用 zip 压缩monkeyWie/create-release@master
建立 Release,其中会用到${{ secrets.GITHUB_TOKEN }}
,这是Github Actions
内置的一个秘钥,用于受权访问你本身的 github 存储库,原理就是使用这个TOKEN
调用Github API
来进行建立 release,还有一个${{ github.ref }}
也是Github Actions
内置的一个变量,而后经过 action 的with
进行参数传递。actions/upload-release-asset@v1.0.1
上传文件,这里使用了两个表达式${{ steps.create_release.outputs.upload_url }}
和${{ steps.create_release.outputs.tag }}
,能够获取到指定action
的输出,第一个是获取建立好的 release 对应的上传地址,第二个是获取对应的 tag(例如:v1.0.0),这样就能够在把上传的文件带上版本号。由于这个action
不支持多个文件上传,因此就写了多个 action 进行上传。接下来在项目打个tag
,而后push
上去看看效果:
# 建立tag名为v1.0.8,并添加描述 git tag -a "v1.0.8" -m '发布v1.0.8版本 修复了如下bug: 1. xxxxx 2. xxxxx' # 把tag推到github上 git push --tags
而后就能够看到已经有一个新的workflow
正在运行了:
运行完成后在Releases
页面查看结果:
完美!和预想的结果一致。
注:因为官方的 create-release有点不能知足需求,因而我本身fork
了一份 create-release代码,就是把tag name
给输出来了,这里是相关的 PR,还没被合并,因此上面的建立 Release 的 action 是用的我本身的仓库monkeyWie/create-release@master
,还有关于 go 交叉编译的知识,有兴趣能够看看个人这篇博客: go-cross-compile。
在Github Actions
提供的虚拟机中,已经内置了docker
,而恰好我有一个项目由于国内的网络缘由构建docker镜像
很是的慢,这是我fork
的一个用于 go 项目交叉编译的项目,仓库地址https://github.com/monkeyWie/xgo,这个项目的主要工做原理就是经过 docker 里内置好各类交叉编译
的工具链,而后对外提供 go 项目交叉编译功能,下面节选一点Dockerfile
内容:
看这大量的apt-get install
,就知道在本地构建有多慢了,下面就改用Github Actions
来帮忙构建和部署镜像。
因为要将镜像推送到docker hub
官方镜像仓库上,须要验证帐号信息,
这里我把本身的用户密码配置到了Secrets
中,以便在 workflow 配置文件中能够访问到:
编写构建文件.github/workflows/main.yml
:
name: CI on: push: branches: - master paths: - "docker/base/*" jobs: build: runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v1 - name: Docker login run: docker login -u liwei2633 -p ${{ secrets.DOCKER_HUB_PWD }} - name: Docker build base run: | docker pull liwei2633/xgo:base docker build --cache-from=liwei2633/xgo:base -t liwei2633/xgo:base ./docker/base docker push liwei2633/xgo:base - name: Docker build other run: | docker build -t liwei2633/xgo:go-1.12.10 ./docker/go-1.12.10 docker push liwei2633/xgo:go-1.12.10 docker build -t liwei2633/xgo:go-1.12.x ./docker/go-1.12.x docker push liwei2633/xgo:go-1.12.x docker build -t liwei2633/xgo:go-1.13.1 ./docker/go-1.13.1 docker push liwei2633/xgo:go-1.13.1 docker build -t liwei2633/xgo:go-1.13.x ./docker/go-1.13.x docker push liwei2633/xgo:go-1.13.x docker build -t liwei2633/xgo:go-latest ./docker/go-latest docker push liwei2633/xgo:go-latest
构建流程以下:
docker/base
目录下文件有修改才进行构建,这样作的目的是在其它与 docker 构建无关的文件改动了不会去触发 workflowubuntu
虚拟机环境下${{ secrets.DOCKER_HUB_PWD }}
,这里不用担忧控制台输出会暴露密码,经过secrets
访问的变量在控制台输出时都会打上马赛克--cache-from=liwei2633/xgo:base
,预先下载好以前的镜像liwei2633/xgo:base
,而后可使用docker
的缓存机制加快构建速度这样经过Github Actions
就把构建镜像和部署时间的缩小了到了13分钟
:
虽然仍是挺慢的可是跟本地构建比起来快了不是一个量级,有次本地构建等了一个多小时,由于网络缘由致使一个软件源安装失败直接没了又要重头开始构建,因此高下立判,Github Actions
真香!!
经过上面三个实例项目,能够看得出Github Actions
为咱们节省大量的时间和重复的操做,且经过官方的 actions 市场很方便的就能够实现大部分编排功能,真是一个能够吹爆的良心产品,因此赶忙一块儿来尝鲜啊。