본문 바로가기
프로그래밍/Golang

Golang Module(모듈) 발행 가이드: GitHub에 패키지 배포

by slowin 2024. 7. 18.

Go 모듈, 왜 사용해야 할까?

  • 버전 관리 용이: 특정 버전 지정으로 프로젝트 재현성을 보장합니다.
  • 종속성 관리 간소화: go.mod로 종속성을 명확히 정의하고 관리합니다.
  • 외부 패키지 사용 편리: go get으로 쉽게 패키지를 추가하고 관리합니다.
  • $GOPATH 의존성 제거: 프로젝트의 독립적인 관리가 가능해집니다.
  • 빌드 성능 향상: 필요한 패키지만 사용하여 빌드 속도가 개선됩니다.

프로젝트 생성

예제 프로젝트를 생성하겠습니다.

$ go mod init slowin.com/example
go: creating new go.mod: module slowin.com/example

$ go get rsc.io/quote/v3
go: downloading rsc.io/quote/v3 v3.1.0
go: added golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c
go: added rsc.io/quote/v3 v3.1.0
go: added rsc.io/sampler v1.3.0

$ ls
go.mod go.sum

$ cat go.mod 
module slowin.com/example

go 1.22.3

require (
        golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
        rsc.io/quote/v3 v3.1.0 // indirect
        rsc.io/sampler v1.3.0 // indirect
)

$ cat go.sum
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
  1. `go mod init slowin.com/example` 명령으로 새 Go 모듈을 초기화했습니다.
  2. `go get rsc.io/quote/v3` 명령으로 `rsc.io/quote/v3` 패키지와 그 의존성을 다운로드하고 추가했습니다.
  3. `go.mod`와 `go.sum` 파일이 생성되었습니다.
  • go.mod 파일에는 모듈 이름, Go 버전, 그리고 프로젝트의 의존성이 명시되어 있습니다.
  • go.sum 파일은 의존성의 체크섬을 포함하고 있어 의존성의 무결성을 보장합니다.

Git 저장소 초기화

우리가만든 모듈을 배포하기 위해 git 초기화를 진행하겠습니다.

go.mod 파일이 있는 디렉토리로 이동한 후 저장소를 생성합니다

# go.mod 파일이 있는 디렉토리로 이동

# Git 저장소 초기화
$ git init
Initialized empty Git repository in ./project/.git/

# 예제 코드 파일 생성
$ touch hello.go hello_test.go

# 모든 파일을 Git 스테이징 영역에 추가
$ git add go.mod go.sum hello.go hello_test.go

# 첫 번째 커밋 생성
$ git commit -m "hello: initial commit"
[main (root-commit) 913515b] hello: initial commit
 4 files changed, 15 insertions(+)
 create mode 100644 go.mod
 create mode 100644 go.sum
 create mode 100644 hello.go
 create mode 100644 hello_test.go

이제 프로젝트의 기본 구조가 준비되었습니다.

다음으로는, `go.mod`, `go.sum`파일에 대해 설명해보겠습니다.

go.mod 파일

`go.mod` 파일은 프로젝트의 주요 모듈 정보를 담고 있습니다. 이 파일에는 프로젝트가 의존하는 다른 모듈들의 이름과 버전 정보가 포함됩니다.

  1. module: 프로젝트의 모듈 이름을 지정합니다.
  2. go: 사용하는 Go 언어 버전을 지정합니다.
  3. require: 이 프로젝트가 의존하는 다른 모듈들과 그 버전 정보를 나열합니다.
    1. https://go.dev/ref/mod#go-mod-file-require
  4. replace: 특정 모듈 버전을 다른 버전으로 대체할 때 사용됩니다.
    1. https://go.dev/ref/mod#go-mod-file-replace
  5. exclude: 특정 버전을 사용하지 않도록 제외할 때 사용됩니다.
    1. https://go.dev/ref/mod#go-mod-file-exclude

go.sum 파일

go.sum 파일은 go.mod 파일에 명시된 모든 모듈의 해시값과 버전 정보를 포함하고 있습니다. 이 파일은 모듈의 정확성을 검증하고, 모듈의 종속성을 고정하는 데 사용됩니다. 각 의존성 모듈의 버전과 그에 대한 체크섬이 기록되어 있어, 의존성 모듈이 정확히 일치하는지 확인할 수 있습니다.

  • go.sum 파일은 아래 명령어를 실행할 때 자동으로 업데이트됩니다.
    • go mod tidy
    • go mod download
    • go build

다음으로는 버전관리에 대해 설명하겠습니다.

