From adef82f9ed391ba5e4f0d27582fd6af89d6169f8 Mon Sep 17 00:00:00 2001 From: Noah S-C Date: Tue, 30 Jul 2024 21:52:01 +0100 Subject: [PATCH] feat(bazel): read binary version info from accompanying files in OCI images instead of stamping //internal/version (#63977) https://linear.app/sourcegraph/issue/DINF-111/rework-how-we-inject-version-in-our-artifacts Pros: - saves having to rebuild `bazel query 'kind("go_library", rdeps(//..., //internal/version))' | wc -l` == 523 Go packages when stamp variables cause a rebuild - Cutting out GoLink action time when stamp changes but code is cached Cons: - Binaries themselves are no longer stamped, only knowing their version info within the context of the docker image - A tad extra complexity in internal/version/version.go to handle this new divergence --- Before: ``` $ bazel aquery --output=summary --include_commandline=false --include_artifacts=false --include_aspects=false --stamp 'inputs(".*volatile-status\.txt", //...)' Action: 1 Genrule: 2 Rustc: 3 ConvertStatusToJson: 88 GoLink: 383 ``` After: ``` $ bazel aquery --output=summary --include_commandline=false --include_artifacts=false --include_aspects=false --stamp 'inputs(".*volatile-status\.txt", //...)' Mnemonics: Genrule: 2 Action: 3 Rustc: 3 ConvertStatusToJson: 86 ``` ## Test plan Lots of building & rebuilding with stamp flags, comparing execution logs & times ## Changelog --- cmd/frontend/image_test.yaml | 10 +++++++++ cmd/server/image_test.yaml | 10 +++++++++ dev/oci_defs.bzl | 1 + internal/version/BUILD.bazel | 41 +++++++++++++++++++++++++++++++----- internal/version/version.go | 10 +++++++++ 5 files changed, 67 insertions(+), 5 deletions(-) diff --git a/cmd/frontend/image_test.yaml b/cmd/frontend/image_test.yaml index 0e9b870136c..e69c492f32a 100644 --- a/cmd/frontend/image_test.yaml +++ b/cmd/frontend/image_test.yaml @@ -20,6 +20,16 @@ fileExistenceTests: shouldExist: true uid: 100 gid: 101 +- name: '/version.txt' + path: '/version.txt' + shouldExist: true + uid: 0 + gid: 0 +- name: '/timestamp.txt' + path: '/timestamp.txt' + shouldExist: true + uid: 0 + gid: 0 metadataTest: envVars: diff --git a/cmd/server/image_test.yaml b/cmd/server/image_test.yaml index 8091e31cfd1..a1562c067c1 100644 --- a/cmd/server/image_test.yaml +++ b/cmd/server/image_test.yaml @@ -102,6 +102,16 @@ fileExistenceTests: uid: 0 gid: 0 permissions: '-rwxrwxrwx' +- name: '/version.txt' + path: '/version.txt' + shouldExist: true + uid: 0 + gid: 0 +- name: '/timestamp.txt' + path: '/timestamp.txt' + shouldExist: true + uid: 0 + gid: 0 metadataTest: envVars: diff --git a/dev/oci_defs.bzl b/dev/oci_defs.bzl index 60be494d835..77be35cd716 100644 --- a/dev/oci_defs.bzl +++ b/dev/oci_defs.bzl @@ -26,6 +26,7 @@ def oci_tarball(name, **kwargs): def oci_image(name, **kwargs): _oci_image( name = name + "_underlying", + tars = kwargs.pop("tars", []) + ["//internal/version:stamps"], **kwargs ) diff --git a/internal/version/BUILD.bazel b/internal/version/BUILD.bazel index 6520055a03e..60ea59bef9b 100644 --- a/internal/version/BUILD.bazel +++ b/internal/version/BUILD.bazel @@ -1,5 +1,7 @@ -load("//dev:go_defs.bzl", "go_test") +load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") load("@io_bazel_rules_go//go:def.bzl", "go_library") +load("@rules_pkg//:pkg.bzl", "pkg_tar") +load("//dev:go_defs.bzl", "go_test") go_library( name = "version", @@ -7,10 +9,6 @@ go_library( importpath = "github.com/sourcegraph/sourcegraph/internal/version", tags = [TAG_INFRA_RELEASE], visibility = ["//:__subpackages__"], - x_defs = { - "github.com/sourcegraph/sourcegraph/internal/version.version": "{STABLE_VERSION}", - "github.com/sourcegraph/sourcegraph/internal/version.timestamp": "{VERSION_TIMESTAMP}", - }, deps = ["//lib/errors"], ) @@ -21,3 +19,36 @@ go_test( embed = [":version"], tags = [TAG_INFRA_RELEASE], ) + +pkg_tar( + name = "stamps", + srcs = [ + ":timestamp_file", + ":version_file", + ], + visibility = ["//visibility:public"], +) + +expand_template( + name = "version_file", + out = "version.txt", + stamp_substitutions = { + "STABLE_VERSION": "{{STABLE_VERSION}}", + }, + substitutions = { + "STABLE_VERSION": "0.0.0+dev", + }, + template = ["STABLE_VERSION"], +) + +expand_template( + name = "timestamp_file", + out = "timestamp.txt", + stamp_substitutions = { + "VERSION_TIMESTAMP": "{{VERSION_TIMESTAMP}}", + }, + substitutions = { + "VERSION_TIMESTAMP": "", + }, + template = ["VERSION_TIMESTAMP"], +) diff --git a/internal/version/version.go b/internal/version/version.go index ad43d40ee91..44bf39de472 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -25,6 +25,16 @@ var LastMinorVersionInMajorRelease = map[int]int{ } func init() { + versionFromFile, err := os.ReadFile("/version.txt") + if err == nil { + version = string(versionFromFile) + } + + timestampFromFile, err := os.ReadFile("/timestamp.txt") + if err == nil && len(timestampFromFile) > 0 { + timestamp = string(timestampFromFile) + } + exportedVersion := expvar.NewString("sourcegraph.version") exportedVersion.Set(version) }