Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 41 additions & 32 deletions eng/_util/cmd/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now runs before the build happens, which doesn't work. I suppose the VERSION file handling actually needs to stay where it is.

cmd.Env = append(os.Environ(), "GOROOT="+goRootDir)
vBytes, err := cmd.CombinedOutput()
Expand Down
Loading