Skip to content

Commit

Permalink
fix(ci): get correct previous release version for release notes (#19443
Browse files Browse the repository at this point in the history
…) (#20315)

* better release notes

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* work on fork

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* don't do unnecessary stuff

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* fix path

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* fix path

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* help debug

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* refactor, clean up

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

* use a workspace to avoid touching the main go.mod

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>

---------

Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com>
  • Loading branch information
crenshaw-dev authored Oct 11, 2024
1 parent d542b02 commit b8f85c9
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 15 deletions.
26 changes: 11 additions & 15 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,16 @@ jobs:
- name: Fetch all tags
run: git fetch --force --tags

- name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in realease branches.
run: |
set -xue
if echo ${{ github.ref_name }} | grep -E -- '-rc1+$';then
echo "GORELEASER_PREVIOUS_TAG=$(git -c 'versionsort.suffix=-rc' tag --list --sort=version:refname | tail -n 2 | head -n 1)" >> $GITHUB_ENV
else
echo "This is not the first release on the branch, Using GoReleaser defaults"
fi
- name: Setup Golang
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2
with:
go-version: ${{ env.GOLANG_VERSION }}

- name: Set GORELEASER_PREVIOUS_TAG # Workaround, GoReleaser uses 'git-describe' to determine a previous tag. Our tags are created in release branches.
run: |
set -xue
echo "GORELEASER_PREVIOUS_TAG=$(go run hack/get-previous-release/get-previous-version-for-release-notes.go ${{ github.ref_name }})" >> $GITHUB_ENV
- name: Set environment variables for ldflags
id: set_ldflag
run: |
Expand All @@ -105,7 +101,7 @@ jobs:
args: release --clean --timeout 55m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KUBECTL_VERSION: ${{ env.KUBECTL_VERSION }}
KUBECTL_VERSION: ${{ env.KUBECTL_VERSION }}
GIT_TREE_STATE: ${{ env.GIT_TREE_STATE }}

- name: Generate subject for provenance
Expand Down Expand Up @@ -188,7 +184,7 @@ jobs:
fi
cd /tmp && tar -zcf sbom.tar.gz *.spdx
- name: Generate SBOM hash
shell: bash
id: sbom-hash
Expand All @@ -197,29 +193,29 @@ jobs:
# base64 -w0 encodes to base64 and outputs on a single line.
# sha256sum /tmp/sbom.tar.gz ... | base64 -w0
echo "hashes=$(sha256sum /tmp/sbom.tar.gz | base64 -w0)" >> "$GITHUB_OUTPUT"
- name: Upload SBOM
uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: |
/tmp/sbom.tar.gz
sbom-provenance:
needs: [generate-sbom]
permissions:
actions: read # for detecting the Github Actions environment
id-token: write # Needed for provenance signing and ID
contents: write # Needed for release uploads
if: github.repository == 'argoproj/argo-cd'
# Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
# Must be referenced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: "${{ needs.generate-sbom.outputs.hashes }}"
provenance-name: "argocd-sbom.intoto.jsonl"
upload-assets: true

post-release:
needs:
- argocd-image
Expand Down
132 changes: 132 additions & 0 deletions hack/get-previous-release/get-previous-version-for-release-notes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package main

import (
"fmt"
"golang.org/x/mod/semver"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
)

/**
This script is used to determine the previous version of a release based on the current version. It is used to help
generate release notes for a new release.
*/

func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run get-previous-version-for-release-notes.go <version being released>")
return
}

proposedTag := os.Args[1]

tags, err := getGitTags()
if err != nil {
fmt.Printf("Error getting git tags: %v\n", err)
return
}

previousTag, err := findPreviousTag(proposedTag, tags)
if err != nil {
fmt.Printf("Error finding previous tag: %v\n", err)
os.Exit(1)
}

fmt.Printf("%s\n", previousTag)
}

func extractPatchAndRC(tag string) (string, string, error) {
re := regexp.MustCompile(`^v\d+\.\d+\.(\d+)(?:-rc(\d+))?$`)
matches := re.FindStringSubmatch(tag)
if len(matches) < 2 {
return "", "", fmt.Errorf("invalid tag format: %s", tag)
}
patch := matches[1]
rc := "0"
if len(matches) == 3 && matches[2] != "" {
rc = matches[2]
}
return patch, rc, nil
}

