TranslateProject/published/201805/20180412 BUILDING GO PROJECTS WITH DOCKER ON GITLAB CI.md
2018-06-03 22:19:23 +08:00

149 lines
4.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

在 GitKab CI 中使用 Docker 构建 Go 项目
===============================================
### 介绍
这篇文章是我在 CI 环境(特别是在 Gitlab 中)的 Docker 容器中构建 Go 项目的研究总结。我发现很难解决私有依赖问题(来自 Node/.NET 背景),因此这是我写这篇文章的主要原因。如果 Docker 镜像上存在任何问题或提交请求,请随时与我们联系。
### dep
由于 dep 是现在管理 Go 依赖关系的最佳选择,因此在构建前之前运行 `dep ensure`
注意:我个人不会将我的 `vendor/`  文件夹提交到源码控制,如果你这样做,我不确定这个步骤是否可以跳过。
使用 Docker 构建的最好方法是使用 `dep ensure -vendor-only`。 [见这里][1]。
### Docker 构建镜像
我第一次尝试使用  `golang:1.10`,但这个镜像没有:
* curl
* git
* make
* dep
* golint
我已经创建好了用于构建的镜像([github][2] / [dockerhub][3]),我会保持更新,但我不提供任何担保,因此你应该创建并管理自己的 Dockerhub。
### 内部依赖关系
我们完全有能力创建一个有公共依赖关系的项目。但是如果你的项目依赖于另一个私人 Gitlab 仓库呢?
在本地运行 `dep ensure` 应该可以和你的 git 设置一起工作,但是一旦在 CI 上不适用,构建就会失败。
#### Gitlab 权限模型
这是在 [Gitlab 8.12 中添加的][4],这个我们最关心的有用的功能是在构建期提供的 `CI_JOB_TOKEN` 环境变量。
这基本上意味着我们可以像这样克隆[依赖仓库][5]
```
git clone https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/myuser/mydependentrepo
```
然而,我们希望使这更友好一点,因为 `dep` 在试图拉取代码时不会奇迹般地添加凭据。
我们将把这一行添加到 `.gitlab-ci.yml``before_script` 部分。
```
before_script:
- echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
```
使用 `.netrc` 文件可以指定哪个凭证用于哪个服务器。这种方法可以避免每次从 Git 中拉取(或推送)时输入用户名和密码。密码以明文形式存储,因此你不应在自己的计算机上执行此操作。这实际用于 Git 在背后使用  `cURL`。 [在这里阅读更多][6]。
### 项目文件
#### Makefile
虽然这是可选的,但我发现它使事情变得更容易。
配置这些步骤意味着在 CI 脚本(和本地)中,我们可以运行 `make lint`、`make build` 等,而无需每次重复步骤。
```
GOFILES = $(shell find . -name '*.go' -not -path './vendor/*')
GOPACKAGES = $(shell go list ./... | grep -v /vendor/)
default: build
workdir:
mkdir -p workdir
build: workdir/scraper
workdir/scraper: $(GOFILES)
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o workdir/scraper .
test: test-all
test-all:
@go test -v $(GOPACKAGES)
lint: lint-all
lint-all:
@golint -set_exit_status $(GOPACKAGES)
```
#### .gitlab-ci.yml
这是 Gitlab CI 魔术发生的地方。你可能想使用自己的镜像。
```
image: sjdweb/go-docker-build:1.10
stages:
- test
- build
before_script:
- cd $GOPATH/src
- mkdir -p gitlab.com/$CI_PROJECT_NAMESPACE
- cd gitlab.com/$CI_PROJECT_NAMESPACE
- ln -s $CI_PROJECT_DIR
- cd $CI_PROJECT_NAME
- echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
- dep ensure -vendor-only
lint_code:
stage: test
script:
- make lint
unit_tests:
stage: test
script:
- make test
build:
stage: build
script:
- make
```
### 缺少了什么
我通常会用我的二进制文件构建 Docker 镜像,并将其推送到 Gitlab 容器注册库中。
你可以看到我正在构建二进制文件并退出,你至少需要将该二进制文件(例如生成文件)存储在某处。
--------------------------------------------------------------------------------
via: https://seandrumm.co.uk/blog/building-go-projects-with-docker-on-gitlab-ci/
作者:[SEAN DRUMM][a]
译者:[geekpi](https://github.com/geekpi)
校对:[wxy](https://github.com/wxy)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://seandrumm.co.uk/
[1]:https://github.com/golang/dep/blob/master/docs/FAQ.md#how-do-i-use-dep-with-docker
[2]:https://github.com/sjdweb/go-docker-build/blob/master/Dockerfile
[3]:https://hub.docker.com/r/sjdweb/go-docker-build/
[4]:https://docs.gitlab.com/ce/user/project/new_ci_build_permissions_model.html
[5]:https://docs.gitlab.com/ce/user/project/new_ci_build_permissions_model.html#dependent-repositories
[6]:https://github.com/bagder/everything-curl/blob/master/usingcurl-netrc.md