mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-02-08 10:47:02 +00:00
feat(releasepr): release PRs can be updated
- PR Description - Read prefix+suffix from PR description and put into changelog - Keep those overrides on PR description changes - Add pending level to new PRs
This commit is contained in:
parent
cb529f4760
commit
fe871a0213
17 changed files with 1442 additions and 22 deletions
116
releasepr.go
116
releasepr.go
|
|
@ -1,13 +1,34 @@
|
|||
package rp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"log"
|
||||
"text/template"
|
||||
|
||||
"github.com/yuin/goldmark/ast"
|
||||
"github.com/yuin/goldmark/parser"
|
||||
"github.com/yuin/goldmark/text"
|
||||
|
||||
"github.com/apricote/releaser-pleaser/internal/markdown"
|
||||
east "github.com/apricote/releaser-pleaser/internal/markdown/extensions/ast"
|
||||
)
|
||||
|
||||
var (
|
||||
releasePRTemplate *template.Template
|
||||
)
|
||||
|
||||
//go:embed releasepr.md.tpl
|
||||
var rawReleasePRTemplate string
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
releasePRTemplate, err = template.New("releasepr").Parse(rawReleasePRTemplate)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse release pr template: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
type ReleasePullRequest struct {
|
||||
ID int
|
||||
Title string
|
||||
|
|
@ -17,6 +38,20 @@ type ReleasePullRequest struct {
|
|||
Head string
|
||||
}
|
||||
|
||||
func NewReleasePullRequest(head, branch, version, changelogEntry string) (*ReleasePullRequest, error) {
|
||||
rp := &ReleasePullRequest{
|
||||
Head: head,
|
||||
Labels: []string{LabelReleasePending},
|
||||
}
|
||||
|
||||
rp.SetTitle(branch, version)
|
||||
if err := rp.SetDescription(changelogEntry); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rp, nil
|
||||
}
|
||||
|
||||
type ReleaseOverrides struct {
|
||||
Prefix string
|
||||
Suffix string
|
||||
|
|
@ -57,6 +92,9 @@ const (
|
|||
LabelNextVersionTypeRC = "rp-next-version::rc"
|
||||
LabelNextVersionTypeBeta = "rp-next-version::beta"
|
||||
LabelNextVersionTypeAlpha = "rp-next-version::alpha"
|
||||
|
||||
LabelReleasePending = "rp-release::pending"
|
||||
LabelReleaseTagged = "rp-release::tagged"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -64,6 +102,10 @@ const (
|
|||
DescriptionLanguageSuffix = "rp-suffix"
|
||||
)
|
||||
|
||||
const (
|
||||
MarkdownSectionOverrides = "overrides"
|
||||
)
|
||||
|
||||
func (pr *ReleasePullRequest) GetOverrides() (ReleaseOverrides, error) {
|
||||
overrides := ReleaseOverrides{}
|
||||
overrides = pr.parseVersioningFlags(overrides)
|
||||
|
|
@ -95,7 +137,7 @@ func (pr *ReleasePullRequest) parseVersioningFlags(overrides ReleaseOverrides) R
|
|||
|
||||
func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (ReleaseOverrides, error) {
|
||||
source := []byte(pr.Description)
|
||||
descriptionAST := parser.NewParser().Parse(text.NewReader(source))
|
||||
descriptionAST := markdown.New().Parser().Parse(text.NewReader(source))
|
||||
|
||||
err := ast.Walk(descriptionAST, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
|
||||
if !entering {
|
||||
|
|
@ -127,6 +169,51 @@ func (pr *ReleasePullRequest) parseDescription(overrides ReleaseOverrides) (Rele
|
|||
return overrides, nil
|
||||
}
|
||||
|
||||
func (pr *ReleasePullRequest) getCurrentOverridesText() (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 textFromLines(source []byte, n ast.Node) string {
|
||||
content := make([]byte, 0)
|
||||
|
||||
|
|
@ -137,5 +224,28 @@ func textFromLines(source []byte, n ast.Node) string {
|
|||
}
|
||||
|
||||
return string(content)
|
||||
|
||||
}
|
||||
|
||||
func (pr *ReleasePullRequest) SetTitle(branch, version string) {
|
||||
pr.Title = fmt.Sprintf("chore(%s): release %s", branch, version)
|
||||
}
|
||||
|
||||
func (pr *ReleasePullRequest) SetDescription(changelogEntry string) error {
|
||||
overrides, err := pr.getCurrentOverridesText()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var description bytes.Buffer
|
||||
err = releasePRTemplate.Execute(&description, map[string]any{
|
||||
"Changelog": changelogEntry,
|
||||
"Overrides": overrides,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pr.Description = description.String()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue