彼得天空-个人心地带 彼得天空-个人心地带

马尔济斯犬,王俊凯身高,小狗-彼得天空-个人心地带

GitHub 前一段时间推出了自家的主动化构建东西:GitHub Actions,不过现在还没有开放注册,只能经过请求等候官方审阅。我第一时间就提交了请求,现在现已审阅经过了,所以第一时间体会了GitHub Actions的功用,整体感触是 Travis CI 之类的东西应该现在在墙角瑟瑟发抖吧?

GitHub Actions答应构建一个完好的 CI/CD Pipeline,与 GitHub 生态系统深度集成,而无需运用 Travis CI 或许 Circle CI 等第三方服务,关于开源项目都是能够免费运用的。假如你也想赶快运用的话,能够经过链接 https://github.com/features/actions/signup 去请求权限。

github actions

Golang 项目

为了演示GitHub Actions的功用,咱们这儿来构建一个最简略的”Hello world”的 Golang 程序,其间就包括一个根本的 Pipeline,每次Pull Request或许推送代码到 master 分支的时分就会触发该 Pipeline 的主动构建,进行代码的 lint 操作、运转单元测验并运用 Codecov 生成代码掩盖率陈述。

当在库房上创立一个新的tag的时分,Pipeline 会运用 GoReleaser 东西发布一个新的 GitHub 版别。

GoReleaser 是一个 Golang 项目的主动化发布东西,能够简化构建、发布流程,为一切流程供给了一些自界说的选项。

在 GitHub 上新建一个名为 go-github-actions的库房,在项目根目录下面创立一个 main.go 文件,内容如下所示:

package main
import (
"fmt"
"github.com/cnych/go-github-actions/hello"
)
func main() {
fmt.Println(hello.Greet())
}

能够看到咱们调用了 hello 这个 package 下面的 Greet 函数,所以需求在根目录下面新建一个名为 hello 的 package,在 package 下面新建一个 hellog.go 的文件,内容如下所示:

package hello
// Greet... Greet GitHub Actions
func Greet() string {
return "Hello GitHub Actions"
}

在项目根目录下面初始化 go modules:

$ go mod init github.com/cnych/go-github-actions
go: creating new go.mod: module github.com/cnych/go-github-actions

然后在 hello 这个 package 下面创立一个单元测验的文件(hello_test.go),内容如下所示:

package hello
import "testing"
func TestGreet(t *testing.T) {
result := Greet()
if result != "Hello GitHub Actions" {
t.Errorf("Greet() = %s; Expected Hello GitHub actions", result)
}
}

在根目录下面履行单元测验:

$ go test ./hello
ok github.com/cnych/go-github-actions/hello 0.007s
$ go run main.go
Hello GitHub Actions

终究的代码结构如下所示:

$ tree .
.
├── README.md
├── go.mod
├── hello
│ ├── hello.go
│ └── hello_test.go
└── main.go
1 directory, 5 files

最终不要忘掉把代码推送到 GitHub 上面去。

GitHub Actions Pipeline

当咱们把代码推送到 GitHub 上去往后,在页面上能够看到 Actions 的进口(条件是现已开通了):

github actions config

在页面中能够看到 Actions 为咱们供给了许多内置的 workflow,比方 golang、Rust、Python、Node 等等,咱们这儿来自己编写 workflow,点击右上角的Set up a workflow yourself,跳转到 Pipeline 的编写页面:

github actions pipeline custom

能够经过特点 on 来操控 workflow 被触发构建的条件,比方当代码推送到master和release分支的时分触发构建:

on:
push:
branches:
- master
- release/*

当只要pull_request被合并到master分支的时分:

on:
pull_request:
branches:
- master

除此之外,还能够经过守时使命来进行触发,比方星期一到星期五的每天2点构建使命呢:

on:
schedule:
- cron: 0 2 * * 1-5

GitHub Actions Workflow 的完好语法能够在文档 https://help.github.com/articles/workflow-syntax-for-github-actions 中查看到。

别的一个比较重要的是action,actions 是可重复运用的作业单元,可由任何人在 GitHub 上构建和分发,咱们能够在 GitHub marketplace 中找打各式各样的操作,经过指定包括 action 和 想运用的 ref 来进行操作:

- name: < display name for action >
uses: {owner}/{repo}@ref
with:

经过查看 GitHub Actions 为咱们生成的默许的 workflow 脚本,咱们就能够看出 workflow 是满意某些条件或事情的时分的一组使命(job)和过程(step):

name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Run a one-line script
run: echo Hello, world!
- name: Run a multi-line script
run: |
echo Add other actions to build,
echo test, and deploy your project.

在一个项目中还能够有多个 workflow,每个 workflow 都呼应一组不同的事情。

main workflow

在咱们这儿的示例中,咱们将会界说两个 workflow,推送代码到 master 分支或许创立 PR 的时分将触发 Build 的 workflow,当创立了一个新的 tag 的时分,会触发 Release 的 workflow,该作业流会发布一个新的运用版别。

每个 workflow 由一个或多个 Job 组成,咱们的 Build Workflow 包括3个 Job(Lint、Build 和 Test),而 Release Workflow 只包括一个 Release 的 Job。

每个 Job 都由多个 Step 组成,比方,“单元测验”的 Job 就包括获取代码、运转测验和出产代码掩盖率陈述的几个过程。

Workflow 会被界说在代码库房根目录下面的.github/workflows目录中的 YAML 文件中,该目录下面的每个文件就代表了不同的作业流。

下面是咱们界说的 Build Workflow:(main.yaml)

name: Build and Test
on:
push:
branches:
- master
pull_request:
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: Check out code
uses: actions/checkout@v1
- name: Lint Go Code
run: |
export PATH=$PATH:$(go env GOPATH)/bin # temporary fix. See https://github.com/actions/setup-go/issues/14
go get -u golang.org/x/lint/golint
make lint
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: Check out code
uses: actions/checkout@v1
- name: Run Unit tests.
run: make test-coverage
- name: Upload Coverage report to CodeCov
uses: codecov/codecov-action@v1.0.0
with:
token: ${{secrets.CODECOV_TOKEN}}
file: ./coverage.txt
build:
name: Build
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: Check out code
uses: actions/checkout@v1
- name: Build
run: make build

咱们首要界说了 workflow 的称号和触发规矩,咱们期望代码推送到 master 分支或许履行一个 PR 的时分触发,所以界说的触发器规矩如下:

on:
push:
branches:
- master
pull_request:

然后在整个 workflow 中包括了3个 Job:Lint、Test 和 Build,Lint 的 Job 界说如下:

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: Check out code
uses: actions/checkout@v1
- name: Lint Go Code
run: |
export PATH=$PATH:$(go env GOPATH)/bin # temporary fix. See https://github.com/actions/setup-go/issues/14
go get -u golang.org/x/lint/golint
make lint

这儿咱们指定了咱们期望这个 Job 使命在 ubuntu 机器上运转(runs-on关键字)。Actions 现在支撑 Linux、Mac、Windows 和 Docker 环境,在今后,也能够将自己的机器来作为 runners 运转,相似与 GitLab CI Runner。然后界说了该 Job 使命的履行过程:

首要是装置 Golang 环境,GitHub 现已供给了这样的一个 action,所以咱们直接运用即可:

- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12

能够在 GitHub marketplace 上面找到 action 的详细运用方法:https://github.com/marketplace/actions/setup-go-for-use-with-actions。

其实这儿的过程声明语法很清晰了,with关键字答应咱们指定 action 所需的参数,这儿setup-go这个 action 答应咱们指定要运用的 go 版别,由于咱们上面的比方中运用了 go modules,所以咱们这儿指定运用的是1.12版别(大于1.11即可),然后下一个过程便是获取源代码,相同这儿仍是直接运用内置的一个 action:

- name: Check out code
uses: actions/checkout@v1

然后咱们装置和运转golint东西:

- name: Lint Go Code
run: |
export PATH=$PATH:$(go env GOPATH)/bin
go get -u golang.org/x/lint/golint
make lint

这样 Lint 这个 Job 使命就界说完结了,其他的 Job 也十分相似,比方咱们再来看下 Test 这个 Job 使命,界说如下所示:

test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.12
- name: Check out code
uses: actions/checkout@v1
- name: Run Unit tests.
run: make test-coverage
- name: Upload Coverage report to CodeCov
uses: codecov/codecov-action@v1.0.0
with:
token: ${{secrets.CODECOV_TOKEN}}
file: ./coverage.txt

这儿的界说仅有不同的是上传代码测验掩盖率运用的 action 是一个第三方的,当然这个 action 也在 marketplace 上面能够找到:https://github.com/marketplace/actions/codecov,咱们会将测验的代码掩盖率上传到 CodeCov。这儿咱们需求运用 GitHub 的secrets来存储操作 CodeCov 所需求的Codecov Token,在 CodeCov 网站上经过 GitHub 用户授权登录,然后启用上面的[go-github-actions]项目,就能够取得Codecov Token的值,然后在 GitHub 项目 settings -> Secrets 下面增加,Name 为CODECOV_TOKEN,Value 便是刚刚获取的Codecov Token的值。这样咱们就完结了 Test 这个 Job 使命的操作声明。

咱们能够运用任何言语创立自己的 actions(只需求包括一个 Dockerfile 文件),假如你喜爱运用 Typescript 的话还能够直接运用官方供给的 action 开发东西包:https://github.com/actions/toolkit。

这样咱们就完结了第一个 workflow,不过需求留意的是咱们这儿一切的操作都是经过 make 指令履行的,所以咱们还需求在项目根目录中增加一个 Makefile 文件,内容如下所示:

PROJECT_NAME := "github.com/cnych/go-github-actions"
PKG := "$(PROJECT_NAME)"
PKG_LIST := $(shell go list ${PKG}/... | grep -v /vendor/)
GO_FILES := $(shell find . -name '*.go' | grep -v /vendor/ | grep -v _test.go)
.PHONY: all dep lint vet test test-coverage build clean
all: build
dep: ## Get the dependencies
@go mod download
lint: ## Lint Golang files
@golint -set_exit_status ${PKG_LIST}
vet: ## Run go vet
@go vet ${PKG_LIST}
test: ## Run unittests
@go test -short ${PKG_LIST}
test-coverage: ## Run tests with coverage
@go test -short -coverprofile cover.out -covermode=atomic ${PKG_LIST}
@cat cover.out >> coverage.txt
build: dep ## Build the binary file
@go build -i -o build/main $(PKG)
clean: ## Remove previous build
@rm -f ./build
help: ## Display this help screen
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

接下来咱们创立一个新的分支改一点代码然后在 Actions 中查看下 PR 的 workflow:

$ git checkout -b actions-demo
Switched to a new branch 'actions-demo'

然后修正 hello 这个 package 下面的 Greet 函数:

// Greet ... Greet GitHub Actions
func Greet() string {
return "Hello GitHub Actions. qikqiak.com is awesome"
}

当然相同也要修正下 hello_test.go 中的测验代码:

func TestGreet(t *testing.T) {
result := Greet()
if result != "Hello GitHub Actions. qikqiak.com is awesome" {
t.Errorf("Greet() = %s; Expected Hello GitHub Actions. qikqiak.com is awesome", result)
}
}

要记住上面界说的 workflow 文件相同要增加到项目根目录.github/workflows/main.yml文件中,现在推送这个分支然后创立一个 Pull Request 到 master 分支,上面咱们界说的作业流就会马上被触发构建了。并且在 workflow 还未履行完结经过的时分,是不能进行 merge 操作的。

当使命履行完结后就能够进行 Merge 操作了:

上面在 workflow 中咱们还和 CodeCov 进行了集成,所以咱们能够看到 PR 的状况查看和 Coverage 代码掩盖陈述:

release workflow

上面咱们界说了构建测验的 workflow,接下来咱们来界说咱们的发布 workflow,运用方法都是相似的,上面咱们也提到过每个 workflow 都是一个独立的文件,咱们这儿创立一个文件.github/workflows/release.yml,内容如下所示:

name: Release
on:
create:
tags:
- v*
jobs:
release:
name: Release on GitHub
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v1
- name: Validates GO releaser config
uses: docker://goreleaser/goreleaser:latest
with:
args: check
- name: Create release on GitHub
uses: docker://goreleaser/goreleaser:latest
with:
args: release
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}

这个 workflow 中咱们界说了只在创立新的 tag 时才触发使命,然后只界说了一个 release 的 Job。

上面咱们界说的 Job 使命中先获取项目代码,然后运用 GoReleaser 官方 Docker 镜像来构建使命。当运用 docker 容器的时分,能够界说容器的args和entrypoint,咱们这儿别离运用args界说了check和release两个参数。

别的还指定了GoReleaser所需的GITHUB_TOKEN这个环境变量,这样能够在 GitHub 上来发布咱们的运用版别,不过需求留意的是,secrets.GITHUB_TOKEN这个变量的值是由 Actions 渠道主动注入的,所以不需求咱们独自手动去增加了,这样就便利许多了。

然后咱们创立一个新的 tag 并推送到代码库房中去:

$ git tag v0.1.0
$ git push --tags
Counting objects: 5, done.
Writing objects: 100% (5/5), 799 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
To git@github.com:cnych/go-github-actions.git
* [new tag] v0.1.0 -> v0.1.0

假如一切正常就会马上触发使命构建,Job 使命构建完结后会在 GitHub 上面创立一个新的版别,其间包括由GoReleaser东西主动生成的运用包和 Changelog。

github actions release

到这儿咱们就完结了第一个 GitHub Actions 的 Pipeline,这是一个十分根底的比方,可是关于咱们了解 GitHub Actions 的作业方式是一个很好的事例。

总结

关于大部分保管在 GitHub 上的开源项目,GitHub Actions 应该满足了,关于更高档的用法,比方手动同意和参数化构建这些企业项目会常常运用的功用现在还不支撑,不过 GitHub Actions 现在还处于测验阶段,或许不久的将来就会支撑这些功用了,关于 Jenkins、GitLab CI 这些在企业中十分受欢迎的东西来说影响或许不大,可是关于一些依靠 GitHub 的第三方 CI/CD 东西影响就很大了,比方 Travis CI 或许 Circle CI 之类的,由于关于保管在 GitHub 上面的项目来说 GitHub Actions 现已满足优异了,更重要的是归于内置的功用,所以前面说 Travis CI 现在在某个墙角瑟瑟发抖不是没有道理的。

参阅文档

  • https://github.com/features/actions
  • https://help.github.com/en/articles/workflow-syntax-for-github-actions
  • https://dev.to/brpaz/building-a-basic-ci-cd-pipeline-for-a-golang-application-using-github-actions-icj
作者:admin 分类:新闻世界 浏览:231 评论:0