diff --git a/Makefile b/Makefile index 7aab102..c2b65e9 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,15 @@ +BUILD_DATE := $(shell date -u +'%Y-%m-%dT%H:%M:%SZ') +BUILD_GIT_COMMIT := $(shell git rev-parse --short HEAD) +BUILD_GIT_TAG := $(shell git describe --tags --abbrev=0 | tr -d '\n') +BUILD_PKG_TAG = $(shell echo $(BUILD_GIT_TAG) | cut -f1 -d.) +BUILD_LDFLAGS := -X 'github.com/mccutchen/go-httpbin/$(BUILD_PKG_TAG)/httpbin.buildDate=$(BUILD_DATE)' -X 'github.com/mccutchen/go-httpbin/$(BUILD_PKG_TAG)/httpbin.buildGitCommit=$(BUILD_GIT_COMMIT)' -X 'github.com/mccutchen/go-httpbin/$(BUILD_PKG_TAG)/httpbin.buildGitTag=$(BUILD_GIT_TAG)' + # The version that will be used in docker tags (e.g. to push a # go-httpbin:latest image use `make imagepush VERSION=latest)` -VERSION ?= $(shell git rev-parse --short HEAD) +VERSION ?= $(BUILD_GIT_TAG) DOCKER_TAG ?= mccutchen/go-httpbin:$(VERSION) + # Built binaries will be placed here DIST_PATH ?= dist @@ -26,7 +33,7 @@ PORT ?= 8080 # ============================================================================= build: mkdir -p $(DIST_PATH) - CGO_ENABLED=0 go build -ldflags="-s -w" -o $(DIST_PATH)/go-httpbin ./cmd/go-httpbin + CGO_ENABLED=0 go build -ldflags="$(BUILD_LDFLAGS) -s -w" -o $(DIST_PATH)/go-httpbin ./cmd/go-httpbin .PHONY: build buildexamples: build @@ -34,7 +41,7 @@ buildexamples: build .PHONY: buildexamples buildtests: - CGO_ENABLED=0 go test -ldflags="-s -w" -v -c -o $(DIST_PATH)/go-httpbin.test ./httpbin + CGO_ENABLED=0 go test -ldflags="$(BUILD_LDFLAGS) -s -w" -v -c -o $(DIST_PATH)/go-httpbin.test ./httpbin .PHONY: buildtests clean: diff --git a/httpbin/handlers.go b/httpbin/handlers.go index 16503f6..0c24063 100644 --- a/httpbin/handlers.go +++ b/httpbin/handlers.go @@ -35,6 +35,13 @@ func (h *HTTPBin) Index(w http.ResponseWriter, r *http.Request) { writeHTML(w, h.indexHTML, http.StatusOK) } +// Version echoes build and version info +func (h *HTTPBin) Version(w http.ResponseWriter, r *http.Request) { + writeJSON(http.StatusOK, w, &versionResponse{ + Version: getVersionInfo(), + }) +} + // FormsPost renders an HTML form that submits a request to the /post endpoint func (h *HTTPBin) FormsPost(w http.ResponseWriter, _ *http.Request) { writeHTML(w, h.formsPostHTML, http.StatusOK) diff --git a/httpbin/httpbin.go b/httpbin/httpbin.go index 82ae6e6..453e6d5 100644 --- a/httpbin/httpbin.go +++ b/httpbin/httpbin.go @@ -185,6 +185,7 @@ func (h *HTTPBin) Handler() http.Handler { mux.HandleFunc("/unstable", h.Unstable) mux.HandleFunc("/user-agent", h.UserAgent) mux.HandleFunc("/uuid", h.UUID) + mux.HandleFunc("/version", h.Version) mux.HandleFunc("/xml", h.XML) // existing httpbin endpoints that we do not support diff --git a/httpbin/responses.go b/httpbin/responses.go index 6b1e82b..a0a3648 100644 --- a/httpbin/responses.go +++ b/httpbin/responses.go @@ -13,6 +13,10 @@ const ( textContentType = "text/plain; charset=utf-8" ) +type versionResponse struct { + Version VersionInfo `json:"version"` +} + type headersResponse struct { Headers http.Header `json:"headers"` } diff --git a/httpbin/version.go b/httpbin/version.go new file mode 100644 index 0000000..9ebc66f --- /dev/null +++ b/httpbin/version.go @@ -0,0 +1,31 @@ +package httpbin + +import ( + "fmt" + "runtime" +) + +var ( + // Values set with ldflags -X at build time + buildDate = "" // ISO-8601 format + buildGitCommit = "" + buildGitTag = "" +) + +type VersionInfo struct { + BuildDate string `json:"buildDate"` + GitCommit string `json:"gitCommit"` + GitVersion string `json:"gitVersion"` + GoVersion string `json:"goVersion"` + Platform string `json:"platform"` +} + +func getVersionInfo() VersionInfo { + return VersionInfo{ + BuildDate: buildDate, + GitCommit: buildGitCommit, + GitVersion: buildGitTag, + GoVersion: runtime.Version(), + Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), + } +}