diff --git a/cmd/releasego/update-azure-linux.go b/cmd/releasego/update-azure-linux.go index 2988955a..2dfe1891 100644 --- a/cmd/releasego/update-azure-linux.go +++ b/cmd/releasego/update-azure-linux.go @@ -276,34 +276,20 @@ func updateSpecFile(assets *buildassets.BuildAssets, changelogDate time.Time, sp oldVersion = goversion.New(matches[2]) } - var oldRelease int + var oldRelease string if matches := specFileReleaseRegex.FindStringSubmatch(specFileContent); matches == nil { return "", fmt.Errorf("no Release declaration found in spec content") } else { - var err error - oldRelease, err = strconv.Atoi(matches[2]) - if err != nil { - return "", fmt.Errorf("failed to parse Release number: %w", err) - } + oldRelease = matches[2] } - newVersion := assets.GoVersion().MajorMinorPatch() - if strings.Contains(newVersion, "$") { - return "", fmt.Errorf("new version %q contains unexpected $", newVersion) - } - specFileContent = specFileVersionRegex.ReplaceAllString(specFileContent, "${1}"+newVersion) - - // For servicing patches, increment release. Azure Linux may have incremented it manually for a - // Azure-Linux-specific fix, so this is independent of Microsoft Go releases. When updating to a - // new major/minor version (as semver refers to them), reset release to 1. - var newRelease int - if assets.GoVersion().MajorMinor() != oldVersion.MajorMinor() { - newRelease = 1 - } else { - newRelease = oldRelease + 1 + newVersion, newRelease, err := updateSpecVersion(assets, oldVersion, oldRelease) + if err != nil { + return "", err } - specFileContent = specFileReleaseRegex.ReplaceAllString(specFileContent, "${1}"+strconv.Itoa(newRelease)+"${3}") + specFileContent = specFileVersionRegex.ReplaceAllString(specFileContent, "${1}"+newVersion) + specFileContent = specFileReleaseRegex.ReplaceAllString(specFileContent, "${1}"+newRelease+"${3}") specFileContent = addChangelogToSpecFile(specFileContent, changelogDate, assets) return specFileContent, nil @@ -416,3 +402,31 @@ func updateCGManifest(buildAssets *buildassets.BuildAssets, cgManifestContent [] return buf.Bytes(), nil } + +func updateSpecVersion(assets *buildassets.BuildAssets, oldVersion *goversion.GoVersion, oldRelease string) (version, release string, err error) { + oldReleaseInt, err := strconv.Atoi(oldRelease) + if err != nil { + return "", "", fmt.Errorf("failed to parse old Release number: %w", err) + } + + newVersion := assets.GoVersion().MajorMinorPatch() + if strings.Contains(newVersion, "$") { + return "", "", fmt.Errorf("new version %q contains unexpected $", newVersion) + } + + // Decide on the new Azure Linux golang package release number. + // + // We don't use assets.GoVersion().Revision because Azure Linux may have incremented the + // release version manually for an Azure-Linux-specific fix. + var newRelease int + if assets.GoVersion().MajorMinorPatch() != oldVersion.MajorMinorPatch() { + // When updating to a new upstream Go version, reset release number to 1. + newRelease = 1 + } else { + // When the upstream Go version didn't change, increment the release number. This means + // there has been a patch specific to Microsoft Go. + newRelease = oldReleaseInt + 1 + } + + return newVersion, strconv.Itoa(newRelease), nil +} diff --git a/cmd/releasego/update-azure-linux_test.go b/cmd/releasego/update-azure-linux_test.go index 2fc203c7..770addc5 100644 --- a/cmd/releasego/update-azure-linux_test.go +++ b/cmd/releasego/update-azure-linux_test.go @@ -10,7 +10,9 @@ import ( "testing" "time" + "github.com/microsoft/go-infra/buildmodel/buildassets" "github.com/microsoft/go-infra/goldentest" + "github.com/microsoft/go-infra/goversion" ) var assetsJsonPath = filepath.Join("testdata", "update-azure-linux", "assets.json") @@ -98,3 +100,66 @@ func TestUpdateCGManifestFileContent(t *testing.T) { filepath.Join("testdata", "update-azure-linux", "updated_cgmanifest.golden.json"), string(updatedCgManifestFile)) } + +func TestUpdateSpecVersion(t *testing.T) { + type args struct { + newGoVersion string + oldVersion string + oldRelease string + } + tests := []struct { + name string + args args + wantVersion string + wantRelease string + wantErr bool + }{ + { + "patch", + args{"1.22.4-1", "1.22.3", "1"}, + "1.22.4", "1", false, + }, + { + "patch-modified-package", + args{"1.22.4-1", "1.22.3", "2"}, + "1.22.4", "1", false, + }, + { + "patch-msft-go-release", + args{"1.22.3-2", "1.22.3", "1"}, + "1.22.3", "2", false, + }, + { + "patch-msft-go-release-modified", + args{"1.22.3-2", "1.22.3", "4"}, + "1.22.3", "5", false, + }, + { + "go-major", + args{"1.23.0-1", "1.22.8", "1"}, + "1.23.0", "1", false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assets := &buildassets.BuildAssets{ + Version: tt.args.newGoVersion, + } + gotVersion, gotRelease, err := updateSpecVersion( + assets, + goversion.New(tt.args.oldVersion), + tt.args.oldRelease, + ) + if (err != nil) != tt.wantErr { + t.Errorf("updateSpecVersion() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotVersion != tt.wantVersion { + t.Errorf("updateSpecVersion() gotVersion = %v, want %v", gotVersion, tt.wantVersion) + } + if gotRelease != tt.wantRelease { + t.Errorf("updateSpecVersion() gotRelease = %v, want %v", gotRelease, tt.wantRelease) + } + }) + } +}