Skip to content

Commit

Permalink
generate release notes for delta since latest release of each chart
Browse files Browse the repository at this point in the history
  • Loading branch information
qrkourier committed Jul 24, 2024
1 parent 61a6b61 commit b2f5ad6
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 10 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ git-upload-url: https://uploads.github.com/
cr upload --config config.yaml
```

`cr` supports any format [Viper](https://github.com/spf13/viper) can read, i. e. JSON, TOML, YAML, HCL, and Java properties files.
`cr` supports any format [Viper](https://github.com/spf13/viper) can read, i.e. JSON, TOML, YAML, HCL, and Java properties files.

Notice that if no config file is specified, `cr.yaml` (or any of the supported formats) is loaded from the current directory, `$HOME/.cr`, or `/etc/cr`, in that order, if found.

Expand All @@ -279,7 +279,7 @@ and then look for `upload_url`. You need the part of the URL that appears before

## Common Error Messages

During the upload, you can get the follwing error :
During the upload, you can get the following error :

```bash
422 Validation Failed [{Resource:Release Field:tag_name Code:already_exists Message:}]
Expand All @@ -289,8 +289,8 @@ You can solve it by adding the `--skip-existing` flag to your command. More deta

## Known Bug

Currently, if you set the upload URL incorrectly, let's say to something like `https://example.com/uploads/`, then `cr upload` will appear to work, but the release will not be complete. When everything is working there should be 3 assets in each release, but instead there will only be the 2 source code assets. The third asset, which is what helm actually uses, is missing. This issue will become apparent when you run `cr index` and it always claims that nothing has changed, because it can't find the asset it expects for the release.
Currently, if you set the upload URL incorrectly, let's say to something like `https://example.com/uploads/`, then `cr upload` will appear to work, but the release will not be complete. When everything is working there should be three assets in each release, but instead, there will only be two source code assets. The third asset is missing and is needed by Helm. This issue will become apparent when you run `cr index` and it always claims that nothing has changed, because it can't find the asset it expects for the release.