Semantic versions and modules

참고: Semantic Versioning

의미론적 버전 관리는 소프트웨어 버전을 세 부분으로 나누어 관리하는 방식입니다

  • vMAJOR.MINOR.PATCH
    • ex) v1.0.0
  1. MAJOR (큰 변화):
    • 제품의 큰 변화를 의미합니다.
    • 예: 스마트폰의 새 모델이 나왔을 때처럼, 이전 버전과 완전히 다른 기능이 추가되거나 사용 방법이 크게 바뀌는 경우입니다.
  2. MINOR (작은 기능 추가):
    • 새로운 기능이 추가되지만, 기존 사용자들이 여전히 문제없이 사용할 수 있는 경우입니다.
    • 예: 스마트폰 앱에 새로운 기능이 추가되었지만, 기존 기능은 그대로인 경우입니다.
  3. PATCH (버그 수정):
    • 작은 문제를 고치는 경우입니다.
    • 예: 앱에서 오타를 수정하거나 작은 버그를 고치는 경우입니다.

이렇게 버전을 관리하면 사용자나 다른 개발자들이 새 버전이 얼마나 큰 변화를 포함하고 있는지 쉽게 이해할 수 있습니다. 1.0.0에서 2.0.0으로 바뀌면 큰 변화가 있다는 뜻이고, 1.1.0에서 1.2.0으로 바뀌면 새 기능이 추가되었다는 뜻이며, 1.0.1에서 1.0.2로 바뀌면 작은 수정이 있었다는 뜻입니다.

v0: 초기 개발 버전 태그 지정하기

초기 단계에서는 v0 버전을 사용합니다. 이 버전은 API가 아직 안정화되지 않았음을 의미합니다.

1. 프로젝트 정리

$ go mod tidy

  • 이 명령어는 사용하지 않는 의존성을 제거하고 필요한 의존성을 추가합니다.

2. 테스트 실행

$ go test ./...
  • 모든 테스트를 실행하여 프로젝트가 정상 작동하는지 확인합니다
3. 변경사항 커밋
$ git add go.mod go.sum hello.go hello_test.go
$ git commit -m "hello: changes for v0.1.0"
  • 버전 관련 변경사항을 커밋합니다.

4. 버전 태그 생성

$ git tag v0.1.0
  • v0.1.0 태그를 생성합니다.

5. 태그 푸시

$ git push origin v0.1.0
  • 생성한 태그를 원격 저장소에 푸시합니다.

버전 업그레이드 가이드

  • 기능 추가 또는 호환되는 변경: MINOR 버전 증가 (예: v0.1.0 → v0.2.0)
  • 버그 수정: PATCH 버전 증가 (예: v0.1.0 → v0.1.1)

v1: 첫 번째 안정 버전 릴리스하기

v1 버전은 여러분의 Go 모듈이 안정화되었음을 선언입니다.

1. 버전 태그 생성 및 푸시

# 코드가 수정됨...
...
$ git tag v1.0.0
$ git push origin v1.0.0

github 배포 및 go get 으로 모듈 불러오기

자세한 설명은 생략하겠습니다.

github에서 레포지토리를 만들고 작업했던것을 레포지토리에 push하겠습니다.

1. GitHub 레포지토리 생성 및 푸시

git remote add origin git@github.com:.../module-publish.git
git branch -M main
git push -u origin main

2. 태그된 버전 푸시

git push origin v1.0.0

3. 다른 프로젝트에서 모듈 사용하기

새 프로젝트 디렉토리를 만들고 모듈을 초기화합니다

mkdir myproject
cd myproject
go mod init myproject

GitHub에 배포한 모듈을 가져옵니다:

go get github.com/.../module-publish@v1.0.0

4. 모듈 사용 예시 (main.go)

package main

import (
    "fmt"
    "github.com/.../module-publish"
)

func main() {
    fmt.Println(modulepublish.HelloWorld())
}

Go 모듈이 GitHub에 배포되었고, 다른 프로젝트에서 go get 명령어로 쉽게 사용할 수 있습니다. 새 버전을 릴리스할 때마다 태그를 생성하고 푸시하면 됩니다.

정리

go 모듈에 대해서 간략하게 알아보면서, github 레포지토리에 나만의 모듈을 배포하는것까지 알아보았습니다.

참고

관련

Golang 패키지 기본 개념: 구조, 사용법 및 모범 사례 가이드

Golang 패키지 네이밍 가이드: 효과적인 패키지 이름 짓기 12가지 팁
Golang 패키지 종속성 관리와 모듈화