Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

publish-announcement: sort versions to be decreasing order #135

Merged
merged 10 commits into from
Jul 19, 2024
26 changes: 20 additions & 6 deletions cmd/releasego/publish-announcement.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ import (
"io"
"os"
"regexp"
"sort"
"strings"
"text/template"
"time"
"unicode"

"github.com/microsoft/go-infra/githubutil"
"github.com/microsoft/go-infra/goversion"
"github.com/microsoft/go-infra/internal/infrasort"
"github.com/microsoft/go-infra/subcmd"
)

Expand Down Expand Up @@ -56,6 +58,19 @@ type ReleaseInfo struct {
// take all this methods and make it one constructor function for ReleaseInfo
func NewReleaseInfo(releaseDate time.Time, versions []string, author string, security bool) *ReleaseInfo {
ri := new(ReleaseInfo)
goVersions := make(infrasort.GoVersions, 0)
for _, version := range versions {
goVersions = append(goVersions, goversion.New(version))
}

// Sort the versions in descending order
sort.Sort(goVersions)

// Recreate versions slice with sorted info.
versions = versions[:0]
for _, goVersion := range goVersions {
versions = append(versions, goVersion.Full())
}

// Generate human-readable title and URL-friendly slug from the Go versions.
ri.Title = generateBlogPostTitle(versions)
Expand All @@ -66,13 +81,12 @@ func NewReleaseInfo(releaseDate time.Time, versions []string, author string, sec
ri.Tags = []string{"go", "release"}

// Process each Go version, extracting release information and generating links.
for _, version := range versions {
goVersion := goversion.New(version).UpstreamFormatGitTag()
for _, goVersion := range goVersions {
ri.Versions = append(ri.Versions, GoVersionData{
MSGoVersion: "v" + version,
MSGoVersionLink: createMSGoReleaseLinkFromVersion(version),
GoVersion: goVersion,
GoVersionLink: createGoReleaseLinkFromVersion(goVersion),
MSGoVersion: "v" + goVersion.Full(),
MSGoVersionLink: createMSGoReleaseLinkFromVersion(goVersion.Full()),
GoVersion: goVersion.UpstreamFormatGitTag(),
GoVersionLink: createGoReleaseLinkFromVersion(goVersion.UpstreamFormatGitTag()),
})
}

Expand Down
3 changes: 2 additions & 1 deletion cmd/releasego/publish-announcement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ func Test_ReleaseInfo_WriteAnnouncement(t *testing.T) {
{"2024-06-04-real", NewReleaseInfo(testTime, []string{"1.22.4-1", "1.21.11-1"}, author, true)},
{"2024-06-04-nonsecurity", NewReleaseInfo(testTime, []string{"1.22.4-1", "1.21.11-1"}, author, false)},
{"only-one-branch", NewReleaseInfo(testTime, []string{"1.22.8-3"}, author, true)},
{"three-branches", NewReleaseInfo(testTime, []string{"1.23.1-1", "1.22.8-1", "1.21.11-16"}, author, true)},
{"three-branches", NewReleaseInfo(testTime, []string{"1.22.8-1", "1.23.1-1", "1.21.11-16"}, author, true)},
{"2024-06-04-note", NewReleaseInfo(testTime, []string{"1.22.4-1-fips", "1.22.4-1", "1.21.11-1", "1.21.11-1-fips"}, author, false)},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
post_title: Go 1.22.4-1, 1.22.4-1-fips, 1.21.11-1, and 1.21.11-1-fips Microsoft builds now available
author1: Test Author
post_slug: go-1-22-4-1--1-22-4-1-fips-1-21-11-1-and-1-21-11-1-fips-microsoft-builds-now-available
categories: Microsoft for Go Developers
tags: go, release
featured_image:
summary: The Microsoft builds of the Go security patches released today, are now available for download.
---

A new set of Microsoft Go builds is now [available for download](https://github.com/microsoft/go#download-and-install).
For more information about this release and the changes included, see the table below:

| Microsoft Release | Upstream Tag |
|-------------------|--------------|
| [v1.22.4-1](https://github.com/microsoft/go/releases/tag/v1.22.4-1) | go1.22.4 [release notes](https://go.dev/doc/devel/release#go1.22.4) |
| [v1.22.4-1-fips](https://github.com/microsoft/go/releases/tag/v1.22.4-1-fips) | go1.22.4 [release notes](https://go.dev/doc/devel/release#go1.22.4) |
| [v1.21.11-1](https://github.com/microsoft/go/releases/tag/v1.21.11-1) | go1.21.11 [release notes](https://go.dev/doc/devel/release#go1.21.11) |
| [v1.21.11-1-fips](https://github.com/microsoft/go/releases/tag/v1.21.11-1-fips) | go1.21.11 [release notes](https://go.dev/doc/devel/release#go1.21.11) |
51 changes: 51 additions & 0 deletions internal/infrasort/goversions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package infrasort

import (
"strconv"

"github.com/microsoft/go-infra/goversion"
)

// GoVersions implements [sort.Interface] and sorts versions in descending order.
// If Major, Minor, Patch, or Revision of any GoVersion in the slice can't be parsed by
// [strconv.Atoi], the result of using this type is undefined.
type GoVersions []*goversion.GoVersion

func (versions GoVersions) Len() int { return len(versions) }
func (versions GoVersions) Swap(i, j int) { versions[i], versions[j] = versions[j], versions[i] }
func (versions GoVersions) Less(i, j int) bool {
less := func(a, b string) bool {
intA, err := strconv.Atoi(a)
if err != nil {
return false
}

intB, err := strconv.Atoi(b)
if err != nil {
return false
}
return intA > intB
}

current, next := versions[i], versions[j]

if current.Major != next.Major {
return less(current.Major, next.Major)
}
if current.Minor != next.Minor {
return less(current.Minor, next.Minor)
}
if current.Patch != next.Patch {
return less(current.Patch, next.Patch)
}
if current.Revision != next.Revision {
return less(current.Revision, next.Revision)
}
if current.Prerelease != next.Prerelease {
return current.Prerelease < next.Prerelease
}
if current.Note != next.Note {
return current.Note < next.Note
}
return false
}
80 changes: 80 additions & 0 deletions internal/infrasort/goversions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package infrasort

import (
"sort"
"testing"

"github.com/microsoft/go-infra/goversion"
)

func TestGoVersions_Sort(t *testing.T) {
tests := []struct {
name string
versions GoVersions
expected GoVersions
}{
{
name: "basic version sorting",
versions: GoVersions{
goversion.New("1.2.3"),
goversion.New("1.2.1"),
goversion.New("1.3.0"),
goversion.New("1.2.3-2"),
goversion.New("1.2.3-1"),
},
expected: GoVersions{
goversion.New("1.3.0"),
goversion.New("1.2.3-2"),
goversion.New("1.2.3"),
goversion.New("1.2.3-1"),
goversion.New("1.2.1"),
},
},
{
name: "version with prerelease and note",
versions: GoVersions{
goversion.New("1.2.3-beta"),
goversion.New("1.2.3-rc1"),
goversion.New("1.2.3-1-fips"),
goversion.New("1.2.3"),
goversion.New("1.2.3-2"),
},
expected: GoVersions{
goversion.New("1.2.3-2"),
goversion.New("1.2.3"),
goversion.New("1.2.3-beta"),
goversion.New("1.2.3-1-fips"),
goversion.New("1.2.3-rc1"),
},
},
{
name: "sorting with major and minor versions",
versions: GoVersions{
goversion.New("2.0.0"),
goversion.New("1.10.0"),
goversion.New("1.2.3"),
goversion.New("1.2.0"),
goversion.New("1.3.0"),
},
expected: GoVersions{
goversion.New("2.0.0"),
goversion.New("1.10.0"),
goversion.New("1.3.0"),
goversion.New("1.2.3"),
goversion.New("1.2.0"),
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Sort the versions
sort.Sort(tt.versions)
for i, v := range tt.versions {
if *v != *tt.expected[i] {
t.Errorf("expected %v at index %d, got %v", tt.expected[i].Original, i, v.Original)
}
}
})
}
}