refactor(releasepr): rebuild pr description

Build PR description from scratch and parsed values instead of copying some of the AST to next description.
This commit is contained in:
Julian Tölle 2024-08-08 18:58:57 +02:00
parent 04ace5cb05
commit 3dd9e61197
4 changed files with 67 additions and 134 deletions

View file

@ -352,7 +352,12 @@ func reconcileReleasePR(ctx context.Context, forge rp.Forge, changesets []rp.Cha
logger.InfoContext(ctx, "opened pull request", "pr.title", pr.Title, "pr.id", pr.ID) logger.InfoContext(ctx, "opened pull request", "pr.title", pr.Title, "pr.id", pr.ID)
} else { } else {
pr.SetTitle(flagBranch, nextVersion) pr.SetTitle(flagBranch, nextVersion)
err = pr.SetDescription(changelogEntry)
overrides, err := pr.GetOverrides()
if err != nil {
return err
}
err = pr.SetDescription(changelogEntry, overrides)
if err != nil { if err != nil {
return err return err
} }

View file

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"log" "log"
"regexp" "regexp"
"strings"
"text/template" "text/template"
"github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/ast"
@ -47,7 +48,7 @@ func NewReleasePullRequest(head, branch, version, changelogEntry string) (*Relea
} }
rp.SetTitle(branch, version) rp.SetTitle(branch, version)
if err := rp.SetDescription(changelogEntry); err != nil { if err := rp.SetDescription(changelogEntry, ReleaseOverrides{}); err != nil {
return nil, err return nil, err
} }
@ -115,7 +116,6 @@ const (
) )
const ( const (
MarkdownSectionOverrides = "overrides"
MarkdownSectionChangelog = "changelog" MarkdownSectionChangelog = "changelog"
) )
@ -190,51 +190,6 @@ func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (Rele
return overrides, nil return overrides, nil
} }
func (pr *ReleasePullRequest) overridesText() (string, error) {
source := []byte(pr.Description)
gm := markdown.New()
descriptionAST := gm.Parser().Parse(text.NewReader(source))
var section *east.Section
err := ast.Walk(descriptionAST, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkContinue, nil
}
if n.Type() != ast.TypeBlock || n.Kind() != east.KindSection {
return ast.WalkContinue, nil
}
anySection, ok := n.(*east.Section)
if !ok {
return ast.WalkStop, fmt.Errorf("node has unexpected type: %T", n)
}
if anySection.Name != MarkdownSectionOverrides {
return ast.WalkContinue, nil
}
section = anySection
return ast.WalkStop, nil
})
if err != nil {
return "", err
}
if section == nil {
return "", nil
}
outputBuffer := new(bytes.Buffer)
err = gm.Renderer().Render(outputBuffer, source, section)
if err != nil {
return "", err
}
return outputBuffer.String(), nil
}
func (pr *ReleasePullRequest) ChangelogText() (string, error) { func (pr *ReleasePullRequest) ChangelogText() (string, error) {
source := []byte(pr.Description) source := []byte(pr.Description)
gm := markdown.New() gm := markdown.New()
@ -289,11 +244,11 @@ func textFromLines(source []byte, n ast.Node) string {
content = append(content, line.Value(source)...) content = append(content, line.Value(source)...)
} }
return string(content) return strings.TrimSpace(string(content))
} }
func (pr *ReleasePullRequest) SetTitle(branch, version string) { func (pr *ReleasePullRequest) SetTitle(branch, version string) {
pr.Title = fmt.Sprintf("chore(%s): release %s", branch, version) pr.Title = fmt.Sprintf(TitleFormat, branch, version)
} }
func (pr *ReleasePullRequest) Version() (string, error) { func (pr *ReleasePullRequest) Version() (string, error) {
@ -305,14 +260,9 @@ func (pr *ReleasePullRequest) Version() (string, error) {
return matches[2], nil return matches[2], nil
} }
func (pr *ReleasePullRequest) SetDescription(changelogEntry string) error { func (pr *ReleasePullRequest) SetDescription(changelogEntry string, overrides ReleaseOverrides) error {
overrides, err := pr.overridesText()
if err != nil {
return err
}
var description bytes.Buffer var description bytes.Buffer
err = releasePRTemplate.Execute(&description, map[string]any{ err := releasePRTemplate.Execute(&description, map[string]any{
"Changelog": changelogEntry, "Changelog": changelogEntry,
"Overrides": overrides, "Overrides": overrides,
}) })

View file

@ -1,29 +1,32 @@
---
<!-- section-start changelog --> <!-- section-start changelog -->
{{ .Changelog }} {{ .Changelog }}
<!-- section-end changelog --> <!-- section-end changelog -->
--- ---
## releaser-pleaser Instructions <details>
{{ if .Overrides }} <summary><h4>PR by <a href="https://github.com/apricote/releaser-pleaser">releaser-pleaser</a> 🤖</h4></summary>
{{- .Overrides -}}
{{- else }}
<!-- section-start overrides -->
> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
### Prefix If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
## Release Notes
### Prefix / Start
This will be added to the start of the release notes.
```rp-prefix ```rp-prefix
{{- if .Overrides.Prefix }}
{{ .Overrides.Prefix }}{{ end }}
``` ```
### Suffix ### Suffix / End
This will be added to the end of the release notes.
```rp-suffix ```rp-suffix
{{- if .Overrides.Suffix }}
{{ .Overrides.Suffix }}{{ end }}
``` ```
<!-- section-end overrides --> </details>
{{ end }}
#### PR by [releaser-pleaser](https://github.com/apricote/releaser-pleaser)

View file

@ -49,121 +49,96 @@ func TestReleasePullRequest_SetDescription(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
pr *ReleasePullRequest
changelogEntry string changelogEntry string
overrides ReleaseOverrides
want string want string
wantErr assert.ErrorAssertionFunc wantErr assert.ErrorAssertionFunc
}{ }{
{ {
name: "empty description", name: "no overrides",
pr: &ReleasePullRequest{},
changelogEntry: `## v1.0.0`, changelogEntry: `## v1.0.0`,
want: `--- overrides: ReleaseOverrides{},
want: `<!-- section-start changelog -->
<!-- section-start changelog -->
## v1.0.0 ## v1.0.0
<!-- section-end changelog --> <!-- section-end changelog -->
--- ---
## releaser-pleaser Instructions <details>
<summary><h4>PR by <a href="https://github.com/apricote/releaser-pleaser">releaser-pleaser</a> 🤖</h4></summary>
<!-- section-start overrides --> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
### Prefix ## Release Notes
### Prefix / Start
This will be added to the start of the release notes.
` + "```" + `rp-prefix ` + "```" + `rp-prefix
` + "```" + ` ` + "```" + `
### Suffix ### Suffix / End
This will be added to the end of the release notes.
` + "```" + `rp-suffix ` + "```" + `rp-suffix
` + "```" + ` ` + "```" + `
<!-- section-end overrides --> </details>
#### PR by [releaser-pleaser](https://github.com/apricote/releaser-pleaser)
`, `,
wantErr: assert.NoError, wantErr: assert.NoError,
}, },
{ {
name: "existing overrides", name: "existing overrides",
pr: &ReleasePullRequest{
Description: `---
<!-- section-start changelog -->
## v0.1.0
### Features
- bedazzle
<!-- section-end changelog -->
---
## releaser-pleaser Instructions
<!-- section-start overrides -->
> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
### Prefix
` + "```" + `rp-prefix
This release is awesome!
` + "```" + `
### Suffix
` + "```" + `rp-suffix
` + "```" + `
<!-- section-end overrides -->
#### PR by [releaser-pleaser](https://github.com/apricote/releaser-pleaser)
`,
},
changelogEntry: `## v1.0.0`, changelogEntry: `## v1.0.0`,
want: `--- overrides: ReleaseOverrides{
Prefix: "This release is awesome!",
<!-- section-start changelog --> Suffix: "Fooo",
},
want: `<!-- section-start changelog -->
## v1.0.0 ## v1.0.0
<!-- section-end changelog --> <!-- section-end changelog -->
--- ---
## releaser-pleaser Instructions <details>
<summary><h4>PR by <a href="https://github.com/apricote/releaser-pleaser">releaser-pleaser</a> 🤖</h4></summary>
<!-- section-start overrides --> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
> If you want to modify the proposed release, add you overrides here. You can learn more about the options in the docs.
### Prefix ## Release Notes
### Prefix / Start
This will be added to the start of the release notes.
` + "```" + `rp-prefix ` + "```" + `rp-prefix
This release is awesome! This release is awesome!
` + "```" + ` ` + "```" + `
### Suffix ### Suffix / End
This will be added to the end of the release notes.
` + "```" + `rp-suffix ` + "```" + `rp-suffix
Fooo
` + "```" + ` ` + "```" + `
<!-- section-end overrides --> </details>
#### PR by [releaser-pleaser](https://github.com/apricote/releaser-pleaser)
`, `,
wantErr: assert.NoError, wantErr: assert.NoError,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
err := tt.pr.SetDescription(tt.changelogEntry) pr := &ReleasePullRequest{}
err := pr.SetDescription(tt.changelogEntry, tt.overrides)
if !tt.wantErr(t, err) { if !tt.wantErr(t, err) {
return return
} }
assert.Equal(t, tt.want, tt.pr.Description) assert.Equal(t, tt.want, pr.Description)
}) })
} }
} }