It appears like the [go-github Do call](https://github.com/google/go-github/blob/master/github/github.go#L520) does not catch the fact that the upload URL is incorrect and pass back the expected error. If the asset upload fails, it would be better if the release was rolled back (deleted) and an appropriate log message is be displayed to the user.
It appears like the [go-github Do call](https://github.com/google/go-github/blob/master/github/github.go#L520) does not catch the fact that the upload URL is incorrect and passes back the expected error. If the asset upload fails, it would be better if the release was rolled back (deleted) and an appropriate log message is displayed to the user.

The `cr index` command should also generate a warning when a release has no assets attached to it, to help people detect and troubleshoot this type of problem.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ toolchain go1.22.4
require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/Songmu/retry v0.1.0
github.com/blang/semver v3.5.1+incompatible
github.com/google/go-github/v56 v56.0.0
github.com/magefile/mage v1.15.0
github.com/mitchellh/go-homedir v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
Expand Down
62 changes: 60 additions & 2 deletions pkg/github/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/Songmu/retry"
"github.com/pkg/errors"

"github.com/blang/semver"
"github.com/google/go-github/v56/github"
"golang.org/x/oauth2"
)
Expand All @@ -34,7 +35,6 @@ type Release struct {
Description string
Assets []*Asset
Commit string
GenerateReleaseNotes bool
MakeLatest string
}

Expand Down Expand Up @@ -102,14 +102,72 @@ func (c *Client) GetRelease(_ context.Context, tag string) (*Release, error) {
return result, nil
}

// GetLatestChartRelease queries the GitHub API for the previous release of a chart
func (c *Client) GetLatestChartRelease(_ context.Context, prefix string) (*Release, error) {
// Find all releases with tags matching prefix
opt := &github.ListOptions{
PerPage: 100,
}
var releases []*github.RepositoryRelease
for {
rels, resp, err := c.Repositories.ListReleases(context.TODO(), c.owner, c.repo, opt)
if err != nil {
return nil, err
}
for _, rel := range rels {
if strings.HasPrefix(*rel.TagName, prefix) {
releases = append(releases, rel)
}
}
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}

// Sort those tags by their semver suffixes
var tags []semver.Version
for _, rel := range releases {
tags = append(tags, semver.MustParse(*rel.TagName))
}

// Find release with highest semver tag
semver.Sort(tags)
latestTag := tags[len(tags)-1]
var release *github.RepositoryRelease
if rel, _, err := c.Repositories.GetReleaseByTag(context.TODO(), c.owner, c.repo, prefix+latestTag.String()); err == nil {
release = rel
}

result := &Release{
Assets: []*Asset{},
}
for _, ass := range release.Assets {
asset := &Asset{*ass.Name, *ass.BrowserDownloadURL}
result.Assets = append(result.Assets, asset)
}
return result, nil
}

// GenerateReleaseNotes generates the release notes for a release
func (c *Client) GenerateReleaseNotes(_ context.Context, latestRelease *Release, nextRelease string) (string, error) {
notes, _, err := c.Repositories.GenerateReleaseNotes(context.TODO(), c.owner, c.repo, &github.GenerateNotesOptions{
TagName: nextRelease,
PreviousTagName: &latestRelease.Name,
})
if err != nil {
return "", err
}
return notes.Body, err
}

// CreateRelease creates a new release object in the GitHub API
func (c *Client) CreateRelease(_ context.Context, input *Release) error {
req := &github.RepositoryRelease{
Name: &input.Name,
Body: &input.Description,
TagName: &input.Name,
TargetCommitish: &input.Commit,
GenerateReleaseNotes: &input.GenerateReleaseNotes,
MakeLatest: &input.MakeLatest,
}

Expand Down
24 changes: 20 additions & 4 deletions pkg/releaser/releaser.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ type GitHub interface {
CreateRelease(ctx context.Context, input *github.Release) error
GetRelease(ctx context.Context, tag string) (*github.Release, error)
CreatePullRequest(owner string, repo string, message string, head string, base string) (string, error)
GetLatestChartRelease(ctx context.Context, prefix string) (*github.Release, error)
GenerateReleaseNotes(ctx context.Context, latestRelease *github.Release, nextRelease string) (string, error)
}

type Git interface {
Expand Down Expand Up @@ -238,16 +240,27 @@ func (r *Releaser) computeReleaseName(chart *chart.Chart) (string, error) {
return releaseName, nil
}

func (r *Releaser) getReleaseNotes(chart *chart.Chart) string {
func (r *Releaser) getReleaseNotes(chart *chart.Chart) (string, error) {
if r.config.ReleaseNotesFile != "" {
for _, f := range chart.Files {
if f.Name == r.config.ReleaseNotesFile {
return string(f.Data)
}
}
fmt.Printf("The release note file %q, is not present in the chart package\n", r.config.ReleaseNotesFile)
} else if r.config.GenerateReleaseNotes {
latestRelease, err := r.github.GetLatestChartRelease(context.TODO(), chart.Metadata.Name)
if err != nil {
return "", errors.Wrapf(err, "failed to get latest release for chart %s", chart.Metadata.Name)
}
notes, err := r.github.GenerateReleaseNotes(context.TODO(), latestRelease, chart.Metadata.Version)
if err != nil {
return "", errors.Wrapf(err, "failed to generate release notes for chart %s", chart.Metadata.Name)
}
return notes, nil
} else {
return chart.Metadata.Description, nil
}
return chart.Metadata.Description
}

func (r *Releaser) splitPackageNameAndVersion(pkg string) []string {
Expand Down Expand Up @@ -307,15 +320,18 @@ func (r *Releaser) CreateReleases() error {
if err != nil {
return err
}
notes, err := r.getReleaseNotes(ch)
if err != nil {
return err
}

release := &github.Release{
Name: releaseName,
Description: r.getReleaseNotes(ch),
Description: notes,
Assets: []*github.Asset{
{Path: p},
},
Commit: r.config.Commit,
GenerateReleaseNotes: r.config.GenerateReleaseNotes,
MakeLatest: strconv.FormatBool(r.config.MakeReleaseLatest),
}
provFile := fmt.Sprintf("%s.prov", p)
Expand Down

0 comments on commit b2f5ad6

Please sign in to comment.