func findPreviousTag(proposedTag string, tags []string) (string, error) {
var previousTag string
proposedMajor := semver.Major(proposedTag)
proposedMinor := semver.MajorMinor(proposedTag)

proposedPatch, proposedRC, err := extractPatchAndRC(proposedTag)
if err != nil {
return "", err
}

// If the current tag is a .0 patch release or a 1 release candidate, adjust to the previous minor release series.
if (proposedPatch == "0" && proposedRC == "0") || proposedRC == "1" {
proposedMinorInt, err := strconv.Atoi(strings.TrimPrefix(proposedMinor, proposedMajor+"."))
if err != nil {
return "", fmt.Errorf("invalid minor version: %v", err)
}
if proposedMinorInt > 0 {
proposedMinor = fmt.Sprintf("%s.%d", proposedMajor, proposedMinorInt-1)
}
}

for _, tag := range tags {
if tag == proposedTag {
continue
}
tagMajor := semver.Major(tag)
tagMinor := semver.MajorMinor(tag)
tagPatch, tagRC, err := extractPatchAndRC(tag)
if err != nil {
continue
}

// Only bother considering tags with the same major and minor version.
if tagMajor == proposedMajor && tagMinor == proposedMinor {
// If it's a non-RC release...
if proposedRC == "0" {
// Only consider non-RC tags.
if tagRC == "0" {
if semver.Compare(tag, previousTag) > 0 {
previousTag = tag
}
}
} else {
if tagRC != "0" && tagPatch == proposedPatch {
if semver.Compare(tag, previousTag) > 0 {
previousTag = tag
}
} else if tagRC == "0" {
if semver.Compare(tag, previousTag) > 0 {
previousTag = tag
}
}
}
}
}
if previousTag == "" {
return "", fmt.Errorf("no matching tag found for tags: " + strings.Join(tags, ", "))
}
return previousTag, nil
}

func getGitTags() ([]string, error) {
cmd := exec.Command("git", "tag", "--sort=-v:refname")
output, err := cmd.Output()
if err != nil {
return nil, fmt.Errorf("error executing git command: %v", err)
}

tags := strings.Split(string(output), "\n")
var semverTags []string
for _, tag := range tags {
if semver.IsValid(tag) {
semverTags = append(semverTags, tag)
}
}

return semverTags, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package main

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestFindPreviousTagRules(t *testing.T) {
t.Parallel()
// Sample pulled from git tag --sort=-v:refname output.
tags := []string{
"v2.13.0-rc3",
"v2.13.0-rc2",
"v2.13.0-rc1",
"v2.12.5",
"v2.12.4",
"v2.12.3",
"v2.12.2",
"v2.12.1",
"v2.12.0-rc5",
"v2.12.0-rc4",
"v2.12.0-rc3",
"v2.12.0-rc2",
"v2.12.0-rc1",
"v2.12.0",
"v2.11.11",
"v2.11.10",
"v2.11.9",
"v2.11.8",
"v2.11.7",
"v2.11.6",
"v2.11.5",
"v2.11.4",
"v2.11.3",
"v2.11.2",
"v2.11.1",
"v2.11.0-rc3",
"v2.11.0-rc2",
"v2.11.0-rc1",
"v2.11.0",
"v2.10.17",
"v2.10.16",
"v2.10.15",
"v2.10.14",
"v2.10.13",
"v2.10.12",
"v2.10.11",
"v2.10.10",
"v2.10.9",
"v2.10.8",
"v2.10.7",
"v2.10.6",
"v2.10.5",
"v2.10.4",
"v2.10.3",
"v2.10.2",
"v2.10.1",
"v2.10.0-rc5",
"v2.10.0-rc4",
"v2.10.0-rc3",
"v2.10.0-rc2",
"v2.10.0-rc1",
"v2.10.0",
}

tests := []struct {
name, proposedTag, expected string
expectError bool
}{
// Rule 1: If we're releasing a .0 patch release, get the most recent tag on the previous minor release series.
{"Rule 1: .0 patch release", "v2.13.0", "v2.12.5", false},
// Rule 2: If we're releasing a non-0 patch release, get the most recent tag within the same minor release series.
{"Rule 2: non-0 patch release", "v2.12.6", "v2.12.5", false},
// Rule 3: If we're releasing a 1 release candidate, get the most recent tag on the previous minor release series.
{"Rule 3: 1 release candidate", "v2.14.0-rc1", "v2.13.0-rc3", false},
// Rule 4: If we're releasing a non-1 release candidate, get the most recent rc tag on the current minor release series.
{"Rule 4: non-1 release candidate", "v2.13.0-rc4", "v2.13.0-rc3", false},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
result, err := findPreviousTag(test.proposedTag, tags)
if test.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equalf(t, test.expected, test.expected, "for proposed tag %s expected %s but got %s", test.proposedTag, test.expected, result)
}
})
}
}
14 changes: 14 additions & 0 deletions hack/get-previous-release/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module github.com/argoproj/argo-cd/get-previous-release

go 1.22.5

require (
github.com/stretchr/testify v1.9.0
golang.org/x/mod v0.21.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
12 changes: 12 additions & 0 deletions hack/get-previous-release/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit b8f85c9

Please sign in to comment.