Repository: FerretDB/FerretDB (Go)

Issue:
Generate and use package.txt
### What should be done?

We should generate `build/version/package.txt` file with:
* `deb` for .deb packages;
* `rpm` for .rpm packages;
* `docker` for Docker images;
* `bin` for our binaries.

We should use that file like we use `branch.txt`: in envtool, logging, metrics, telemetry, etc.

### Where?

https://github.com/FerretDB/FerretDB/tree/main/build and build system.

### Definition of Done

- unit tests added;
- integration tests added?
- spot refactorings done;
- user documentation updated;
- something else?



Discussion:

Patch:
diff --git a/build/version/version.go b/build/version/version.go
index 53d979d2f312..21e440b01283 100644
--- a/build/version/version.go
+++ b/build/version/version.go
@@ -21,6 +21,7 @@
 //     similar to `git describe` output: `v<major>.<minor>.<patch>`.
 //   - commit.txt (optional) contains information about the source git commit.
 //   - branch.txt (optional) contains information about the source git branch.
+//   - package.txt (optional) contains package type (e.g. "deb", "rpm", "docker", etc).
 //
 // # Go build tags
 //
@@ -68,6 +69,7 @@ type Info struct {
 	Commit           string
 	Branch           string
 	Dirty            bool
+	Package          string // TODO https://github.com/FerretDB/FerretDB/issues/1805
 	DebugBuild       bool
 	BuildEnvironment *types.Document
 
@@ -107,6 +109,7 @@ func init() {
 		Commit:              unknown,
 		Branch:              unknown,
 		Dirty:               false,
+		Package:             unknown, // TODO https://github.com/FerretDB/FerretDB/issues/1805
 		DebugBuild:          debugBuild,
 		BuildEnvironment:    must.NotFail(types.NewDocument()),
 		MongoDBVersion:      mongoDBVersion,
@@ -125,8 +128,15 @@ func init() {
 		return
 	}
 
-	if b, _ := gen.ReadFile("version.txt"); len(b) > 0 {
-		info.Version = strings.TrimSpace(string(b))
+	for f, sp := range map[string]*string{
+		"version.txt": &info.Version,
+		"commit.txt":  &info.Commit,
+		"branch.txt":  &info.Branch,
+		"package.txt": &info.Package,
+	} {
+		if b, _ := gen.ReadFile(f); len(b) > 0 {
+			*sp = strings.TrimSpace(string(b))
+		}
 	}
 
 	if !strings.HasPrefix(info.Version, "v") {
@@ -137,14 +147,6 @@ func init() {
 		panic(msg)
 	}
 
-	if b, _ := gen.ReadFile("commit.txt"); len(b) > 0 {
-		info.Commit = strings.TrimSpace(string(b))
-	}
-
-	if b, _ := gen.ReadFile("branch.txt"); len(b) > 0 {
-		info.Branch = strings.TrimSpace(string(b))
-	}
-
 	for _, s := range buildInfo.Settings {
 		switch s.Key {
 		case "vcs.revision":
diff --git a/cmd/envtool/envtool.go b/cmd/envtool/envtool.go
index 30d64ced5bb0..38b4b3fa3867 100644
--- a/cmd/envtool/envtool.go
+++ b/cmd/envtool/envtool.go
@@ -278,6 +278,7 @@ func printDiagnosticData(setupError error, logger *zap.SugaredLogger) {
 		"Commit":     info.Commit,
 		"Branch":     info.Branch,
 		"Dirty":      info.Dirty,
+		"Package":    info.Package,
 		"DebugBuild": info.DebugBuild,
 
 		"GoVersion":      runtime.Version(),
diff --git a/cmd/ferretdb/main.go b/cmd/ferretdb/main.go
index c74ebb68ae55..5893f754b462 100644
--- a/cmd/ferretdb/main.go
+++ b/cmd/ferretdb/main.go
@@ -182,6 +182,7 @@ func setupLogger(stateProvider *state.Provider) *zap.Logger {
 		zap.String("commit", info.Commit),
 		zap.String("branch", info.Branch),
 		zap.Bool("dirty", info.Dirty),
+		zap.String("package", info.Package),
 		zap.Bool("debugBuild", info.DebugBuild),
 		zap.Any("buildEnvironment", info.BuildEnvironment.Map()),
 	}
@@ -239,6 +240,7 @@ func run() {
 		fmt.Fprintln(os.Stdout, "commit:", info.Commit)
 		fmt.Fprintln(os.Stdout, "branch:", info.Branch)
 		fmt.Fprintln(os.Stdout, "dirty:", info.Dirty)
+		fmt.Fprintln(os.Stdout, "package:", info.Package)
 		fmt.Fprintln(os.Stdout, "debugBuild:", info.DebugBuild)
 
 		return
diff --git a/internal/util/state/metrics.go b/internal/util/state/metrics.go
index bea4e0f44bc4..35394518f5a6 100644
--- a/internal/util/state/metrics.go
+++ b/internal/util/state/metrics.go
@@ -56,6 +56,7 @@ func (mc *metricsCollector) Collect(ch chan<- prometheus.Metric) {
 		"commit":  v.Commit,
 		"branch":  v.Branch,
 		"dirty":   strconv.FormatBool(v.Dirty),
+		"package": v.Package,
 		"debug":   strconv.FormatBool(v.DebugBuild),
 	}
 
diff --git a/internal/util/telemetry/reporter.go b/internal/util/telemetry/reporter.go
index 30c654517772..cb7622446d47 100644
--- a/internal/util/telemetry/reporter.go
+++ b/internal/util/telemetry/reporter.go
@@ -38,6 +38,7 @@ type request struct {
 	Commit           string         `json:"commit"`
 	Branch           string         `json:"branch"`
 	Dirty            bool           `json:"dirty"`
+	Package          string         `json:"-"` // TODO https://github.com/FerretDB/FerretDB/issues/1805
 	Debug            bool           `json:"debug"`
 	BuildEnvironment map[string]any `json:"build_environment"`
 	OS               string         `json:"os"`
@@ -189,6 +190,7 @@ func makeRequest(s *state.State, m *connmetrics.ConnMetrics) *request {
 		Commit:           v.Commit,
 		Branch:           v.Branch,
 		Dirty:            v.Dirty,
+		Package:          v.Package,
 		Debug:            v.DebugBuild,
 		BuildEnvironment: v.BuildEnvironment.Map(),
 		OS:               runtime.GOOS,


Test patch:
diff --git a/internal/util/state/metrics_test.go b/internal/util/state/metrics_test.go
index 3b3bdea976b3..4b3cbb2b599e 100644
--- a/internal/util/state/metrics_test.go
+++ b/internal/util/state/metrics_test.go
@@ -46,11 +46,12 @@ func TestMetrics(t *testing.T) {
 		require.NoError(t, err)
 		require.Empty(t, problems)
 
+		//nolint:lll // it is more readable this way
 		expected := fmt.Sprintf(
 			`
 				# HELP ferretdb_up FerretDB instance state.
 				# TYPE ferretdb_up gauge
-				ferretdb_up{branch=%q,commit=%q,debug="%t",dirty="%t",telemetry="undecided",uuid=%q,version=%q} 1
+				ferretdb_up{branch=%q,commit=%q,debug="%t",dirty="%t",package="unknown",telemetry="undecided",uuid=%q,version=%q} 1
 			`,
 			v.Branch, v.Commit, v.DebugBuild, v.Dirty, uuid, v.Version,
 		)
@@ -69,7 +70,7 @@ func TestMetrics(t *testing.T) {
 			`
 				# HELP ferretdb_up FerretDB instance state.
 				# TYPE ferretdb_up gauge
-				ferretdb_up{branch=%q,commit=%q,debug="%t",dirty="%t",telemetry="undecided",version=%q} 1
+				ferretdb_up{branch=%q,commit=%q,debug="%t",dirty="%t",package="unknown",telemetry="undecided",version=%q} 1
 			`,
 			v.Branch, v.Commit, v.DebugBuild, v.Dirty, v.Version,
 		)