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 市場很方便的就能夠實現大部分編排功能,真是一個能夠吹爆的良心產品,因此趕忙一塊兒來嚐鮮啊。