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
This commit is contained in:
Cole Faust 2023-09-28 13:56:30 -07:00
parent eba51bf937
commit 583dfb426f
3 changed files with 42 additions and 25 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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)