mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-02-07 10:17:02 +00:00
feat: push branch with changelog
This commit is contained in:
parent
8199918903
commit
c7743e0a80
10 changed files with 313 additions and 36 deletions
|
|
@ -7,6 +7,9 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
"github.com/go-git/go-git/v5/config"
|
||||
"github.com/go-git/go-git/v5/plumbing"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
rp "github.com/apricote/releaser-pleaser"
|
||||
|
|
@ -61,12 +64,12 @@ func run(cmd *cobra.Command, args []string) error {
|
|||
})
|
||||
}
|
||||
|
||||
changesets, err := getChangesetsFromForge(ctx, f)
|
||||
changesets, tag, err := getChangesetsFromForge(ctx, f)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get changesets: %w", err)
|
||||
}
|
||||
|
||||
err = reconcileReleasePR(ctx, f, changesets)
|
||||
err = reconcileReleasePR(ctx, f, changesets, tag)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reconcile release pr: %w", err)
|
||||
}
|
||||
|
|
@ -74,32 +77,38 @@ func run(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getChangesetsFromForge(ctx context.Context, forge rp.Forge) ([]rp.Changeset, error) {
|
||||
func getChangesetsFromForge(ctx context.Context, forge rp.Forge) ([]rp.Changeset, *rp.Tag, error) {
|
||||
tag, err := forge.LatestTag(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
logger.InfoContext(ctx, "Latest Tag", "tag.hash", tag.Hash, "tag.name", tag.Name)
|
||||
if tag != nil {
|
||||
logger.InfoContext(ctx, "found previous tag", "tag.hash", tag.Hash, "tag.name", tag.Name)
|
||||
} else {
|
||||
logger.InfoContext(ctx, "no previous tag found")
|
||||
}
|
||||
|
||||
releasableCommits, err := forge.CommitsSince(ctx, tag)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
logger.InfoContext(ctx, "Found releasable commits", "length", len(releasableCommits))
|
||||
|
||||
changesets, err := forge.Changesets(ctx, releasableCommits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
logger.InfoContext(ctx, "Found changesets", "length", len(changesets))
|
||||
|
||||
return changesets, nil
|
||||
return changesets, tag, nil
|
||||
}
|
||||
|
||||
func reconcileReleasePR(ctx context.Context, forge rp.Forge, changesets []rp.Changeset) error {
|
||||
func reconcileReleasePR(ctx context.Context, forge rp.Forge, changesets []rp.Changeset, tag *rp.Tag) error {
|
||||
rpBranch := fmt.Sprintf(RELEASER_PLEASER_BRANCH, flagBranch)
|
||||
rpBranchRef := plumbing.NewBranchReferenceName(rpBranch)
|
||||
// Check Forge for open PR
|
||||
// Get any modifications from open PR
|
||||
// Clone Repo
|
||||
|
|
@ -114,12 +123,90 @@ func reconcileReleasePR(ctx context.Context, forge rp.Forge, changesets []rp.Cha
|
|||
logger.InfoContext(ctx, "found existing release pull request: %d: %s", pr.ID, pr.Title)
|
||||
}
|
||||
|
||||
releaseOverrides, err := pr.GetOverrides()
|
||||
var releaseOverrides rp.ReleaseOverrides
|
||||
if pr != nil {
|
||||
releaseOverrides, err = pr.GetOverrides()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
nextVersion, err := rp.NextVersion(tag, changesets, releaseOverrides.NextVersionType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logger.InfoContext(ctx, "next version", "version", nextVersion)
|
||||
|
||||
logger.DebugContext(ctx, "cloning repository", "clone.url", forge.CloneURL())
|
||||
repo, err := rp.CloneRepo(ctx, forge.CloneURL(), flagBranch, forge.GitAuth())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
worktree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// ...
|
||||
if branch, _ := repo.Branch(rpBranch); branch != nil {
|
||||
logger.DebugContext(ctx, "deleting previous releaser-pleaser branch locally", "branch.name", rpBranch)
|
||||
if err = repo.DeleteBranch(rpBranch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = worktree.Checkout(&git.CheckoutOptions{
|
||||
Branch: rpBranchRef,
|
||||
Create: true,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rp.RunUpdater(ctx, nextVersion, worktree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changelogEntry, err := rp.NewChangelogEntry(changesets, nextVersion, forge.ReleaseURL(nextVersion))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = rp.UpdateChangelogFile(worktree, changelogEntry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
releaseCommitMessage := fmt.Sprintf("chore(%s): release %s", flagBranch, nextVersion)
|
||||
releaseCommit, err := worktree.Commit(releaseCommitMessage, &git.CommitOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.InfoContext(ctx, "created release commit", "commit.hash", releaseCommit.String(), "commit.message", releaseCommitMessage)
|
||||
|
||||
// TODO: Check if there is a diff between forge/rpBranch..rpBranch..forge/rpBranch and only push if there are changes
|
||||
// To reduce wasted CI cycles
|
||||
|
||||
pushRefSpec := config.RefSpec(fmt.Sprintf(
|
||||
"+%s:%s",
|
||||
rpBranchRef,
|
||||
// This needs to be the local branch name, not the remotes/origin ref
|
||||
// See https://stackoverflow.com/a/75727620
|
||||
rpBranchRef,
|
||||
))
|
||||
logger.DebugContext(ctx, "pushing branch", "commit.hash", releaseCommit.String(), "branch.name", rpBranch, "refspec", pushRefSpec.String())
|
||||
if err = repo.PushContext(ctx, &git.PushOptions{
|
||||
RemoteName: rp.GitRemoteName,
|
||||
RefSpecs: []config.RefSpec{pushRefSpec},
|
||||
Force: true,
|
||||
Auth: forge.GitAuth(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.InfoContext(ctx, "pushed branch", "commit.hash", releaseCommit.String(), "branch.name", rpBranch, "refspec", pushRefSpec.String())
|
||||
|
||||
// TODO Open PR
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue