refactor: cleanup label handling

This commit is contained in:
Julian Tölle 2024-08-17 15:45:36 +02:00
parent 32734d9aa1
commit f2a982d7a0
3 changed files with 54 additions and 29 deletions

View file

@ -49,20 +49,35 @@ type Forge interface {
// Changesets looks up the Pull/Merge Requests for each commit, returning its parsed metadata. // Changesets looks up the Pull/Merge Requests for each commit, returning its parsed metadata.
Changesets(context.Context, []Commit) ([]Changeset, error) Changesets(context.Context, []Commit) ([]Changeset, error)
EnsureLabelsExist(context.Context, []string) error // EnsureLabelsExist verifies that all desired labels are available on the repository. If labels are missing, they
// are created them.
EnsureLabelsExist(context.Context, []Label) error
// PullRequestForBranch returns the open pull request between the branch and ForgeOptions.BaseBranch. If no open PR // PullRequestForBranch returns the open pull request between the branch and ForgeOptions.BaseBranch. If no open PR
// exists, it returns nil. // exists, it returns nil.
PullRequestForBranch(context.Context, string) (*ReleasePullRequest, error) PullRequestForBranch(context.Context, string) (*ReleasePullRequest, error)
// CreatePullRequest opens a new pull/merge request for the ReleasePullRequest.
CreatePullRequest(context.Context, *ReleasePullRequest) error CreatePullRequest(context.Context, *ReleasePullRequest) error
// UpdatePullRequest updates the pull/merge request identified through the ID of
// the ReleasePullRequest to the current description and title.
UpdatePullRequest(context.Context, *ReleasePullRequest) error UpdatePullRequest(context.Context, *ReleasePullRequest) error
SetPullRequestLabels(ctx context.Context, pr *ReleasePullRequest, remove, add []string) error
// SetPullRequestLabels updates the pull/merge request identified through the ID of
// the ReleasePullRequest to the current labels.
SetPullRequestLabels(ctx context.Context, pr *ReleasePullRequest, remove, add []Label) error
// ClosePullRequest closes the pull/merge request identified through the ID of
// the ReleasePullRequest, as it is no longer required.
ClosePullRequest(context.Context, *ReleasePullRequest) error ClosePullRequest(context.Context, *ReleasePullRequest) error
PendingReleases(context.Context) ([]*ReleasePullRequest, error) // PendingReleases returns a list of ReleasePullRequest. The list should contain all pull/merge requests that are
// merged and have the matching label.
PendingReleases(context.Context, Label) ([]*ReleasePullRequest, error)
CreateRelease(ctx context.Context, commit Commit, title, changelog string, prelease, latest bool) error // CreateRelease creates a release on the Forge, pointing at the commit with the passed in details.
CreateRelease(ctx context.Context, commit Commit, title, changelog string, prerelease, latest bool) error
} }
type ForgeOptions struct { type ForgeOptions struct {
@ -326,7 +341,7 @@ func (g *GitHub) Changesets(ctx context.Context, commits []Commit) ([]Changeset,
return changesets, nil return changesets, nil
} }
func (g *GitHub) EnsureLabelsExist(ctx context.Context, labels []string) error { func (g *GitHub) EnsureLabelsExist(ctx context.Context, labels []Label) error {
existingLabels := make([]string, 0, len(labels)) existingLabels := make([]string, 0, len(labels))
page := 1 page := 1
@ -354,12 +369,12 @@ func (g *GitHub) EnsureLabelsExist(ctx context.Context, labels []string) error {
} }
for _, label := range labels { for _, label := range labels {
if !slices.Contains(existingLabels, label) { if !slices.Contains(existingLabels, string(label)) {
g.log.Info("creating label in repository", "label.name", label) g.log.Info("creating label in repository", "label.name", label)
_, _, err := g.client.Issues.CreateLabel( _, _, err := g.client.Issues.CreateLabel(
ctx, g.options.Owner, g.options.Repo, ctx, g.options.Owner, g.options.Repo,
&github.Label{ &github.Label{
Name: &label, Name: Pointer(string(label)),
Color: Pointer(GitHubLabelColor), Color: Pointer(GitHubLabelColor),
}, },
) )
@ -422,7 +437,7 @@ func (g *GitHub) CreatePullRequest(ctx context.Context, pr *ReleasePullRequest)
// TODO: String ID? // TODO: String ID?
pr.ID = ghPR.GetNumber() pr.ID = ghPR.GetNumber()
err = g.SetPullRequestLabels(ctx, pr, []string{}, pr.Labels) err = g.SetPullRequestLabels(ctx, pr, []Label{}, pr.Labels)
if err != nil { if err != nil {
return err return err
} }
@ -445,20 +460,25 @@ func (g *GitHub) UpdatePullRequest(ctx context.Context, pr *ReleasePullRequest)
return nil return nil
} }
func (g *GitHub) SetPullRequestLabels(ctx context.Context, pr *ReleasePullRequest, remove, add []string) error { func (g *GitHub) SetPullRequestLabels(ctx context.Context, pr *ReleasePullRequest, remove, add []Label) error {
for _, label := range remove { for _, label := range remove {
_, err := g.client.Issues.RemoveLabelForIssue( _, err := g.client.Issues.RemoveLabelForIssue(
ctx, g.options.Owner, g.options.Repo, ctx, g.options.Owner, g.options.Repo,
pr.ID, label, pr.ID, string(label),
) )
if err != nil { if err != nil {
return err return err
} }
} }
addString := make([]string, 0, len(add))
for _, label := range add {
addString = append(addString, string(label))
}
_, _, err := g.client.Issues.AddLabelsToIssue( _, _, err := g.client.Issues.AddLabelsToIssue(
ctx, g.options.Owner, g.options.Repo, ctx, g.options.Owner, g.options.Repo,
pr.ID, add, pr.ID, addString,
) )
if err != nil { if err != nil {
return err return err
@ -481,7 +501,7 @@ func (g *GitHub) ClosePullRequest(ctx context.Context, pr *ReleasePullRequest) e
return nil return nil
} }
func (g *GitHub) PendingReleases(ctx context.Context) ([]*ReleasePullRequest, error) { func (g *GitHub) PendingReleases(ctx context.Context, pendingLabel Label) ([]*ReleasePullRequest, error) {
page := 1 page := 1
var prs []*ReleasePullRequest var prs []*ReleasePullRequest
@ -509,7 +529,7 @@ func (g *GitHub) PendingReleases(ctx context.Context) ([]*ReleasePullRequest, er
for _, pr := range ghPRs { for _, pr := range ghPRs {
pending := slices.ContainsFunc(pr.Labels, func(l *github.Label) bool { pending := slices.ContainsFunc(pr.Labels, func(l *github.Label) bool {
return l.GetName() == LabelReleasePending return l.GetName() == string(pendingLabel)
}) })
if !pending { if !pending {
continue continue
@ -559,9 +579,12 @@ func (g *GitHub) CreateRelease(ctx context.Context, commit Commit, title, change
} }
func gitHubPRToReleasePullRequest(pr *github.PullRequest) *ReleasePullRequest { func gitHubPRToReleasePullRequest(pr *github.PullRequest) *ReleasePullRequest {
labels := make([]string, 0, len(pr.Labels)) labels := make([]Label, 0, len(pr.Labels))
for _, label := range pr.Labels { for _, label := range pr.Labels {
labels = append(labels, label.GetName()) labelName := Label(label.GetName())
if slices.Contains(KnownLabels, Label(label.GetName())) {
labels = append(labels, labelName)
}
} }
var releaseCommit *Commit var releaseCommit *Commit

View file

@ -35,7 +35,7 @@ type ReleasePullRequest struct {
ID int ID int
Title string Title string
Description string Description string
Labels []string Labels []Label
Head string Head string
ReleaseCommit *Commit ReleaseCommit *Commit
@ -44,7 +44,7 @@ type ReleasePullRequest struct {
func NewReleasePullRequest(head, branch, version, changelogEntry string) (*ReleasePullRequest, error) { func NewReleasePullRequest(head, branch, version, changelogEntry string) (*ReleasePullRequest, error) {
rp := &ReleasePullRequest{ rp := &ReleasePullRequest{
Head: head, Head: head,
Labels: []string{LabelReleasePending}, Labels: []Label{LabelReleasePending},
} }
rp.SetTitle(branch, version) rp.SetTitle(branch, version)
@ -89,18 +89,20 @@ func (n NextVersionType) String() string {
} }
} }
// PR Labels // Label is the string identifier of a pull/merge request label on the forge.
const ( type Label string
LabelNextVersionTypeNormal = "rp-next-version::normal"
LabelNextVersionTypeRC = "rp-next-version::rc"
LabelNextVersionTypeBeta = "rp-next-version::beta"
LabelNextVersionTypeAlpha = "rp-next-version::alpha"
LabelReleasePending = "rp-release::pending" const (
LabelReleaseTagged = "rp-release::tagged" LabelNextVersionTypeNormal Label = "rp-next-version::normal"
LabelNextVersionTypeRC Label = "rp-next-version::rc"
LabelNextVersionTypeBeta Label = "rp-next-version::beta"
LabelNextVersionTypeAlpha Label = "rp-next-version::alpha"
LabelReleasePending Label = "rp-release::pending"
LabelReleaseTagged Label = "rp-release::tagged"
) )
var Labels = []string{ var KnownLabels = []Label{
LabelNextVersionTypeNormal, LabelNextVersionTypeNormal,
LabelNextVersionTypeRC, LabelNextVersionTypeRC,
LabelNextVersionTypeBeta, LabelNextVersionTypeBeta,

View file

@ -30,7 +30,7 @@ func New(forge Forge, logger *slog.Logger, targetBranch string) *ReleaserPleaser
func (rp *ReleaserPleaser) EnsureLabels(ctx context.Context) error { func (rp *ReleaserPleaser) EnsureLabels(ctx context.Context) error {
// TODO: Wrap Error // TODO: Wrap Error
return rp.forge.EnsureLabelsExist(ctx, Labels) return rp.forge.EnsureLabelsExist(ctx, KnownLabels)
} }
func (rp *ReleaserPleaser) Run(ctx context.Context) error { func (rp *ReleaserPleaser) Run(ctx context.Context) error {
@ -65,7 +65,7 @@ func (rp *ReleaserPleaser) runCreatePendingReleases(ctx context.Context) error {
logger := rp.logger.With("method", "runCreatePendingReleases") logger := rp.logger.With("method", "runCreatePendingReleases")
logger.InfoContext(ctx, "checking for pending releases") logger.InfoContext(ctx, "checking for pending releases")
prs, err := rp.forge.PendingReleases(ctx) prs, err := rp.forge.PendingReleases(ctx, LabelReleasePending)
if err != nil { if err != nil {
return err return err
} }
@ -119,7 +119,7 @@ func (rp *ReleaserPleaser) createPendingRelease(ctx context.Context, pr *Release
logger.DebugContext(ctx, "created release", "release.title", version, "release.url", rp.forge.ReleaseURL(version)) logger.DebugContext(ctx, "created release", "release.title", version, "release.url", rp.forge.ReleaseURL(version))
logger.DebugContext(ctx, "updating pr labels") logger.DebugContext(ctx, "updating pr labels")
err = rp.forge.SetPullRequestLabels(ctx, pr, []string{LabelReleasePending}, []string{LabelReleaseTagged}) err = rp.forge.SetPullRequestLabels(ctx, pr, []Label{LabelReleasePending}, []Label{LabelReleaseTagged})
if err != nil { if err != nil {
return err return err
} }