I believe that all developers writing Go language projects must be using Go module now, and Go module files are written in /go/pkg/mod directory by default, so when you want to string CI/CD process, because it is not under the project path, each container cannot share the /go/pkg/mod path, resulting in repeated downloads of third-party packages. In fact, the cross-container solution can be solved by Drone’s Temporary Volumes, but eventually, when you want to finish the compilation process, you can pack the final mod directory and save it for the next CI/CD deployment process, and if you can change the /go/pkg/mod path, you can dynamically adjust the directory structure. The following is an explanation of the Drone deployment tool.

## GOMODCACHE Environment Variables

Go 1.15 started to support GOMODCACHE environment variable, the default is GOPATH[0]/pkg/mod, now this path can be corrected by environment variable. This tutorial will use the meltwater/drone-cache package to complete the cache mechanism of the go module to speed up each subsequent CI/CD deployment. To do the cache, we need to create Temporary Volumes in the pipeline first.

 1 2 3  volumes: - name: cache temp: {} 

With this temporary space, you can see the same files in containers that are not synchronized with each other. Next, set up the steps to compile the Go project.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16  - name: build pull: always image: golang:1.15-rc commands: - make build environment: CGO_ENABLED: 0 GOMODCACHE: '/drone/src/pkg.mod' GOCACHE: '/drone/src/pkg.build' when: event: exclude: - tag volumes: - name: cache path: /go 

Here you can notice that since Go 1.15 is not yet released (expected 2020/08), we have used the rc version first. Here you can notice that we modified GOMODCACHE to put the original mod content in /drone/src/pkg.mod and /drone/src is the project directory, so remember to set a directory name that will not be used, please use the absolute path.

## Using build cache

In the CI/CD compilation process, the first step is to download the remotely backed up mod file to the container and uncompress it to the path specified by GOMODCACHE.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22  - name: restore-cache image: meltwater/drone-cache environment: AWS_ACCESS_KEY_ID: from_secret: aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: aws_secret_access_key pull: always settings: debug: true restore: true cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}' bucket: drone-cache-demo region: ap-northeast-1 local_root: / archive_format: gzip mount: - pkg.mod - pkg.build volumes: - name: cache path: /go 

Here you can see that I am using AWS S3 as the backend storage, you can also change it via SFTP or other methods. In archive_format please select gzip to make the file smaller. Then you will go through a series of Go processes, such as testing, compiling, packaging … etc., and finally pkg.mod will be packaged and uploaded to AWS S3.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  - name: rebuild-cache image: meltwater/drone-cache pull: always environment: AWS_ACCESS_KEY_ID: from_secret: aws_access_key_id AWS_SECRET_ACCESS_KEY: from_secret: aws_secret_access_key settings: rebuild: true cache_key: '{{ .Repo.Name }}_{{ checksum "go.mod" }}_{{ checksum "go.sum" }}_{{ arch }}_{{ os }}' bucket: drone-cache-demo region: ap-northeast-1 archive_format: gzip mount: - pkg.mod - pkg.build volumes: - name: cache path: /go 

Please refer to the code here.