本文转载自微信公众号《crossoverJie》,作者crossoverJie。转载本文请联系跨界姐公众号。前言最近公司内部项目的发布过程已经接入了GitHubActions,整个体验过程还是比较不错的;本文的主要目的是希望能够使用它快速构建自动化测试、打包推送Docker镜像等过程。创建项目本文主要以Go语言为例。当然,其他语言也类似,与语言本身关系不大。这里我们先在GitHub上创建一个项目,写几个简单的代码main.go:varversion="0.0.1"funcGetVersion()string{returnversion}funcmain(){fmt.Println(GetVersion())}内容很简单,只打印版本号;同时匹配到一个单元测试main_test.go:funcTestGetVersion1(t*testing.T){tests:=[]struct{namestringwantstring}{{name:"test1",want:"0.0.1"},}for_,tt:=rangetests{t.Run(tt.name,func(t*testing.T){ifgot:=GetVersion();got!=tt.want{t.Errorf("GetVersion()=%v,want%v",got,tt.want)}})}}我们可以执行gotest来运行单元测试。$gotestPASSokgithub.com/crossoverJie/go-docker1.729s自动测试当然,以上过程可以使用Actions自动完成。首先,我们需要在项目根路径下创建.github/workflows/*.yml配置文件,添加如下内容:name:go-dockeron:pushjobs:test:runs-on:ubuntu-latestif:github.ref=='refs/heads/main'||startsWith(github.ref,'refs/tags')steps:-uses:actions/checkout@v2-name:RunUnitTestsrun:gotest简单说明:name不用多说,它是为当前的工作流程创建一个名词。on指的是什么事件被触发。这里指的是代码推送时的触发。更多的事件定义可以参考官方文档:Eventsthattriggerworkflowsjobs就是定义任务。这里只有一个名为test的任务。该任务在ubuntu-latest环境下运行,仅在主分支有推送或标签推送时运行。别人封装的actions/checkout@v2,运行时会用到。当然,这里使用的是官方的pullcodeaction。基于这个逻辑,我们可以灵活的共享和使用其他人的Actions来简化流程,这也是GitHubActions非常可扩展的地方。最后运行是运行自己的命令,自然会触发单元测试。如果是Java,可以改成mvntest。一旦我们在主分支上推送了代码,或者合并了其他分支的代码,单元测试就会自动运行,非常方便。和我们当地的运营效果是一致的。自动发布接下来考虑自动打包Docker镜像并上传到DockerHub;为此,首先创建一个Dockerfile:FROMgolang:1.15ASbuilderARGVERSION=0.0.10WORKDIR/go/src/appCOPYmain.go.RUNgobuild-omain-ldflags="-X'main.version=${VERSION}'"main.goFROMdebian:stable-slimCOPY--from=builder/go/src/app/main/go/bin/mainENVPATH="/go/bin:${PATH}"CMD["main"]这里可以使用ldflags传递一些参数编译时进入打包程序,如打包时间、go版本、git版本等。这里只是将VERSION传入main.version变量,以便在运行时获取。dockerbuild-tgo-docker:last.dockerrun--rmgo-docker:0.0.100.0.10继续编写docker.yml,添加Docker的自动打包并推送到dockerhub。部署:runs-on:ubuntu-latestneeds:testif:startsWith(github.ref,'refs/tags')steps:-name:ExtractVersionid:version_steprun:|echo“##[set-outputname=version;]VERSION=${GITHUB_REF#$"refs/tags/v"}"echo"##[set-outputname=version_tag;]$GITHUB_REPOSITORY:${GITHUB_REF#$"refs/tags/v"}"echo"##[set-outputname=latest_tag;]$GITHUB_REPOSITORY:latest"-name:SetupQEMUuses:docker/setup-qemu-action@v1-name:SetupDockerBuildxuses:docker/setup-buildx-action@v1-name:LogintoDockerHubuses:docker/login-action@v1with:用户名:${{secrets.DOCKER_USER_NAME}}密码:${{secrets.DOCKER_ACCESS_TOKEN}}-name:PrepareRegNamesid:read-docker-image-identifiersrun:|echoVERSION_TAG=$(echo${{steps.version_step.outputs.version_tag}}|tr'[:upper:]''[:lower:]')>>$GITHUB_ENVechoLASTEST_TAG=$(echo${{steps.version_step.outputs.latest_tag}}|tr'[:upper:]''[:lower:]')>>$GITHUB_ENV-name:BuildandpushDockerimagesid:docker_builduses:docker/build-push-action@v2.3.0with:push:truetags:|${{env.VERSION_TAG}}${{env.LASTEST_TAG}}build-args:|${{steps.version_step.outputs.version}}新添加了一个deployjobneeds:testif:startsWith(github.ref,'refs/tags'),其运行条件为上一步中的单个测试流程运行通过,只有在生成新标签时才会触发后续步骤。name:登录DockerHub这一步我们需要登录DockerHub,所以首先我们需要在GitHub项目中配置hub的user_name和access_token。配置完成后,我们就可以在动作中使用这个变量了。这里使用了docker官方提供的登录动作(docker/login-action)。需要注意的一点是,我们需要将图片名称改为小写,否则会上传失败。比如我名字里的字母J是大写的,直接上传会报错。所以在上传之前执行此步骤转换为小写。最后,使用这两个变量上传到DockerHub。以后只要我们打上标签,Action就会自动执行单元测试、构建、上传的过程。综上所述,GitHubActions非常灵活。您需要的大部分功能都可以在市场上找到现成的并直接使用。比如可以使用ssh登录自己的服务器,执行一些命令或者脚本,想象空间很大。就像搭积木一样使用,您可以灵活地满足您的需求。参考链接:HowtoBuildaCI/CDpipelinewithGo,GitHubActionsandDocker
