From 07cf64da906298e6a9c50f6fdfac625620713137 Mon Sep 17 00:00:00 2001 From: Davis Goodin Date: Fri, 13 Feb 2026 15:38:25 -0800 Subject: [PATCH] Include revision in Microsoft-specific version string --- eng/_util/cmd/build/build.go | 73 ++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/eng/_util/cmd/build/build.go b/eng/_util/cmd/build/build.go index a25d8bef56..65aae7a1f8 100644 --- a/eng/_util/cmd/build/build.go +++ b/eng/_util/cmd/build/build.go @@ -110,6 +110,7 @@ func build(o *options) (err error) { if err != nil { return err } + goRootDir := filepath.Join(rootDir, "go") if o.Refresh { config, err := patch.FindAncestorConfig(rootDir) @@ -142,6 +143,45 @@ func build(o *options) (err error) { return err } + // Next, make sure VERSION and MICROSOFT_REVISION files are in the Go root. We need them for + // different reasons. + // + // A VERSION file is necessary to make distpack run. The build runs fine without this file, + // but for consistency with MICROSOFT_REVISION, we include VERSION during the build as well. + var version string + if data, err := os.ReadFile(filepath.Join(goRootDir, "VERSION")); err != nil { + if errors.Is(err, os.ErrNotExist) { + // If the Go root doesn't have a VERSION file, we're either in main or a prerelease + // branch. distpack needs a VERSION file to run, so create a temp dev version and put it + // in VERSION. + if version, err = writeDevelVersionFile(goRootDir, executableExtension); err != nil { + return fmt.Errorf("unable to write development VERSION file: %v", err) + } + // Best effort: clean up the VERSION file when we're done with the build. Clean up for + // tidier dev workflows: the temp VERSION file should never be checked in. + defer os.Remove(filepath.Join(goRootDir, "VERSION")) + } else { + return fmt.Errorf("unable to read VERSION file for unexpected reason: %v", err) + } + } else { + version, _, _ = strings.Cut(string(data), "\n") + } + + // A MICROSOFT_REVISION file only exists in a release branch. We need to copy it in before + // running the build (not only copy it into the tar.gz output) because it's used during the + // build to generate the "src/internal/buildcfg/zbootstrap.go" file. + microsoftRevisionDst := filepath.Join(goRootDir, "MICROSOFT_REVISION") + if err := copyFile(microsoftRevisionDst, filepath.Join(rootDir, "MICROSOFT_REVISION")); err != nil { + if !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("unable to read MICROSOFT_REVISION file for unexpected reason: %v", err) + } + // Ok: a main branch or pre-stable release branch has no MICROSOFT_REVISION file. + } else { + // Best effort: clean up the MICROSOFT_REVISION file when we're done. Clean up for + // tidier dev workflows: the temp MICROSOFT_REVISION file should never be checked in. + defer os.Remove(microsoftRevisionDst) + } + // The upstream build scripts in {repo-root}/src require your working directory to be src, or // they instantly fail. Change the current process dir so that we can run them. if err := os.Chdir("go/src"); err != nil { @@ -213,7 +253,6 @@ func build(o *options) (err error) { } } - goRootDir := filepath.Join(rootDir, "go") if o.CreatePDB { if _, err := exec.LookPath("gopdb"); err != nil { return fmt.Errorf("gopdb not found in PATH: %v", err) @@ -262,37 +301,6 @@ func build(o *options) (err error) { } if o.PackBuild || o.PackSource { - // distpack needs a VERSION file to run. If we're on the main branch, we don't have one, so - // use dist's version calculation to create a temp dev version and put it in VERSION. - var version string - if data, err := os.ReadFile(filepath.Join(goRootDir, "VERSION")); err != nil { - if errors.Is(err, os.ErrNotExist) { - if version, err = writeDevelVersionFile(goRootDir, executableExtension); err != nil { - return fmt.Errorf("unable to pack: failed writing development VERSION file: %v", err) - } - // Best effort: clean up the VERSION file when we're done. Clean up for tidier dev - // workflows: the temp VERSION file should never be checked in. - defer os.Remove(filepath.Join(goRootDir, "VERSION")) - } else { - return fmt.Errorf("unable to pack: VERSION file in unexpected state: %v", err) - } - } else { - version, _, _ = strings.Cut(string(data), "\n") - } - // We also need to copy our MICROSOFT_REVISION file in so the toolset can report that it's a - // Microsoft build of a specific revision and embed that info into built binaries. - microsoftRevisionDst := filepath.Join(goRootDir, "MICROSOFT_REVISION") - if err := copyFile(microsoftRevisionDst, filepath.Join(rootDir, "MICROSOFT_REVISION")); err != nil { - if !errors.Is(err, os.ErrNotExist) { - return fmt.Errorf("unable to pack: failed to read MICROSOFT_REVISION file for unexpected reason: %v", err) - } - // Ok: a main branch or pre-stable release branch has no MICROSOFT_REVISION file. - } else { - // Best effort: clean up the MICROSOFT_REVISION file when we're done. Clean up for - // tidier dev workflows: the temp MICROSOFT_REVISION file should never be checked in. - defer os.Remove(microsoftRevisionDst) - } - cmd := exec.Command(filepath.Join(goRootDir, "bin", "go"+executableExtension), "tool", "distpack") cmd.Env = append(os.Environ(), "GOROOT="+goRootDir) cmd.Stdout = os.Stdout @@ -342,6 +350,7 @@ func build(o *options) (err error) { } func writeDevelVersionFile(goRootDir, executableExtension string) (string, error) { + // Use "go tool dist version" to directly get the version the toolset would call itself. cmd := exec.Command(filepath.Join(goRootDir, "bin", "go"+executableExtension), "tool", "dist", "version") cmd.Env = append(os.Environ(), "GOROOT="+goRootDir) vBytes, err := cmd.CombinedOutput()