mirror of
https://github.com/golang/go
synced 2024-11-22 23:50:03 -07:00
cmd/api: disallow silent API additions after api/go1.n.txt is created
At this time, the golang.org/s/release process arranges such that the api/go1.n.txt file is created when a Go 1.N Beta 1 release is being cut. The API check is currently configured so that tests don't fail visibly even if api/go1.n.txt becomes a subset of the actual API additions in the upcoming Go 1.N release as long as 'go version' has "devel" in it. The first time that 'go version' output drops the "devel" substring during testing is after the release-branch.go1.N branch is created as part of the process to cut a Go 1.N Release Candidate 1 release. The month or so between Beta 1 and RC 1 is well into the freeze and deliberate API changes are rare and very intentional. There seems to be agreement that it's healthy to make the API check stricter during that time period. Doing so will ensure that api/go1.n.txt cannot get stale after creation without anyone noticing, and may catch CLs that don't have the intended diff on the API. This CL changes behavior to be simple and clear: from the moment an api/go1.n.txt file corresponding to the current Go version in development is added to the tree, silent API additions stop being permitted. This CL also moves the magical "override the value of -allow_new flag if runtime.Version() contains 'devel' string" behavior from cmd/api command to the run.go script that calls it, making the CLI of cmd/api itself less surprising. Fixes #43956. Change-Id: I89468207573f7ccdbc9f12625dcdd3ef2bcf8f10 Reviewed-on: https://go-review.googlesource.com/c/go/+/315350 Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org> Trust: Dmitri Shuralyov <dmitshur@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Alexander Rakoczy <alex@golang.org>
This commit is contained in:
parent
791854700d
commit
9f347035ef
@ -215,8 +215,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
optional := fileFeatures(*nextFile)
|
optional := fileFeatures(*nextFile)
|
||||||
exception := fileFeatures(*exceptFile)
|
exception := fileFeatures(*exceptFile)
|
||||||
fail = !compareAPI(bw, features, required, optional, exception,
|
fail = !compareAPI(bw, features, required, optional, exception, *allowNew)
|
||||||
*allowNew && strings.Contains(runtime.Version(), "devel"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// export emits the exported package features.
|
// export emits the exported package features.
|
||||||
|
@ -10,8 +10,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
exec "internal/execabs"
|
exec "internal/execabs"
|
||||||
|
"internal/goversion"
|
||||||
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -43,6 +46,7 @@ func main() {
|
|||||||
apiDir := filepath.Join(goroot, "api")
|
apiDir := filepath.Join(goroot, "api")
|
||||||
out, err := exec.Command(goCmd(), "tool", "api",
|
out, err := exec.Command(goCmd(), "tool", "api",
|
||||||
"-c", findAPIDirFiles(apiDir),
|
"-c", findAPIDirFiles(apiDir),
|
||||||
|
allowNew(apiDir),
|
||||||
"-next", filepath.Join(apiDir, "next.txt"),
|
"-next", filepath.Join(apiDir, "next.txt"),
|
||||||
"-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
|
"-except", filepath.Join(apiDir, "except.txt")).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,3 +75,35 @@ func findAPIDirFiles(apiDir string) string {
|
|||||||
}
|
}
|
||||||
return strings.Join(apiFiles, ",")
|
return strings.Join(apiFiles, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allowNew returns the -allow_new flag to use for the 'go tool api' invocation.
|
||||||
|
func allowNew(apiDir string) string {
|
||||||
|
// Verify that the api/go1.n.txt for previous Go version exists.
|
||||||
|
// It definitely should, otherwise it's a signal that the logic below may be outdated.
|
||||||
|
if _, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version-1))); err != nil {
|
||||||
|
log.Fatalln("Problem with api file for previous release:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// See whether the api/go1.n.txt for this Go version has been created.
|
||||||
|
// (As of April 2021, it gets created during the release of the first Beta.)
|
||||||
|
_, err := os.Stat(filepath.Join(apiDir, fmt.Sprintf("go1.%d.txt", goversion.Version)))
|
||||||
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
|
// It doesn't exist, so we're in development or before Beta 1.
|
||||||
|
// At this stage, unmentioned API additions are deemed okay.
|
||||||
|
// (They will be quietly shown in API check output, but the test won't fail).
|
||||||
|
return "-allow_new=true"
|
||||||
|
} else if err == nil {
|
||||||
|
// The api/go1.n.txt for this Go version has been created,
|
||||||
|
// so we're definitely past Beta 1 in the release cycle.
|
||||||
|
//
|
||||||
|
// From this point, enforce that api/go1.n.txt is an accurate and complete
|
||||||
|
// representation of what's going into the release by failing API check if
|
||||||
|
// there are API additions (a month into the freeze, there shouldn't be many).
|
||||||
|
//
|
||||||
|
// See golang.org/issue/43956.
|
||||||
|
return "-allow_new=false"
|
||||||
|
} else {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user