Selama module hanya hidup di komputer kita, versi adalah urusan pribadi. Begitu module dipakai orang lain — rekan tim, aplikasi lain, atau publik — setiap rilis menjadi kontrak: pemakai berhak tahu apa yang berubah dan apakah kode mereka masih aman setelah memperbarui dependency. Go mengadopsi semantic versioning yang dipetakan ke tag git, dengan satu aturan khusus yang mengejutkan pendatang baru: major version 2 ke atas harus pindah alamat ke path /v2. Pada chapter ini kita akan merilis module demo secara nyata dengan tag, mengonsumsinya sebagai dependency lokal, lalu menempuh jalur upgrade ke v2 lengkap dengan galatnya.

Semantic Versioning dalam Tiga Angka #

Versi module ditulis vMAJOR.MINOR.PATCH — misalnya v1.1.0. Setiap segmen punya janji yang berbeda bagi pemakai:

SegmenNaik ketikaDampak bagi pemakai
PATCH (1.1.0 → 1.1.1)Perbaikan cacat tanpa perubahan APIAman diperbarui begitu saja
MINOR (1.1.0 → 1.2.0)Penambahan API baru, yang lama tak diubahAman; fitur baru tersedia
MAJOR (1.1.0 → 2.0.0)Perubahan yang merusak (breaking change)Wajib penyesuaian kode

Nomor versi boleh memuat pre-release seperti v2.1.0-rc.1 — dianggap lebih rendah dari v2.1.0 final, cocok untuk kandidat rilis, dan go get memilihnya hanya bila diminta eksplisit.

Merilis dengan Tag Git #

Tool Go membaca versi langsung dari tag repository git. Demo berikut dijalankan nyata pada direktori sementara: module contoh.com/penyimpan diberi dua rilis berurutan:

bash
git add -A && git commit -m "fitur awal: Simpan" && git tag v1.0.0
git add -A && git commit -m "tambah fungsi Muat" && git tag v1.1.0

Pengecekan tag yang sudah terpasang:

bash
git tag -l

Output yang Dihasilkan:

text
v1.0.0
v1.1.0

Riwayat commit memperlihatkan tempat setiap rilis dipancangkan:

bash
git log --oneline --decorate

Output yang Dihasilkan:

text
e700ab8 (HEAD -> main, tag: v1.1.0) tambah fungsi Muat
e23f04b (tag: v1.0.0) fitur awal: Simpan

Dua ketentuan penting: tag wajib berawalan huruf v (v1.1.0, bukan 1.1.0), dan satu versi hanya boleh dipancangkan sekali — memindahkan tag yang sudah dikonsumsi membuat checksum di go.sum pemakai tidak cocok lagi.

Mengonsumsi Versi Tertentu #

Pembuat module memakai require di go.mod. Konsumen demo berikut menunjuk versi v1.1.0 dengan replace menuju repo lokal agar bisa dijalankan tanpa publikasi (mekanisme dari chapter go.work ):

text
module contoh.com/pengguna

go 1.27.2

require contoh.com/penyimpan v1.1.0

replace contoh.com/penyimpan => ../repo

Program pemanggil menggunakan penyimpan.Simpan dan penyimpan.Muat, lalu berjalan dengan sukses:

text
4 5

Daftar versi yang benar-benar terpasang bisa diperiksa kapan saja:

bash
go list -m all

Output yang Dihasilkan:

text
contoh.com/pengguna
contoh.com/penyimpan v1.1.0 => ../repo

Pada kondisi nyata tanpa replace, baris kedua menunjukkan versi hasil unduhan dari proxy — mekanismenya identik.

Major v2: Pindah Alamat ke /v2 #

Inilah aturan yang paling sering menjegal pendatang: rilis major 2 atau lebih mewajibkan module path baru berakhiran /v2. Perubahan dilakukan di go.mod module yang dirilis — module contoh.com/penyimpan/v2 — lalu ditandai git tag v2.0.0. Konsumen yang mencoba import path baru tanpa require akan menemui jalan buntu yang justru sehat:

go
import "contoh.com/penyimpan/v2"

Output yang Dihasilkan (sebelum require ditambahkan):

text
main.go:6:2: no required module provides package contoh.com/penyimpan/v2; to add it:
	go get contoh.com/penyimpan/v2

Setelah require contoh.com/penyimpan/v2 v2.0.0 ditambahkan, program berjalan dan memakai fitur baru:

text
true 5
bash
go list -m all

Output yang Dihasilkan:

text
contoh.com/pengguna2
contoh.com/penyimpan/v2 v2.0.0 => ../repo

Konsumen baru memanggil penyimpan.Hapus("budi") — fungsi khas v2 — dan penyimpan.Muat("siti") dari v1. Pada dunia nyata, perintahnya cukup go get contoh.com/penyimpan/[email protected]: import path, require, dan kode program semuanya menyebut path /v2.

+incompatible dan Pseudo-version #

Dua penanda versi khusus melengkapi rilis. Sufiks +incompatible menandai repository tua yang menandai versi v2.0.0 ke atas sebelum era module (tanpa go.mod) — tetap dapat dikonsumsi sebagai v2.4.0+incompatible, melewati jaminan module path. Sementara itu, pseudo-version muncul ketika kita meminta commit yang tidak berada di tag mana pun: Go menyusun versi sintetis berformat v0.0.0-<waktu-commit-UTC>-<12-karakter-hash>. Commit e700ab8 pada demo kita, seandainya tidak bertag, dikenal lewat timestamp 20260220090000 dan hash pendeknya — dua komponen yang tampak pada git log di atas.

Tag dan versi mengatur bagaimana kode kita diterbitkan; sisi pemakainya — menambahkan, memperbarui, dan membersihkan dependency beserta verifikasi checksum di go.sum — adalah pekerjaan rutin go get, go mod tidy, dan kawan-kawannya, yang kita praktikkan tuntas pada chapter Dependency Management .

Referensi #