internal/releasetargets: create

We duplicate a list of release targets between cmd/releasebot and
cmd/release. The format of the latter is, to me, unpleasant to deal
with. This is an attempt at a better one, more information-dense and
less error-prone.

AFAIK, the only thing that really matters is what builder we should use
to issue the next release in each series. Reproducibility of prior
releases is not so important, especially because when we change builders
mid-stream it's usually involuntary. So, rather than supporting the
full-fledged and quite complicated GoQuery syntax, simply have an entry
per live release series.

Make the minimal changes to integrate the new package into cmd/release
and cmd/releasebot.

For golang/go#51797.

Change-Id: Ic48b1cdd751fb4ea5e2acad8f1898b48faa30cd9
Reviewed-on: https://go-review.googlesource.com/c/build/+/387714
Run-TryBot: Heschi Kreinick <heschi@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Rakoczy <alex@golang.org>
This commit is contained in:
Heschi Kreinick 2022-02-23 15:08:35 -05:00
Родитель 793428baa8
Коммит 3f9de2b7dd
9 изменённых файлов: 449 добавлений и 362 удалений

Просмотреть файл

@ -31,6 +31,8 @@ import (
"golang.org/x/build/buildenv"
"golang.org/x/build/buildlet"
"golang.org/x/build/dashboard"
"golang.org/x/build/internal/releasetargets"
"golang.org/x/build/maintner/maintnerd/maintapi/version"
)
//go:embed releaselet/releaselet.go
@ -42,10 +44,10 @@ var (
stagingDir = flag.String("staging_dir", "", "If specified, use this as the staging directory for untested release artifacts. Default is the system temporary directory.")
rev = flag.String("rev", "", "Go revision to build")
version = flag.String("version", "", "Version string (go1.5.2)")
user = flag.String("user", username(), "coordinator username, appended to 'user-'")
skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash but not all.bash (only use if sufficient testing was done elsewhere)")
rev = flag.String("rev", "", "Go revision to build")
flagVersion = flag.String("version", "", "Version string (go1.5.2)")
user = flag.String("user", username(), "coordinator username, appended to 'user-'")
skipTests = flag.Bool("skip_tests", false, "skip tests; run make.bash but not all.bash (only use if sufficient testing was done elsewhere)")
uploadMode = flag.Bool("upload", false, "Upload files (exclusive to all other flags)")
)
@ -71,7 +73,7 @@ func main() {
if *rev == "" {
log.Fatal("must specify -rev")
}
if *version == "" {
if *flagVersion == "" {
log.Fatal(`must specify -version flag (such as "go1.12" or "go1.13beta1")`)
}
@ -80,14 +82,15 @@ func main() {
var wg sync.WaitGroup
matches := 0
for _, b := range builds {
targets, ok := releasetargets.TargetsForVersion(*flagVersion)
if !ok {
log.Fatalf("Unknown version %q", *flagVersion)
}
for _, b := range targetsToBuilds(targets) {
b := b
if *target != "" && b.String() != *target {
continue
}
if !match(b.GoQuery, *version) {
continue
}
matches++
b.logf("Start.")
wg.Add(1)
@ -106,11 +109,38 @@ func main() {
wg.Wait()
}
type Build struct {
// GoQuery is a Go version query specifying the Go versions
// the build applies to. Empty string means all Go versions.
GoQuery string
func targetsToBuilds(targets releasetargets.ReleaseTargets) []*Build {
builds := []*Build{
{
Source: true,
Builder: "linux-amd64",
},
}
for _, target := range targets {
build := &Build{
OS: target.GOOS,
Arch: target.GOARCH,
Race: target.Race,
Builder: target.Builder,
SkipTests: target.BuildOnly,
}
if target.GOOS == "linux" && target.GOARCH == "arm" {
build.Goarm = 6
}
builds = append(builds, build)
if target.LongTestBuilder != "" {
builds = append(builds, &Build{
OS: target.GOOS,
Arch: target.GOARCH,
Builder: target.LongTestBuilder,
TestOnly: true,
})
}
}
return builds
}
type Build struct {
OS, Arch string
Source bool
@ -146,169 +176,6 @@ func (b *Build) logf(format string, args ...interface{}) {
log.Printf(format, args...)
}
var builds = []*Build{
{
Source: true,
Builder: "linux-amd64",
},
{
OS: "linux",
Arch: "386",
Builder: "linux-386-stretch",
},
{
OS: "linux",
Arch: "arm",
Builder: "linux-arm-aws",
Goarm: 6, // For compatibility with all Raspberry Pi models.
},
{
OS: "linux",
Arch: "amd64",
Race: true,
Builder: "linux-amd64-stretch", // Using Stretch as of Go 1.16 because Jessie LTS has ended (golang.org/issue/40561#issuecomment-731482962).
},
{
OS: "linux",
Arch: "arm64",
Builder: "linux-arm64-aws",
},
{
GoQuery: ">= go1.18beta1", // See #40561.
OS: "freebsd",
Arch: "386",
Builder: "freebsd-386-12_3",
},
{
GoQuery: ">= go1.18beta1", // See #40561.
OS: "freebsd",
Arch: "amd64",
Race: true,
Builder: "freebsd-amd64-12_3",
},
{
GoQuery: ">= go1.17beta1 && < go1.18beta1", // See #45727.
OS: "freebsd",
Arch: "386",
Builder: "freebsd-386-11_4",
},
{
GoQuery: ">= go1.17beta1 && < go1.18beta1", // See #45727.
OS: "freebsd",
Arch: "amd64",
Race: true,
Builder: "freebsd-amd64-11_4",
},
{
OS: "windows",
Arch: "386",
Builder: "windows-386-2008",
},
{
OS: "windows",
Arch: "amd64",
Race: true,
Builder: "windows-amd64-2008",
},
{
GoQuery: ">= go1.17beta1 && < go1.18beta1", // Go 1.17 Beta 1 is the first Go (pre-)release with the windows/arm64 port.
OS: "windows",
Arch: "arm64",
Race: false, // Not supported as of 2021-06-01.
Builder: "windows-arm64-10",
},
{
GoQuery: ">= go1.18beta1", // Go 1.17 Beta 1 is the first Go (pre-)release with the windows/arm64 port.
OS: "windows",
Arch: "arm64",
Race: false, // Not supported as of 2021-06-01.
Builder: "windows-arm64-11",
},
{
GoQuery: ">= go1.18beta1", // Start exercising a macOS 12 releaselet as of Go 1.18 Beta 1; see issue 40561.
OS: "darwin",
Arch: "amd64",
Race: true,
Builder: "darwin-amd64-12_0",
},
{
GoQuery: ">= go1.18beta1", // Start exercising a macOS 12 releaselet as of Go 1.18 Beta 1; see issue 40561.
OS: "darwin",
Arch: "arm64",
Race: true,
Builder: "darwin-arm64-12_0-toothrot",
},
{
OS: "linux",
Arch: "s390x",
SkipTests: true,
Builder: "linux-s390x-crosscompile",
},
// TODO(bradfitz): switch this ppc64 builder to a Kubernetes
// container cross-compiling ppc64 like the s390x one? For
// now, the ppc64le builders (5) are back, so let's see if we
// can just depend on them not going away.
{
OS: "linux",
Arch: "ppc64le",
SkipTests: true,
Builder: "linux-ppc64le-buildlet",
},
// Older builds.
{
GoQuery: "< go1.17beta1", // See #40563.
OS: "freebsd",
Arch: "386",
Builder: "freebsd-386-11_2",
},
{
GoQuery: "< go1.17beta1", // See #40563.
OS: "freebsd",
Arch: "amd64",
Race: true,
Builder: "freebsd-amd64-11_2",
},
{
GoQuery: ">= go1.17beta1 && < go1.18beta1",
OS: "darwin",
Arch: "amd64",
Race: true,
Builder: "darwin-amd64-11_0",
},
{
GoQuery: "< go1.17beta1", // See golang/go#46161.
OS: "darwin",
Arch: "amd64",
Race: true,
Builder: "darwin-amd64-10_15",
},
{
GoQuery: "< go1.18beta1", // Go 1.17 and 1.16 still use macOS 11. See issue 49889.
OS: "darwin",
Arch: "arm64",
Race: true,
Builder: "darwin-arm64-11_0-toothrot",
},
// Test-only builds.
{
Builder: "linux-386-longtest",
OS: "linux", Arch: "386",
TestOnly: true,
},
{
Builder: "linux-amd64-longtest",
OS: "linux", Arch: "amd64",
TestOnly: true,
},
{
Builder: "windows-amd64-longtest",
OS: "windows", Arch: "amd64",
TestOnly: true,
},
}
var preBuildCleanFiles = []string{
".gitattributes",
".github",
@ -375,7 +242,7 @@ func (b *Build) make() error {
// Write out version file.
b.logf("Writing VERSION file.")
if err := client.Put(ctx, strings.NewReader(*version), "go/VERSION", 0644); err != nil {
if err := client.Put(ctx, strings.NewReader(*flagVersion), "go/VERSION", 0644); err != nil {
return err
}
@ -398,7 +265,7 @@ func (b *Build) make() error {
return fmt.Errorf("verifying file permissions: %v", err)
}
finalFilename := *version + "." + b.String() + ".tar.gz"
finalFilename := *flagVersion + "." + b.String() + ".tar.gz"
return b.fetchTarball(ctx, client, finalFilename)
}
@ -416,7 +283,7 @@ func (b *Build) make() error {
// Issues #36025 #35459
if b.OS == "darwin" && b.Arch == "amd64" {
minMacVersion := minSupportedMacOSVersion(*version)
minMacVersion := minSupportedMacOSVersion(*flagVersion)
env = append(env, fmt.Sprintf("CGO_CFLAGS=-mmacosx-version-min=%s", minMacVersion))
}
@ -559,7 +426,7 @@ func (b *Build) make() error {
}
}
stagingFile := func(ext string) string {
return filepath.Join(stagingDir, *version+"."+b.String()+ext+".untested")
return filepath.Join(stagingDir, *flagVersion+"."+b.String()+ext+".untested")
}
if !b.TestOnly && b.OS == "windows" {
@ -569,7 +436,7 @@ func (b *Build) make() error {
}
releases = append(releases, releaseFile{
Untested: untested,
Final: *version + "." + b.String() + ".msi",
Final: *flagVersion + "." + b.String() + ".msi",
})
}
@ -606,7 +473,7 @@ func (b *Build) make() error {
}
releases = append(releases, releaseFile{
Untested: untested,
Final: *version + "." + b.String() + ".tar.gz",
Final: *flagVersion + "." + b.String() + ".tar.gz",
})
case !b.TestOnly && b.OS == "windows":
untested := stagingFile(".zip")
@ -615,7 +482,7 @@ func (b *Build) make() error {
}
releases = append(releases, releaseFile{
Untested: untested,
Final: *version + "." + b.String() + ".zip",
Final: *flagVersion + "." + b.String() + ".zip",
})
case b.TestOnly:
// Use an empty .test-only file to indicate the test outcome.
@ -628,7 +495,7 @@ func (b *Build) make() error {
}
releases = append(releases, releaseFile{
Untested: untested,
Final: *version + "." + b.String() + ".test-only",
Final: *flagVersion + "." + b.String() + ".test-only",
})
}
@ -962,39 +829,16 @@ func setGOARCH(env []string, goarch string) []string {
// minSupportedMacOSVersion provides the minimum supported macOS
// version (of the form N.M) for supported Go versions.
func minSupportedMacOSVersion(goVer string) string {
// TODO(amedee,dmitshur,golang.org/issue/40558): Use a version package to compare versions of Go.
// The minimum supported version of macOS with each version of go:
// go1.16 - macOS 10.12
// go1.17 - macOS 10.13
// go1.18 - macOS 10.13
minMacVersion := "10.13"
if match("< go1.17beta1", goVer) {
minMacVersion = "10.12"
return minMacVersion
x, ok := version.Go1PointX(goVer)
if !ok {
panic(fmt.Sprintf("could not parse version %v", goVer))
}
return minMacVersion
}
// match reports whether the Go version goVer matches the provided version query.
// The empty query matches all Go versions.
// match panics if given a query that it doesn't support.
func match(query, goVer string) bool {
// TODO(golang.org/issue/40558): This should help inform the API for a Go version parser.
switch query {
case "": // A special case to make the zero Build.GoQuery value useful.
return true
case ">= go1.18beta1":
return !strings.HasPrefix(goVer, "go1.17") && !strings.HasPrefix(goVer, "go1.16")
case "< go1.18beta1":
return strings.HasPrefix(goVer, "go1.17") || strings.HasPrefix(goVer, "go1.16")
case ">= go1.17beta1":
return !strings.HasPrefix(goVer, "go1.16")
case "< go1.17beta1":
return strings.HasPrefix(goVer, "go1.16")
case ">= go1.17beta1 && < go1.18beta1":
return strings.HasPrefix(goVer, "go1.17")
default:
panic(fmt.Errorf("match: query %q is not supported", query))
if x < 17 {
return "10.12"
}
return "10.13"
}

Просмотреть файл

@ -7,48 +7,14 @@ package main
import (
"testing"
"golang.org/x/build/dashboard"
"golang.org/x/build/internal/releasetargets"
)
func TestBuildersExist(t *testing.T) {
for _, b := range builds {
_, ok := dashboard.Builders[b.Builder]
if !ok {
t.Errorf("missing builder: %q", b.Builder)
}
}
}
func TestAllQueriesSupported(t *testing.T) {
for _, b := range builds {
t.Run(b.String(), func(t *testing.T) {
defer func() {
if err := recover(); err != nil {
t.Errorf("build %v uses an unsupported version query:\n%v", b, err)
}
}()
match(b.GoQuery, "go1.15.6") // Shouldn't panic for any b.GoQuery.
})
}
}
func TestTestOnlyBuildsDontSkipTests(t *testing.T) {
for _, b := range builds {
if b.TestOnly && b.SkipTests {
t.Errorf("build %s is configured to run tests only, but also to skip tests; is that intentional?", b)
}
}
}
func TestMinSupportedMacOSVersion(t *testing.T) {
testCases := []struct {
goVer string
wantMacOS string
}{
{"go1.16beta1", "10.12"},
{"go1.16rc1", "10.12"},
{"go1.16", "10.12"},
{"go1.16.1", "10.12"},
{"go1.17beta1", "10.13"},
{"go1.17rc1", "10.13"},
{"go1.17", "10.13"},
@ -69,9 +35,13 @@ func TestMinSupportedMacOSVersion(t *testing.T) {
}
func TestBuilderSelectionPerGoVersion(t *testing.T) {
matchBuilds := func(target, goVer string) (matched []*Build) {
for _, b := range builds {
if b.String() != target || !match(b.GoQuery, goVer) {
matchBuilds := func(t *testing.T, target, goVer string) (matched []*Build) {
targets, ok := releasetargets.TargetsForVersion(goVer)
if !ok {
t.Fatalf("failed to parse %q", goVer)
}
for _, b := range targetsToBuilds(targets) {
if b.String() != target {
continue
}
matched = append(matched, b)
@ -85,9 +55,6 @@ func TestBuilderSelectionPerGoVersion(t *testing.T) {
wantBuilder string
}{
// linux
// Go 1.16 use the the Stretch builders.
{"go1.16", "linux-amd64", "linux-amd64-stretch"},
{"go1.16", "linux-386", "linux-386-stretch"},
// Go 1.17 use the the Stretch builders.
{"go1.17", "linux-amd64", "linux-amd64-stretch"},
{"go1.17", "linux-386", "linux-386-stretch"},
@ -96,20 +63,12 @@ func TestBuilderSelectionPerGoVersion(t *testing.T) {
{"go1.18", "linux-386", "linux-386-stretch"},
// linux-arm
{"go1.16", "linux-arm64", "linux-arm64-aws"},
{"go1.16", "linux-armv6l", "linux-arm-aws"},
{"go1.17", "linux-arm64", "linux-arm64-aws"},
{"go1.17", "linux-armv6l", "linux-arm-aws"},
{"go1.18", "linux-arm64", "linux-arm64-aws"},
{"go1.18", "linux-armv6l", "linux-arm-aws"},
// FreeBSD
{"go1.16rc2", "freebsd-amd64", "freebsd-amd64-11_2"},
{"go1.16rc2", "freebsd-386", "freebsd-386-11_2"},
{"go1.16", "freebsd-amd64", "freebsd-amd64-11_2"},
{"go1.16", "freebsd-386", "freebsd-386-11_2"},
{"go1.16.1", "freebsd-amd64", "freebsd-amd64-11_2"},
{"go1.16.1", "freebsd-386", "freebsd-386-11_2"},
// Go 1.17 continues to use the the FreeBSD 11.4 builder.
{"go1.17rc2", "freebsd-amd64", "freebsd-amd64-11_4"},
{"go1.17rc2", "freebsd-386", "freebsd-386-11_4"},
@ -120,23 +79,18 @@ func TestBuilderSelectionPerGoVersion(t *testing.T) {
{"go1.18", "freebsd-386", "freebsd-386-12_3"},
// macOS (amd64)
// Go 1.16 uses MacOS 10.15.
{"go1.16", "darwin-amd64", "darwin-amd64-10_15"},
// Go 1.17 uses MacOS 11.0.
{"go1.17", "darwin-amd64", "darwin-amd64-11_0"},
// Go 1.18 starts using a macOS 12 releaselet.
{"go1.18", "darwin-amd64", "darwin-amd64-12_0"},
// macOS (arm64)
// Go 1.16 and 1.17 use macOS 11.
{"go1.16", "darwin-arm64", "darwin-arm64-11_0-toothrot"},
{"go1.17", "darwin-arm64", "darwin-arm64-11_0-toothrot"},
// Go 1.18 starts using a macOS 12 releaselet.
{"go1.18", "darwin-arm64", "darwin-arm64-12_0-toothrot"},
// Windows
// Go 1.16 & 1.17 & 1.18 use Windows 2008.
{"go1.16", "windows-386", "windows-386-2008"},
{"go1.16", "windows-amd64", "windows-amd64-2008"},
// Go 1.17 & 1.18 use Windows 2008.
{"go1.17", "windows-386", "windows-386-2008"},
{"go1.17", "windows-amd64", "windows-amd64-2008"},
{"go1.18", "windows-386", "windows-386-2008"},
@ -144,7 +98,7 @@ func TestBuilderSelectionPerGoVersion(t *testing.T) {
}
for _, tc := range testCases {
t.Run(tc.target+"@"+tc.goVer, func(t *testing.T) {
builds := matchBuilds(tc.target, tc.goVer)
builds := matchBuilds(t, tc.target, tc.goVer)
if len(builds) != 1 {
t.Fatalf("got %d matching builds; want 1", len(builds))
}

Просмотреть файл

@ -30,6 +30,7 @@ import (
"golang.org/x/build/buildenv"
"golang.org/x/build/internal/envutil"
"golang.org/x/build/internal/releasetargets"
"golang.org/x/build/internal/task"
"golang.org/x/build/internal/workflow"
"golang.org/x/build/maintner"
@ -37,39 +38,10 @@ import (
// A Target is a release target.
type Target struct {
// GoQuery is a Go version query specifying the Go versions the
// release target applies to. Empty string means all Go versions.
GoQuery string
Name string // Target name as accepted by cmd/release. For example, "linux-amd64".
TestOnly bool // Run tests only; don't produce a release artifact.
}
var releaseTargets = []Target{
// Source-only target.
{Name: "src"},
// Binary targets.
{Name: "linux-386"},
{Name: "linux-armv6l"},
{Name: "linux-amd64"},
{Name: "linux-arm64"},
{Name: "freebsd-386"},
{Name: "freebsd-amd64"},
{Name: "windows-386"},
{Name: "windows-amd64"},
{Name: "windows-arm64", GoQuery: ">= go1.17beta1"},
{Name: "darwin-amd64"},
{Name: "darwin-arm64"},
{Name: "linux-s390x"},
{Name: "linux-ppc64le"},
// Test-only targets.
{Name: "linux-386-longtest", TestOnly: true},
{Name: "linux-amd64-longtest", TestOnly: true},
{Name: "windows-amd64-longtest", TestOnly: true},
}
var releaseModes = map[string]bool{
"prepare": true,
"release": true,
@ -1001,12 +973,17 @@ func (w *Work) uploadStagingRelease(target Target, out *ReleaseOutput) error {
// releaseTarget returns a release target with the specified name
// for the specified Go version.
func releaseTarget(name, goVer string) (_ Target, ok bool) {
for _, t := range releaseTargets {
if !match(t.GoQuery, goVer) {
continue
}
if t.Name == name {
return t, true
targets, ok := releasetargets.TargetsForVersion(goVer)
if !ok {
return Target{}, false
}
_, ok = targets[name]
if ok {
return Target{Name: name}, true
}
for _, target := range targets {
if target.LongTestBuilder == name {
return Target{Name: name, TestOnly: true}, true
}
}
return Target{}, false
@ -1014,31 +991,23 @@ func releaseTarget(name, goVer string) (_ Target, ok bool) {
// matchTargets selects release targets that have a matching
// GoQuery value for the specified Go version.
func matchTargets(goVer string) (matched []Target) {
for _, t := range releaseTargets {
if !match(t.GoQuery, goVer) {
continue
func matchTargets(goVer string) []Target {
targets, ok := releasetargets.TargetsForVersion(goVer)
if !ok {
return nil
}
matched := []Target{
{Name: "src"},
}
for name, target := range targets {
matched = append(matched, Target{Name: name})
if target.LongTestBuilder != "" {
matched = append(matched, Target{Name: target.LongTestBuilder, TestOnly: true})
}
matched = append(matched, t)
}
return matched
}
// match reports whether the Go version goVer matches the provided version query.
// The empty query matches all Go versions.
// match panics if given a query that it doesn't support.
func match(query, goVer string) bool {
// TODO(golang.org/issue/40558): This should help inform the API for a Go version parser.
switch query {
case "": // A special case to make the zero Target.GoQuery value useful.
return true
case ">= go1.17beta1":
return !strings.HasPrefix(goVer, "go1.16")
default:
panic(fmt.Errorf("match: query %q is not supported", query))
}
}
// splitLogMessage splits a string into n number of strings of maximum size maxStrLen.
// It naively attempts to split the string along the boundaries of new line characters in order
// to make each individual string as readable as possible.

Просмотреть файл

@ -5,6 +5,7 @@
package main
import (
"sort"
"testing"
"github.com/google/go-cmp/cmp"
@ -47,34 +48,13 @@ func TestTargetSelectionPerGoVersion(t *testing.T) {
"windows-amd64-longtest",
},
},
{
goVer: []string{
"go1.16.3",
},
want: []string{
"src",
"linux-386",
"linux-armv6l",
"linux-amd64",
"linux-arm64",
"freebsd-386",
"freebsd-amd64",
"windows-386",
"windows-amd64",
"darwin-amd64",
"darwin-arm64", // New to Go 1.16.
"linux-s390x",
"linux-ppc64le",
"linux-386-longtest",
"linux-amd64-longtest",
"windows-amd64-longtest",
},
},
} {
for _, goVer := range tc.goVer {
t.Run(goVer, func(t *testing.T) {
got := matchTargets(goVer)
if diff := cmp.Diff(tc.want, targetNames(got)); diff != "" {
got := targetNames(matchTargets(goVer))
sort.Strings(tc.want)
sort.Strings(got)
if diff := cmp.Diff(tc.want, got); diff != "" {
t.Errorf("release target mismatch (-want +got):\n%s", diff)
}
})
@ -82,19 +62,6 @@ func TestTargetSelectionPerGoVersion(t *testing.T) {
}
}
func TestAllQueriesSupported(t *testing.T) {
for _, r := range releaseTargets {
t.Run(r.Name, func(t *testing.T) {
defer func() {
if err := recover(); err != nil {
t.Errorf("target %s uses an unsupported version query:\n%v", r.Name, err)
}
}()
match(r.GoQuery, "go1.15.7") // Shouldn't panic for any r.GoQuery.
})
}
}
func TestSplitLogMessage(t *testing.T) {
testCases := []struct {
desc string

Просмотреть файл

@ -0,0 +1,76 @@
Targets for release 1.17
================================================================================
darwin-amd64 darwin amd64 darwin-amd64-11_0
Race enabled
darwin-arm64 darwin arm64 darwin-arm64-11_0-toothrot
Race enabled
freebsd-386 freebsd 386 freebsd-386-11_4
freebsd-amd64 freebsd amd64 freebsd-amd64-11_4
Race enabled
linux-386 linux 386 linux-386-stretch
Long tests on linux-386-longtest
linux-amd64 linux amd64 linux-amd64-stretch
Race enabled, Long tests on linux-amd64-longtest
linux-arm64 linux arm64 linux-arm64-aws
linux-armv6l linux arm linux-arm-aws
linux-ppc64le linux ppc64le linux-ppc64le-buildlet
Build only
linux-s390x linux s390x linux-s390x-crosscompile
Build only
windows-386 windows 386 windows-386-2008
windows-amd64 windows amd64 windows-amd64-2008
Race enabled, Long tests on windows-amd64-longtest
windows-arm64 windows arm64 windows-arm64-10
Targets for release 1.18
================================================================================
darwin-amd64 darwin amd64 darwin-amd64-12_0
Race enabled
darwin-arm64 darwin arm64 darwin-arm64-12_0-toothrot
Race enabled
freebsd-386 freebsd 386 freebsd-386-12_3
freebsd-amd64 freebsd amd64 freebsd-amd64-12_3
Race enabled
linux-386 linux 386 linux-386-stretch
Long tests on linux-386-longtest
linux-amd64 linux amd64 linux-amd64-stretch
Race enabled, Long tests on linux-amd64-longtest
linux-arm64 linux arm64 linux-arm64-aws
linux-armv6l linux arm linux-arm-aws
linux-ppc64le linux ppc64le linux-ppc64le-buildlet
Build only
linux-s390x linux s390x linux-s390x-crosscompile
Build only
windows-386 windows 386 windows-386-2008
windows-amd64 windows amd64 windows-amd64-2008
Race enabled, Long tests on windows-amd64-longtest
windows-arm64 windows arm64 windows-arm64-11

Просмотреть файл

@ -0,0 +1,158 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package releasetargets
import (
"sort"
"strings"
"golang.org/x/build/maintner/maintnerd/maintapi/version"
)
type Target struct {
GOOS, GOARCH string
Builder string
BuildOnly bool
LongTestBuilder string
Race bool
}
// ReleaseTargets maps a target name (usually but not always $GOOS-$GOARCH)
// to its target.
type ReleaseTargets map[string]*Target
// allReleases contains all the targets for all releases we're currently
// supporting. To reduce duplication, targets from earlier versions are
// propagated forward unless overridden. To remove a target in a later release,
// set it to nil explicitly.
// GOOS and GOARCH will be set automatically from the target name, but can be
// overridden if necessary.
var allReleases = map[int]ReleaseTargets{
17: {
"darwin-amd64": &Target{
Builder: "darwin-amd64-11_0",
Race: true,
},
"darwin-arm64": &Target{
Builder: "darwin-arm64-11_0-toothrot",
Race: true,
},
"freebsd-386": &Target{
Builder: "freebsd-386-11_4",
},
"freebsd-amd64": &Target{
Builder: "freebsd-amd64-11_4",
Race: true,
},
"linux-386": &Target{
Builder: "linux-386-stretch",
LongTestBuilder: "linux-386-longtest",
},
"linux-armv6l": &Target{
GOARCH: "arm",
Builder: "linux-arm-aws",
},
"linux-arm64": &Target{
Builder: "linux-arm64-aws",
},
"linux-amd64": &Target{
Builder: "linux-amd64-stretch",
LongTestBuilder: "linux-amd64-longtest",
Race: true,
},
"linux-s390x": &Target{
Builder: "linux-s390x-crosscompile",
BuildOnly: true,
},
"linux-ppc64le": &Target{
Builder: "linux-ppc64le-buildlet",
BuildOnly: true,
},
"windows-386": &Target{
Builder: "windows-386-2008",
},
"windows-amd64": &Target{
Builder: "windows-amd64-2008",
LongTestBuilder: "windows-amd64-longtest",
Race: true,
},
"windows-arm64": &Target{
Builder: "windows-arm64-10",
},
},
18: {
"darwin-amd64": &Target{
Builder: "darwin-amd64-12_0",
Race: true,
},
"darwin-arm64": &Target{
Builder: "darwin-arm64-12_0-toothrot",
Race: true,
},
"freebsd-386": &Target{
Builder: "freebsd-386-12_3",
},
"freebsd-amd64": &Target{
Builder: "freebsd-amd64-12_3",
Race: true,
},
"windows-arm64": &Target{
Builder: "windows-arm64-11",
},
},
}
func init() {
for _, targets := range allReleases {
for name, target := range targets {
parts := strings.SplitN(name, "-", 2)
if target.GOOS == "" {
target.GOOS = parts[0]
}
if target.GOARCH == "" {
target.GOARCH = parts[1]
}
}
}
}
func sortedReleases() []int {
var releases []int
for rel := range allReleases {
releases = append(releases, rel)
}
sort.Ints(releases)
return releases
}
// TargetsForGo1Point returns the ReleaseTargets that apply to the given
// version.
func TargetsForGo1Point(x int) ReleaseTargets {
targets := ReleaseTargets{}
for _, release := range sortedReleases() {
if release > x {
break
}
for osarch, target := range allReleases[release] {
if target == nil {
delete(targets, osarch)
} else {
copy := *target
targets[osarch] = &copy
}
}
}
return targets
}
// TargetsForVersion returns the ReleaseTargets for a given Go version string,
// e.g. go1.18.1.
func TargetsForVersion(versionStr string) (ReleaseTargets, bool) {
x, ok := version.Go1PointX(versionStr)
if !ok {
return nil, false
}
return TargetsForGo1Point(x), true
}

Просмотреть файл

@ -0,0 +1,83 @@
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package releasetargets
import (
"bytes"
"flag"
"fmt"
"io"
"io/ioutil"
"sort"
"strings"
"testing"
"golang.org/x/build/dashboard"
)
var update = flag.Bool("update", false, "controls whether to update releases.txt")
func TestReleaseTargets(t *testing.T) {
out := &bytes.Buffer{}
for _, release := range sortedReleases() {
printRelease(out, release, TargetsForGo1Point(release))
}
if *update {
if err := ioutil.WriteFile("releases.txt", out.Bytes(), 0); err != nil {
t.Fatalf("updating golden: %v", err)
}
return
}
golden, err := ioutil.ReadFile("releases.txt")
if err != nil {
t.Fatalf("reading golden: %v", err)
}
if !bytes.Equal(golden, out.Bytes()) {
t.Error("Goldens need updating. Rerun with -update.")
}
}
func printRelease(w io.Writer, release int, targets ReleaseTargets) {
fmt.Fprintf(w, "Targets for release 1.%v\n%s\n", release, strings.Repeat("=", 80))
var targetNames []string
for name := range targets {
targetNames = append(targetNames, name)
}
sort.Strings(targetNames)
for _, name := range targetNames {
target := targets[name]
var flags []string
if target.BuildOnly {
flags = append(flags, "Build only")
}
if target.Race {
flags = append(flags, "Race enabled")
}
if target.LongTestBuilder != "" {
flags = append(flags, "Long tests on "+target.LongTestBuilder)
}
fmt.Fprintf(w, "%-15v %-10v %-10v %v\n", name, target.GOOS, target.GOARCH, target.Builder)
if len(flags) != 0 {
fmt.Fprintf(w, "\t%v\n", strings.Join(flags, ", "))
}
fmt.Fprintf(w, "\n")
}
fmt.Fprintf(w, "\n\n")
}
func TestBuildersExist(t *testing.T) {
for _, rel := range allReleases {
for _, target := range rel {
_, ok := dashboard.Builders[target.Builder]
if !ok {
t.Errorf("missing builder: %q", target.Builder)
}
if _, ok := dashboard.Builders[target.LongTestBuilder]; target.LongTestBuilder != "" && !ok {
t.Errorf("missing longtest builder: %q", target.LongTestBuilder)
}
}
}
}

Просмотреть файл

@ -116,3 +116,20 @@ func parse0To999(s string) (n int, ok bool) {
}
return n, true
}
// Go1PointX returns the second number in a string that looks like a Go
// version, i.e. X in anything that starts with "go1.X".
func Go1PointX(version string) (int, bool) {
const prefix = "go1."
if !strings.HasPrefix(version, prefix) {
return 0, false
}
numberEnd := len(prefix)
for ; numberEnd < len(version) && version[numberEnd] >= '0' && version[numberEnd] <= '9'; numberEnd++ {
}
x, ok := parse0To999(version[len(prefix):numberEnd])
if !ok {
return 0, false
}
return x, true
}

Просмотреть файл

@ -167,3 +167,22 @@ func TestAllocs(t *testing.T) {
t.Fatalf("unexpected %v allocation(s)", got)
}
}
func TestGo1PointX(t *testing.T) {
tests := []struct {
goVer string
wantX int
}{
{"go1.9", 9},
{"go1.16beta1", 16},
{"go1.16rc1", 16},
{"go1.16", 16},
{"go1.16.1", 16},
}
for _, tt := range tests {
x, ok := Go1PointX(tt.goVer)
if !ok || x != tt.wantX {
t.Errorf("Go1PointX(%q) = %v, %v, want %v, true", tt.goVer, x, ok, tt.wantX)
}
}
}