Supported commands: ls, cd ${PATH}

Golang Build Tools

Feb. 1, 2022

부제: golang 프로젝트를 빌드하는 개발자를 위한 안내서 (Happy Hacking하지만 make로 빌드하고 싶지 않은 개발자를 위한 안내서)

golang 프로젝트 빌드에 어떤 툴이 좋을까요? 정해진 답은 없지만 오늘은

위 세 가지 도구에 대해 알아보겠습니다.

1. golang 프로젝트 준비

Note: 지금부터 코드 블럭의 ‘jiwonaid’에 유의해 주세요.

아래와 같이 간단한 golang 기반의 CLI 프로젝트를 준비합니다.

go get -u github.com/spf13/cobra
mkdir golang-build-tools
cd golang-build-tools
go mod init github.com/jiwonaid/golang-build-tools

cobra init --pkg-name github.com/jiwonaid/golang-build-tools

go get github.com/mitchellh/go-homedir
go get github.com/spf13/cobra
go get github.com/spf13/viper

아래와 같은 결과가 출력됩니다.

go run main.go
A longer description that spans multiple lines and likely contains
examples and usage of using your application. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.

이제 git을 설정하고 아래 2번 항목 중 취향에 맞는 빌드 도구를 선택하여 적용합니다.

# github에서 repository 생성

git init
git add .
git commit -m "Add cobra"
git branch -M main
git remote add origin https://github.com/jiwonaid/golang-build-tools.git
git push -u origin main

2-A. GoReleaser 적용

GoReleaser is a release automation tool for Go projects. The goal is to simplify the build, release and publish steps while providing variant customization options for all steps.

번역: GoReleaser는 Go 프로젝트들을 위한 릴리스 자동화 도구로 빌드, 릴리스, 퍼블리시를 간소화하고 다양한 사용자 옵션을 제공하는 것을 목표로 합니다.

# brew install goreleaser/tap/goreleaser
brew install goreleaser

goreleaser init
git add .
git commit -m "Add goreleaser"
git push

# github에서 GITHUB_TOKEN 생성
# https://github.com/settings/tokens
# write:packages
export GITHUB_TOKEN="YOUR_GH_TOKEN"

git tag -a v0.1.0 -m "goreleaser release"
git push origin v0.1.0

goreleaser build

아래와 같이 릴리스도 가능합니다.

goreleaser release

goreleaser release

2-B. ko 적용

ko는 구글에서 만든 간단한 이미지 빌드용 도구로, 로컬 go build를 이용해서 CI/CD에 용의한 가벼운 이미지를 빌드하고 이미지 레지스트리에 푸시할 수 있습니다. 또한, 로컬과 쿠버네티스 환경에도 적용이 가능합니다.

brew install ko
# KO_DOCKER_REPO=gcr.io/my-project
# KO_DOCKER_REPO=my-dockerhub-user
export KO_DOCKER_REPO=jiwonaid

ko publish .

dockerhub

2-C. Bazel(bazel-gazelle) 적용

우선 Bazel과 Bazel을 조금 더 쉽게 사용할 수 있게 해주는 bazel-gazelle을 설치합니다.

brew install bazel

go install github.com/bazelbuild/bazel-gazelle/cmd/gazelle@latest

다음으로 WORKSPACE 파일을 생성합니다.

cat << EOD > WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "io_bazel_rules_go",
    sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
        "https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip",
    ],
)

http_archive(
    name = "bazel_gazelle",
    sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb",
    urls = [
        "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
        "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz",
    ],
)

load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

############################################################
# Define your own dependencies here using go_repository.
# Else, dependencies declared by rules_go/gazelle will be used.
# The first declaration of an external repository "wins".
############################################################

go_rules_dependencies()

go_register_toolchains(version = "1.17.2")

gazelle_dependencies()
EOD

마지막으로 gazelle을 이용해서 dependency들을 갱신하고 BUILD 파일을 생성합니다.

# WORKSPACE dependency 갱신
gazelle update-repos -from_file=go.mod

# BUILD 파일 생성
gazelle -go_prefix github.com/jiwonaid/golang-build-tools

이제 bazel로 빌드가 가능합니다.

bazel build //:golang-build-tools

git commit -m "Add bazel-gazelle"
git push

결과물

https://github.com/jiwonaid/golang-build-tools