前言

上一篇博客中讲到如何解决从 Gitlab 安装私有扩展包的方法,但是也发现了一系列的问题:

  • 直接从 Gitlab Repository 拉去:这种方式最大的问题就是以来的包如果有代码改动,每次都要走一遍 Gitflow,比较麻烦!
  • 使用 replace 将 Gitlab 上的包替换为本地的目录:这种方式虽然解决了上面的问题,但是也产生了新的额问题,就是当开发完成提交代码时,需要手动将 go.mod 文件中的 replace 的配置都删掉,如果项目只有一两个包还好,多了的话那可真是灾难。

Workspace 就是为了解决这一问题而残生的,它的优先级要高于 go.mod 所以如果在项目目录下创建了 go.work,那么只需要在 go.work 中配置 replace 就可以了。

初始化 Workspace

在为项目初始化 Workspace 之前,我们可以看到现在 Go Env 中第 32 行的配置 GOWORK 是空的:

go env
GO111MODULE="on"
GOARCH="arm64"
GOBIN=""
GOCACHE="/Users/George/Library/Caches/go-build"
GOENV="/Users/George/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/George/Develop/Go/pkg/mod"
GONOPROXY=""
GONOSUMDB="gitlab.example.com/services/modules"
GOOS="darwin"
GOPATH="/Users/George/Develop/Go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/opt/homebrew/Cellar/go/1.19.2/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/homebrew/Cellar/go/1.19.2/libexec/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="go1.19.2"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/George/Develop/GA/udfs/server/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/p6/g0wwf37d165dfg5hvqtr9l180000gn/T/go-build1666497732=/tmp/go-build -gno-record-gcc-switches -fno-common"

接下来执行初始化 Workspace 的命令:

go work init .
cat go.work
go 1.19

use .

会在项目目录中创建一个 go.work 的文件,这时候再查看 Go Env 会发现 GOWORK 的值变成了当前目录下的 go.work

GOWORK="/Users/George/Develop/udfs/server/go.work"

从本地安装依赖

你可以可以在 use 中引入多个本地的包路径,这样在本地开发时,Go 会自动用 Workspace 下的包替换掉远端的包:

cat go.work
go 1.19

use (
    .
    ../modules/inquiry
)

当然也可以在 go.work 中使用 replace 来替换掉 go.mod 中声明的依赖包为本地包路径:

go work edit -replace=gitlab.example.com/services/modules/inquiry=/Users/George/Develop/services/modules/inquiry
cat go.work
go 1.19

use .

replace gitlab.example.com/services/modules/inquiry => /Users/George/Develop/services/modules/inquiry

这样就在 go.work 文件中定义了一个 replace,从而使用本地的项目作为包的源。本地目录可以是相对或绝对路径,但是目录下必须要有 go.mod 文件。

另外需要将 go.workgo.work.sum 文件加入 .gitignore 配置文件中,否则会导致在 CI/CD 中无法找到对应的 package。

总结

到这里在本地开发的问题就解决了,避免了每次修改需要走一遍包的发布流程。但是新的问题又来了,在执行 CI/CD 的流程中,如何按照环境来指定是从 Release Tag 安装还是从某个测试分支安装?

我将在后面的 CI/CD 实践中,继续探索这个问题,以及寻找最佳实践方案!

I hope this is helpful, Happy hacking…