diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index c0da563a5..b09d2b84d 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -17,15 +17,17 @@ jobs: - name: clone uses: actions/checkout@v2 + - name: setup + run: | + # setup git tag in Actions environment + echo "GITHUB_TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV + - name: build env: GOOS: linux CGO_ENABLED: '1' run: | - go build -a \ - -ldflags '-s -w -extldflags "-static"' \ - -o release/vela-server \ - github.com/go-vela/server/cmd/vela-server + make build-static-ci - name: publish uses: elgohr/Publish-Docker-Github-Action@master diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 933856ada..3b8885bc4 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,10 +21,7 @@ jobs: GOOS: linux CGO_ENABLED: '1' run: | - go build -a \ - -ldflags '-s -w -extldflags "-static"' \ - -o release/vela-server \ - github.com/go-vela/server/cmd/vela-server + make build-static-ci - name: publish uses: elgohr/Publish-Docker-Github-Action@master diff --git a/Makefile b/Makefile index b38ca9d17..8fb0897c9 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,30 @@ # # Use of this source code is governed by the LICENSE file in this repository. +# capture the current date we build the application from +BUILD_DATE = $(shell date +%Y-%m-%dT%H:%M:%SZ) + +# check if a git commit sha is already set +ifndef GITHUB_SHA + # capture the current git commit sha we build the application from + GITHUB_SHA = $(shell git rev-parse HEAD) +endif + +# check if a git tag is already set +ifndef GITHUB_TAG + # capture the current git tag we build the application from + GITHUB_TAG = $(shell git describe --tag --abbrev=0) +endif + +# check if a go version is already set +ifndef GOLANG_VERSION + # capture the current go version we build the application from + GOLANG_VERSION = $(shell go version | awk '{ print $$3 }') +endif + +# create a list of linker flags for building the golang application +LD_FLAGS = -X github.com/go-vela/server/version.Commit=${GITHUB_SHA} -X github.com/go-vela/server/version.Date=${BUILD_DATE} -X github.com/go-vela/server/version.Go=${GOLANG_VERSION} -X github.com/go-vela/server/version.Tag=${GITHUB_TAG} + # The `clean` target is intended to clean the workspace # and prepare the local changes for submission. # @@ -104,6 +128,7 @@ build: @echo "### Building release/vela-server binary" GOOS=linux CGO_ENABLED=0 \ go build -a \ + -ldflags '${LD_FLAGS}' \ -o release/vela-server \ github.com/go-vela/server/cmd/vela-server @@ -117,7 +142,21 @@ build-static: @echo "### Building static release/vela-server binary" GOOS=linux CGO_ENABLED=0 \ go build -a \ - -ldflags '-s -w -extldflags "-static"' \ + -ldflags '-s -w -extldflags "-static" ${LD_FLAGS}' \ + -o release/vela-server \ + github.com/go-vela/server/cmd/vela-server + +# The `build-static-ci` target is intended to compile +# the Go source code into a statically linked binary +# when used within a CI environment. +# +# Usage: `make build-static-ci` +.PHONY: build-static-ci +build-static-ci: + @echo + @echo "### Building CI static release/vela-server binary" + @go build -a \ + -ldflags '-s -w -extldflags "-static" ${LD_FLAGS}' \ -o release/vela-server \ github.com/go-vela/server/cmd/vela-server diff --git a/api/version.go b/api/version.go index 5108a8981..e5b5de5e1 100644 --- a/api/version.go +++ b/api/version.go @@ -30,5 +30,5 @@ import ( // Version represents the API handler to // report the version number for Vela. func Version(c *gin.Context) { - c.JSON(http.StatusOK, version.Version.String()) + c.JSON(http.StatusOK, version.New()) } diff --git a/cmd/vela-server/main.go b/cmd/vela-server/main.go index 0906a5a83..bbef49fc8 100644 --- a/cmd/vela-server/main.go +++ b/cmd/vela-server/main.go @@ -17,7 +17,7 @@ func main() { app := cli.NewApp() app.Name = "vela-server" app.Action = server - app.Version = version.Version.String() + app.Version = version.New().Semantic() app.Flags = []cli.Flag{ &cli.StringFlag{ diff --git a/go.mod b/go.mod index 70ea7437f..8b6e57dc9 100644 --- a/go.mod +++ b/go.mod @@ -3,15 +3,15 @@ module github.com/go-vela/server go 1.13 require ( + github.com/Masterminds/semver v1.5.0 github.com/aws/aws-sdk-go v1.34.33 - github.com/coreos/go-semver v0.3.0 github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/frankban/quicktest v1.7.2 // indirect github.com/gin-gonic/gin v1.6.3 github.com/go-redis/redis v6.15.8+incompatible github.com/go-vela/compiler v0.6.0 - github.com/go-vela/types v0.6.0 + github.com/go-vela/types v0.6.1-0.20201019123446-226d0cc72538 github.com/google/go-github/v29 v29.0.3 github.com/google/uuid v1.1.1 github.com/hashicorp/go-hclog v0.10.0 // indirect diff --git a/go.sum b/go.sum index b66fd8d29..ec53fe8e7 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= @@ -90,6 +88,8 @@ github.com/go-vela/compiler v0.6.0 h1:Z0kaz3nfCxAFBnbzuT2qoj5JjlbGckCmpjVr16PtDJ github.com/go-vela/compiler v0.6.0/go.mod h1:chxdAtFcUfJFaewZ5kupqIEjuH+zbK0MDNVc5+Yx4Bg= github.com/go-vela/types v0.6.0 h1:82/+Y3EGnnr37HeaJ5qhz/PGMvLkJfYvblEw1kFwxb4= github.com/go-vela/types v0.6.0/go.mod h1:G1Qp0JFtXV+QRNTEWXht+WdllOhjAGapg9vBZKdj6N0= +github.com/go-vela/types v0.6.1-0.20201019123446-226d0cc72538 h1:ck0Ylos/ExUCluEqQgVxKrTZ21nsup0VZT31sWqTU4Y= +github.com/go-vela/types v0.6.1-0.20201019123446-226d0cc72538/go.mod h1:6r6mWIPrTANBpHwAFAIii64VKtzlAzVagbm/wX5bHHk= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= diff --git a/router/middleware/header.go b/router/middleware/header.go index da1ddb8d6..5e6852104 100644 --- a/router/middleware/header.go +++ b/router/middleware/header.go @@ -65,13 +65,12 @@ func Cors(c *gin.Context) { // information into the request so it will be logged. This is // intended for debugging and troubleshooting. func RequestVersion(c *gin.Context) { - apiVersion := version.Version + v := version.New() if gin.Mode() == "debug" { - c.Request.Header.Set("X-Vela-Version", apiVersion.String()) + c.Request.Header.Set("X-Vela-Version", v.Semantic()) } else { // in prod we don't want the build number metadata - apiVersion.Metadata = "" - c.Request.Header.Set("X-Vela-Version", apiVersion.String()) + c.Request.Header.Set("X-Vela-Version", v.Semantic()) } } @@ -79,12 +78,11 @@ func RequestVersion(c *gin.Context) { // information into the response so it will be logged. This is // intended for debugging and troubleshooting. func ResponseVersion(c *gin.Context) { - apiVersion := version.Version + v := version.New() if gin.Mode() == "debug" { - c.Header("X-Vela-Version", apiVersion.String()) + c.Header("X-Vela-Version", v.Semantic()) } else { // in prod we don't want the build number metadata - apiVersion.Metadata = "" - c.Header("X-Vela-Version", apiVersion.String()) + c.Header("X-Vela-Version", v.Semantic()) } } diff --git a/router/middleware/header_test.go b/router/middleware/header_test.go index 0ea8b4eac..f228d302c 100644 --- a/router/middleware/header_test.go +++ b/router/middleware/header_test.go @@ -290,127 +290,3 @@ func TestMiddleware_Secure_TLS(t *testing.T) { t.Errorf("Secure Strict-Transport-Security is %v, want %v", gotSecurity, wantSecurity) } } - -func TestMiddleware_RequestVersion(t *testing.T) { - // setup types - wantVersion := "0.6.0" - - // setup context - gin.SetMode(gin.DebugMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - - // setup mock server - engine.Use(RequestVersion) - engine.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - gotVersion := context.Request.Header.Get("X-Vela-Version") - - if resp.Code != http.StatusOK { - t.Errorf("RequestVersion returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(gotVersion, wantVersion) { - t.Errorf("RequestVersion X-Vela-Version is %v, want %v", gotVersion, wantVersion) - } -} - -func TestMiddleware_RequestVersion_Prod(t *testing.T) { - // setup types - wantVersion := "0.6.0" - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - - // setup mock server - engine.Use(RequestVersion) - engine.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - gotVersion := context.Request.Header.Get("X-Vela-Version") - - if resp.Code != http.StatusOK { - t.Errorf("RequestVersion returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(gotVersion, wantVersion) { - t.Errorf("RequestVersion X-Vela-Version is %v, want %v", gotVersion, wantVersion) - } -} - -func TestMiddleware_ResponseVersion(t *testing.T) { - // setup types - wantVersion := "0.6.0" - - // setup context - gin.SetMode(gin.DebugMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - - // setup mock server - engine.Use(ResponseVersion) - engine.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - gotVersion := context.Writer.Header().Get("X-Vela-Version") - - if resp.Code != http.StatusOK { - t.Errorf("ResponseVersion returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(gotVersion, wantVersion) { - t.Errorf("ResponseVersion X-Vela-Version is %v, want %v", gotVersion, wantVersion) - } -} - -func TestMiddleware_ResponseVersion_Prod(t *testing.T) { - // setup types - wantVersion := "0.6.0" - - // setup context - gin.SetMode(gin.TestMode) - - resp := httptest.NewRecorder() - context, engine := gin.CreateTestContext(resp) - context.Request, _ = http.NewRequest(http.MethodGet, "/health", nil) - - // setup mock server - engine.Use(ResponseVersion) - engine.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) - - // run test - engine.ServeHTTP(context.Writer, context.Request) - - gotVersion := context.Writer.Header().Get("X-Vela-Version") - - if resp.Code != http.StatusOK { - t.Errorf("ResponseVersion returned %v, want %v", resp.Code, http.StatusOK) - } - - if !reflect.DeepEqual(gotVersion, wantVersion) { - t.Errorf("ResponseVersion X-Vela-Version is %v, want %v", gotVersion, wantVersion) - } -} diff --git a/version/version.go b/version/version.go index e4228153c..6f09e1c4e 100644 --- a/version/version.go +++ b/version/version.go @@ -4,23 +4,52 @@ package version -import "github.com/coreos/go-semver/semver" +import ( + "fmt" + "runtime" + + "github.com/Masterminds/semver" + + "github.com/go-vela/types/version" +) var ( - // VersionMajor is for an API incompatible changes. - VersionMajor int64 - // VersionMinor is for functionality in a backwards-compatible manner. - VersionMinor int64 = 6 - // VersionPatch is for backwards-compatible bug fixes. - VersionPatch int64 - // VersionDev indicates build metadata. Releases will be empty string. - VersionDev string + // Arch represents the architecture information for the package. + Arch = runtime.GOARCH + // Commit represents the git commit information for the package. + Commit string + // Compiler represents the compiler information for the package. + Compiler = runtime.Compiler + // Date represents the build date information for the package. + Date string + // Go represents the golang version information for the package. + Go string + // OS represents the operating system information for the package. + OS = runtime.GOOS + // Tag represents the git tag information for the package. + Tag string ) -// Version is the specification version that the package types support. -var Version = semver.Version{ - Major: VersionMajor, - Minor: VersionMinor, - Patch: VersionPatch, - Metadata: VersionDev, +// New creates a new version object for Vela that is used throughout the application. +func New() *version.Version { + v, err := semver.NewVersion(Tag) + if err != nil { + fmt.Println(fmt.Errorf("unable to parse semantic version for %s: %v", Tag, err)) + } + + return &version.Version{ + Canonical: Tag, + Major: v.Major(), + Minor: v.Minor(), + Patch: v.Patch(), + PreRelease: v.Prerelease(), + Metadata: version.Metadata{ + Architecture: Arch, + BuildDate: Date, + Compiler: Compiler, + GitCommit: Commit, + GoVersion: Go, + OperatingSystem: OS, + }, + } }