From 583dfb426f40302a35cb0a321422278419583171 Mon Sep 17 00:00:00 2001 From: Cole Faust Date: Thu, 28 Sep 2023 13:56:30 -0700 Subject: [PATCH] Generate build_number.txt only once build_number.txt was generated in runKati, and runKati is run multiple times throughout the build. If a build number is not set, then one will be generated using the current timestamp, meaning that multiple different build numbers will be used in different phases of the build. Instead, generate build_number.txt during SetupOutDir(), so that we only have 1 build number. This is a resubmission with a change to ensure out/soong is created before writing the build number file. Bug: 297269187 Test: edit a bzl file to force bazel to rerun, change the code so that use_fixed_timestamp=true during partition builds, m installclean, m bazel_sandwich, and observe that the bazel/make partitions are byte-for-byte identical Change-Id: I47abcca166c701bb66a6a7731aecad5818279244 --- ui/build/build.go | 30 ++++++++++++++++++++++++++++-- ui/build/config.go | 11 +++++++++++ ui/build/kati.go | 26 +++----------------------- 3 files changed, 42 insertions(+), 25 deletions(-) diff --git a/ui/build/build.go b/ui/build/build.go index 14d23a7da..9d5c330e1 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -15,11 +15,13 @@ package build import ( + "fmt" "io/ioutil" "os" "path/filepath" "sync" "text/template" + "time" "android/soong/ui/metrics" ) @@ -29,6 +31,7 @@ import ( func SetupOutDir(ctx Context, config Config) { ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk")) ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk")) + ensureEmptyDirectoriesExist(ctx, config.TempDir()) // Potentially write a marker file for whether kati is enabled. This is used by soong_build to // potentially run the AndroidMk singleton and postinstall commands. @@ -56,6 +59,31 @@ func SetupOutDir(ctx Context, config Config) { } else { ctx.Fatalln("Missing BUILD_DATETIME_FILE") } + + // BUILD_NUMBER should be set to the source control value that + // represents the current state of the source code. E.g., a + // perforce changelist number or a git hash. Can be an arbitrary string + // (to allow for source control that uses something other than numbers), + // but must be a single word and a valid file name. + // + // If no BUILD_NUMBER is set, create a useful "I am an engineering build + // from this date/time" value. Make it start with a non-digit so that + // anyone trying to parse it as an integer will probably get "0". + buildNumber, ok := config.environ.Get("BUILD_NUMBER") + if ok { + writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber) + } else { + var username string + if username, ok = config.environ.Get("BUILD_USERNAME"); !ok { + ctx.Fatalln("Missing BUILD_USERNAME") + } + buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */)) + writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username) + } + // Write the build number to a file so it can be read back in + // without changing the command line every time. Avoids rebuilds + // when using ninja. + writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber) } var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(` @@ -246,8 +274,6 @@ func Build(ctx Context, config Config) { // checkCaseSensitivity issues a warning if a case-insensitive file system is being used. checkCaseSensitivity(ctx, config) - ensureEmptyDirectoriesExist(ctx, config.TempDir()) - SetupPath(ctx, config) what := evaluateWhatToRun(config, ctx.Verboseln) diff --git a/ui/build/config.go b/ui/build/config.go index 084d28d83..f80868c33 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -22,6 +22,7 @@ import ( "math/rand" "os" "os/exec" + "os/user" "path/filepath" "runtime" "strconv" @@ -455,6 +456,16 @@ func NewConfig(ctx Context, args ...string) Config { ret.environ.Set("BUILD_DATETIME_FILE", buildDateTimeFile) + if _, ok := ret.environ.Get("BUILD_USERNAME"); !ok { + username := "unknown" + if u, err := user.Current(); err == nil { + username = u.Username + } else { + ctx.Println("Failed to get current user:", err) + } + ret.environ.Set("BUILD_USERNAME", username) + } + if ret.UseRBE() { for k, v := range getRBEVars(ctx, Config{ret}) { ret.environ.Set(k, v) diff --git a/ui/build/kati.go b/ui/build/kati.go index aea56d31a..31e744029 100644 --- a/ui/build/kati.go +++ b/ui/build/kati.go @@ -15,6 +15,8 @@ package build import ( + "android/soong/ui/metrics" + "android/soong/ui/status" "crypto/md5" "fmt" "io/ioutil" @@ -22,10 +24,6 @@ import ( "os/user" "path/filepath" "strings" - "time" - - "android/soong/ui/metrics" - "android/soong/ui/status" ) var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_") @@ -198,32 +196,14 @@ func runKati(ctx Context, config Config, extraSuffix string, args []string, envF } } writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname) - - // BUILD_NUMBER should be set to the source control value that - // represents the current state of the source code. E.g., a - // perforce changelist number or a git hash. Can be an arbitrary string - // (to allow for source control that uses something other than numbers), - // but must be a single word and a valid file name. - // - // If no BUILD_NUMBER is set, create a useful "I am an engineering build - // from this date/time" value. Make it start with a non-digit so that - // anyone trying to parse it as an integer will probably get "0". - cmd.Environment.Unset("HAS_BUILD_NUMBER") - buildNumber, ok := cmd.Environment.Get("BUILD_NUMBER") + _, ok = cmd.Environment.Get("BUILD_NUMBER") // Unset BUILD_NUMBER during kati run to avoid kati rerun, kati will use BUILD_NUMBER from a file. cmd.Environment.Unset("BUILD_NUMBER") if ok { cmd.Environment.Set("HAS_BUILD_NUMBER", "true") - writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber) } else { - buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */)) cmd.Environment.Set("HAS_BUILD_NUMBER", "false") - writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username) } - // Write the build number to a file so it can be read back in - // without changing the command line every time. Avoids rebuilds - // when using ninja. - writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber) // Apply the caller's function closure to mutate the environment variables. envFunc(cmd.Environment)