https://github.com/mfridman/buildversion
Generate release version for Go apps
https://github.com/mfridman/buildversion
build cli golang versioning
Last synced: 8 months ago
JSON representation
Generate release version for Go apps
- Host: GitHub
- URL: https://github.com/mfridman/buildversion
- Owner: mfridman
- Archived: true
- Created: 2024-04-13T17:04:19.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-02-12T02:19:37.000Z (over 1 year ago)
- Last Synced: 2025-02-14T14:53:54.182Z (over 1 year ago)
- Topics: build, cli, golang, versioning
- Language: Go
- Homepage:
- Size: 16.6 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# buildversion
> [!WARNING]
> This package is no longer required as of Go 1.24. The `runtime/debug` package now provides the
> `BuildInfo` struct, which can be used to extract the version information. For more information,
> see https://github.com/golang/go/issues/50603 or the [Go 1.24 release notes](https://go.dev/doc/go1.24#go-command).
>
> _The go build command now sets the main module’s version in the compiled binary based on the
> version control system tag and/or commit. A +dirty suffix will be appended if there are
> uncommitted changes. Use the `-buildvcs=false` flag to omit version control information from the
> binary._
A simple package to generate a release version for Go applications. Compatible with Go modules.
Ideal in CLI tools when you want to display the version using commands such as `mytool --version`.
## Usage
Here's a simple example of how you can use this package in your application. Now when `go build` or
`go install` is run, the version will be stamped into the binary in a consistent way.
```go
package main
import (
"flag"
"fmt"
"os"
"github.com/mfridman/buildversion"
)
func main() {
versionPtr := flag.Bool("version", false, "")
flag.Parse()
if *versionPtr {
fmt.Fprintln(os.Stdout, buildversion.New())
return
}
}
```
### Linking the version at build time
The reason `New()` takes a variadic `string` argument is to allow you to pass in the version at
build time. This can be useful when building a release binary with tools like
[goreleaser](https://goreleaser.com/).
Define a version variable in your main package:
```go
package main
var version string
func main() {
buildversion.New(version)
}
```
Then, when building the binary, pass in the version using the `-ldflags` flag:
```
go build -ldflags "-X main.version=v1.2.3" -o bin/example ./cmd/example
```
## Example
### No tags (pseudo-version)
```
$ go install github.com/mfridman/buildversion/cmd/example@latest
example --version
v0.0.0-20240413170022-fe4dc7cb6b9d
```
### Tagged release
```
$ go install github.com/mfridman/buildversion/cmd/example@latest
example --version
v0.1.0
```
### Building from source
```
$ go build -o bin/example ./cmd/example
./bin/example --version
devel (fe4dc7cb6b9d, dirty)
```
## But why?
I've ended up copying this simple function across a few projects, so I decided to make it a package.
The `New()` function returns the version string from the
[BuildInfo](https://pkg.go.dev/runtime/debug#BuildInfo), if available.
**`New()` will always return a non-empty string.**
- If the build info is not available, it returns `devel`. This can happen if the binary was built
without module support, if the Go version is too old or `-buildvcs=false` was set.
- If building from source, it returns `devel` followed by the first 12 characters of the VCS
revision, followed by `, dirty` if the working directory was dirty. For example,
- `devel (abcdef012345, dirty)`
- `devel (abcdef012345)`
- `devel (unknown revision)`
Note, VCS info not stamped when built listing .go files directly. For example,
```
go build main.go
go build .
```
For more information, see https://github.com/golang/go/issues/51279