From d9f25b342bebccf0e627da4587c8cbc3d9e08ebd Mon Sep 17 00:00:00 2001 From: Matt Robenolt Date: Mon, 12 Jun 2023 10:10:51 -0700 Subject: [PATCH 1/3] Read release info from build info Since go1.18, vcs.revision gets compiled into the binary and can be read. Conveniently, debug.ReadBuildInfo has been around since go1.12, so there's no need to conditionally compile this unless sentry-go needs to support < go1.12 for some reason. So in builds newer than 1.18, this key just simply won't exist and effectively will do nothing. This is much more convenient to detect in anything go1.18 since it's much more common to have this compiled in. --- util.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/util.go b/util.go index e5717c631..1866f492c 100644 --- a/util.go +++ b/util.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "os" + "runtime/debug" "strings" "time" @@ -66,6 +67,15 @@ func defaultRelease() (release string) { } } + if info, ok := debug.ReadBuildInfo(); ok { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" && setting.Value != "" { + Logger.Printf("Using release from debug info: %s", setting.Value) + return setting.Value + } + } + } + // Derive a version string from Git. Example outputs: // v1.0.1-0-g9de4 // v2.0-8-g77df-dirty From 3a938c65ac7407513f0af5dc8f1efac504b2fbfe Mon Sep 17 00:00:00 2001 From: Arun Philip Date: Wed, 23 Aug 2023 13:59:26 -0400 Subject: [PATCH 2/3] refactor build info collection to unit test, add unit tests for using debug.ReadBuildInfo for release --- helpers_test.go | 23 +++++++++++++++ util.go | 19 ++++++++---- util_test.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 5 deletions(-) diff --git a/helpers_test.go b/helpers_test.go index 5821f5b46..434845763 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -2,8 +2,31 @@ package sentry import ( "github.com/getsentry/sentry-go/internal/testutils" + "os" ) var assertEqual = testutils.AssertEqual var assertNotEqual = testutils.AssertNotEqual var assertBaggageStringsEqual = testutils.AssertBaggageStringsEqual + +func envSetter(envs map[string]string) (closer func()) { + originalEnvs := map[string]string{} + + for name, value := range envs { + if originalValue, ok := os.LookupEnv(name); ok { + originalEnvs[name] = originalValue + } + _ = os.Setenv(name, value) + } + + return func() { + for name := range envs { + origValue, has := originalEnvs[name] + if has { + _ = os.Setenv(name, origValue) + } else { + _ = os.Unsetenv(name) + } + } + } +} diff --git a/util.go b/util.go index 1866f492c..47f814850 100644 --- a/util.go +++ b/util.go @@ -68,11 +68,9 @@ func defaultRelease() (release string) { } if info, ok := debug.ReadBuildInfo(); ok { - for _, setting := range info.Settings { - if setting.Key == "vcs.revision" && setting.Value != "" { - Logger.Printf("Using release from debug info: %s", setting.Value) - return setting.Value - } + buildInfoVcsRevision := revisionFromBuildInfo(info) + if len(buildInfoVcsRevision) > 0 { + return buildInfoVcsRevision } } @@ -99,3 +97,14 @@ func defaultRelease() (release string) { Logger.Printf("Using release from Git: %s", release) return release } + +func revisionFromBuildInfo(info *debug.BuildInfo) string { + for _, setting := range info.Settings { + if setting.Key == "vcs.revision" && setting.Value != "" { + Logger.Printf("Using release from debug info: %s", setting.Value) + return setting.Value + } + } + + return "" +} diff --git a/util_test.go b/util_test.go index 409e91f4e..eba31b33a 100644 --- a/util_test.go +++ b/util_test.go @@ -1,6 +1,7 @@ package sentry import ( + "runtime/debug" "testing" ) @@ -27,3 +28,80 @@ func TestFileExistsReturnsFalseForNonExistingFiles(t *testing.T) { assertEqual(t, fileExists(("util_nope.go")), false) assertEqual(t, fileExists(("util_nope_test.go")), false) } + +func TestDefaultReleaseSentryReleaseEnvvar(t *testing.T) { + releaseVersion := "1.2.3" + cleanup := envSetter(map[string]string{ + "SENTRY_RELEASE": releaseVersion, + }) + + assertEqual(t, defaultRelease(), releaseVersion) + + t.Cleanup(cleanup) +} + +func TestDefaultReleaseSentryReleaseEnvvarPrecedence(t *testing.T) { + releaseVersion := "1.2.3" + cleanup := envSetter(map[string]string{ + "SOURCE_VERSION": "3.2.1", + "SENTRY_RELEASE": releaseVersion, + }) + + assertEqual(t, defaultRelease(), releaseVersion) + + t.Cleanup(cleanup) +} + +func TestRevisionFromBuildInfo(t *testing.T) { + releaseVersion := "deadbeef" + + info := &debug.BuildInfo{ + Main: debug.Module{ + Path: "my/module", + Version: "(devel)", + }, + Deps: []*debug.Module{ + { + Path: "github.com/getsentry/sentry-go", + Version: "v0.23.1", + Replace: &debug.Module{ + Path: "pkg/sentry", + }, + }, + }, + Settings: []debug.BuildSetting{ + { + Key: "vcs.revision", + Value: releaseVersion, + }, + }, + } + cleanup := envSetter(map[string]string{}) + + assertEqual(t, revisionFromBuildInfo(info), releaseVersion) + + t.Cleanup(cleanup) +} + +func TestRevisionFromBuildInfoNoVcsInformation(t *testing.T) { + info := &debug.BuildInfo{ + Main: debug.Module{ + Path: "my/module", + Version: "(devel)", + }, + Deps: []*debug.Module{ + { + Path: "github.com/getsentry/sentry-go", + Version: "v0.23.1", + Replace: &debug.Module{ + Path: "pkg/sentry", + }, + }, + }, + } + cleanup := envSetter(map[string]string{}) + + assertEqual(t, revisionFromBuildInfo(info), "") + + t.Cleanup(cleanup) +} From 434cad0157ad5c0e53fa9c4fe645d3fc59225666 Mon Sep 17 00:00:00 2001 From: Arun Philip Date: Wed, 30 Aug 2023 14:43:17 -0400 Subject: [PATCH 3/3] use builtin t.Setenv instead of custom envSetter helper --- helpers_test.go | 23 ----------------------- util_test.go | 20 +++----------------- 2 files changed, 3 insertions(+), 40 deletions(-) diff --git a/helpers_test.go b/helpers_test.go index 434845763..5821f5b46 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -2,31 +2,8 @@ package sentry import ( "github.com/getsentry/sentry-go/internal/testutils" - "os" ) var assertEqual = testutils.AssertEqual var assertNotEqual = testutils.AssertNotEqual var assertBaggageStringsEqual = testutils.AssertBaggageStringsEqual - -func envSetter(envs map[string]string) (closer func()) { - originalEnvs := map[string]string{} - - for name, value := range envs { - if originalValue, ok := os.LookupEnv(name); ok { - originalEnvs[name] = originalValue - } - _ = os.Setenv(name, value) - } - - return func() { - for name := range envs { - origValue, has := originalEnvs[name] - if has { - _ = os.Setenv(name, origValue) - } else { - _ = os.Unsetenv(name) - } - } - } -} diff --git a/util_test.go b/util_test.go index eba31b33a..e6a5568fb 100644 --- a/util_test.go +++ b/util_test.go @@ -31,25 +31,17 @@ func TestFileExistsReturnsFalseForNonExistingFiles(t *testing.T) { func TestDefaultReleaseSentryReleaseEnvvar(t *testing.T) { releaseVersion := "1.2.3" - cleanup := envSetter(map[string]string{ - "SENTRY_RELEASE": releaseVersion, - }) + t.Setenv("SENTRY_RELEASE", releaseVersion) assertEqual(t, defaultRelease(), releaseVersion) - - t.Cleanup(cleanup) } func TestDefaultReleaseSentryReleaseEnvvarPrecedence(t *testing.T) { releaseVersion := "1.2.3" - cleanup := envSetter(map[string]string{ - "SOURCE_VERSION": "3.2.1", - "SENTRY_RELEASE": releaseVersion, - }) + t.Setenv("SOURCE_VERSION", "3.2.1") + t.Setenv("SENTRY_RELEASE", releaseVersion) assertEqual(t, defaultRelease(), releaseVersion) - - t.Cleanup(cleanup) } func TestRevisionFromBuildInfo(t *testing.T) { @@ -76,11 +68,8 @@ func TestRevisionFromBuildInfo(t *testing.T) { }, }, } - cleanup := envSetter(map[string]string{}) assertEqual(t, revisionFromBuildInfo(info), releaseVersion) - - t.Cleanup(cleanup) } func TestRevisionFromBuildInfoNoVcsInformation(t *testing.T) { @@ -99,9 +88,6 @@ func TestRevisionFromBuildInfoNoVcsInformation(t *testing.T) { }, }, } - cleanup := envSetter(map[string]string{}) assertEqual(t, revisionFromBuildInfo(info), "") - - t.Cleanup(cleanup) }