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

Create CAPI releases #1183

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add all app and component version changes since last release to the release notes.

## [7.0.0] - 2024-12-13

**Note** Creating vintage releases is not supported anymore, please use an older release of `devctl`.
Expand Down
90 changes: 32 additions & 58 deletions pkg/release/changelog/changelog.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package changelog

import (
"errors"
"fmt"
"io"
"net/http"
"regexp"
Expand Down Expand Up @@ -320,7 +321,7 @@ type Version struct {

const kubernetes = "kubernetes"

func ParseChangelog(componentName, componentVersion string) (*Version, error) {
func ParseChangelog(componentName, componentVersion, previousVersion string) (*Version, error) {
params, ok := knownComponentParseParams[componentName]
if !ok {
return nil, microerror.Mask(errors.New("unknown component: " + componentName))
Expand Down Expand Up @@ -387,77 +388,50 @@ func ParseChangelog(componentName, componentVersion string) (*Version, error) {
// Skip parsing and return the entire changelog for Flatcar and Kubernetes
return &currentVersion, nil
}
// Lines of the downloaded changelog
lines := strings.Split(string(body), "\n")

// Regexes used for parsing lines below
startPattern, err := regexp.Compile(params.start)
if err != nil {
return nil, microerror.Mask(err)
}
intermediatePattern, err := regexp.Compile(params.intermediate)
if err != nil {
return nil, microerror.Mask(err)
}
endPattern, err := regexp.Compile(params.end)
if err != nil {
return nil, microerror.Mask(err)
}
inSection := false
var preRoute string

versionFound := false
reachedVersionContent := false
reachedIntermediateMarker := params.intermediate == ""
lines := strings.Split(string(body), "\n")
for _, line := range lines {
// Skip blank lines
if line == "" {
continue
// When we see the previousVersion line, we stop collecting
if strings.Contains(line, "## ["+previousVersion+"]") && inSection {
break
}

isStartLine := params.start != "" && startPattern.MatchString(line)
isEndLine := params.end != "" && endPattern.MatchString(line)

if (isStartLine || isEndLine) && reachedVersionContent {
// The version has been fully extracted, stop parsing lines and return.
break
// When we see the start line for currentVersion, begin collecting
if strings.Contains(line, "## ["+componentVersion+"]") {
inSection = true
continue
}

if isStartLine {
// Get "Version" part from regex
subMatches := startPattern.FindStringSubmatch(line)
var version string
versionInStartPattern := false
for i, subName := range startPattern.SubexpNames() {
if subName == "Version" {
versionInStartPattern = true
version = subMatches[i]
var startRegex = regexp.MustCompile(commonStartPattern)
if inSection {
// Replace "## [" at the start with "### Previous Version ["
if strings.HasPrefix(line, "## [") {
matches := startRegex.FindStringSubmatch(line)
if len(matches) > 1 {
oldVersion := matches[1]
line = fmt.Sprintf(
"#### Previous Version %s [%s](%s)",
componentName, oldVersion, strings.Replace(params.tag, "{{.Version}}", oldVersion, -1))
// when adding former versions we need to inherit the preRoute
preRoute = "#"
}
}

// Skip if this isn't the desired version
if versionInStartPattern && version != componentVersion {
continue
} else if strings.HasPrefix(line, "### ") && !strings.Contains(line, "[") {
// Increase heading level for lines like “### Added” → “##### Added”
line = preRoute + "#" + line
}

reachedVersionContent = true
versionFound = true
} else if reachedVersionContent {
// An intermediate marker indicates that the non-useful info at the start
// of the changelog has been passed.
if !reachedIntermediateMarker {
reachedIntermediateMarker = intermediatePattern.MatchString(line)
continue
}

// Transform level 1-3 headers like "#"-"###" into at least level 4 headers like "####"
for strings.HasPrefix(line, "#") && !strings.HasPrefix(line, "#### ") {
line = "#" + line
}

// Accumulate the changelog lines for the currentVersion
currentVersion.Content += line + "\n"
}
}

if !versionFound {
currentVersion.Content = "Not found"
// If we never entered the section, we didn’t find the version
if !inSection || currentVersion.Content == "" {
return nil, microerror.Mask(fmt.Errorf("version [%s] not found in changelog", currentVersion))
}

return &currentVersion, nil
Expand Down
4 changes: 2 additions & 2 deletions pkg/release/release_notes.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func createReleaseNotes(release, baseRelease v1alpha1.Release, provider string)
}
}

componentChangelog, err := changelog.ParseChangelog(component.Name, component.Version)
componentChangelog, err := changelog.ParseChangelog(component.Name, component.Version, previousComponentVersion)
if err != nil {
return "", microerror.Mask(err)
}
Expand All @@ -126,7 +126,7 @@ func createReleaseNotes(release, baseRelease v1alpha1.Release, provider string)
}
}

componentChangelog, err := changelog.ParseChangelog(app.Name, app.Version)
componentChangelog, err := changelog.ParseChangelog(app.Name, app.Version, previousAppVersion)
if err != nil {
return "", microerror.Mask(err)
}
Expand Down
Loading