diff --git a/actions/prepare_branch.go b/actions/prepare_branch.go index f812aa0..8b747c5 100644 --- a/actions/prepare_branch.go +++ b/actions/prepare_branch.go @@ -2,8 +2,10 @@ package actions import ( "bytes" + "encoding/base64" "fmt" "os" + "strings" gh "github.com/google/go-github/v48/github" "github.com/ipfs/kuboreleaser/git" @@ -183,6 +185,75 @@ func (ctx PrepareBranch) UpdateVersion(branch, source, currentVersionNumber, bas return pr, nil } +func (ctx PrepareBranch) GetBody(branch, foreword string) (string, error) { + kuboCommits, err := ctx.GitHub.Compare(repos.Kubo.Owner, repos.Kubo.Repo, branch, repos.Kubo.DefaultBranch) + if err != nil { + return "", err + } + file, err := ctx.GitHub.GetFile(repos.Kubo.Owner, repos.Kubo.Repo, "go.mod", branch) + if err != nil { + return "", err + } + if file == nil { + return "", fmt.Errorf("https://github.com/%s/%s/tree/%s/go.mod not found", repos.Kubo.Owner, repos.Kubo.Repo, branch) + } + + content, err := base64.StdEncoding.DecodeString(*file.Content) + if err != nil { + return "", err + } + + // find the boxo version + boxoVersion := "" + for _, line := range strings.Split(string(content[:]), "\n") { + line = strings.TrimSpace(line) + if strings.HasPrefix(line, fmt.Sprintf("github.com/%s/%s", repos.Boxo.Owner, repos.Boxo.Repo)) { + boxoVersion = strings.Split(line, " ")[1] + break + } + } + if boxoVersion == "" { + return "", fmt.Errorf("boxo version not found in https://github.com/%s/%s/tree/%s/go.mod", repos.Kubo.Owner, repos.Kubo.Repo, branch) + } + + // find the boxo commit or tag in boxo version + boxoBranch := "" + if strings.Contains(boxoVersion, "-") { + boxoBranch = strings.Split(boxoVersion, "-")[2] + } else { + boxoBranch = boxoVersion + } + + boxoCommits, err := ctx.GitHub.Compare(repos.Boxo.Owner, repos.Boxo.Repo, boxoBranch, repos.Boxo.DefaultBranch) + if err != nil { + return "", err + } + + kuboCommitsStr := "```\n" + for _, commit := range kuboCommits[:100] { + kuboCommitsStr += fmt.Sprintf("%s %s\n", commit.GetSHA()[:7], strings.Split(commit.GetCommit().GetMessage(), "\n")[0]) + } + kuboCommitsStr += "```" + + boxoCommitsStr := "```\n" + for _, commit := range boxoCommits[:100] { + boxoCommitsStr += fmt.Sprintf("%s %s\n", commit.GetSHA()[:7], strings.Split(commit.GetCommit().GetMessage(), "\n")[0]) + } + boxoCommitsStr += "```" + + return fmt.Sprintf(`%s + +--- + +### Kubo commits **NOT** included in this release + +%s + +### Boxo commits **NOT** included in this release + +%s`, foreword, kuboCommitsStr, boxoCommitsStr), nil +} + func (ctx PrepareBranch) Run() error { log.Info("I'm going to create PRs that update the version in the release branch and the master branch.") log.Info("I'm also going to update the changelog if we're performing the final release. Please note that it might take a while because I have to clone a looooot of repos.") @@ -207,6 +278,17 @@ func (ctx PrepareBranch) Run() error { return err } + body, err = ctx.GetBody(branch, body) + if err != nil { + return err + } + + pr.Body = &body + err = ctx.GitHub.UpdatePR(pr) + if err != nil { + return err + } + fmt.Printf(`Your release PR is ready at %s\n`, pr.GetHTMLURL()) // TODO: check for conflicts and tell the user to resolve them diff --git a/github/github.go b/github/github.go index 7f0d6d9..740b6ed 100644 --- a/github/github.go +++ b/github/github.go @@ -357,6 +357,17 @@ func (c *Client) GetOrCreatePR(owner, repo, head, base, title, body string, draf return pr, nil } +func (c *Client) UpdatePR(pr *github.PullRequest) error { + log.WithFields(log.Fields{ + "owner": pr.Base.Repo.Owner.GetLogin(), + "repo": pr.Base.Repo.GetName(), + "number": pr.GetNumber(), + }).Debug("Updating PR...") + + _, _, err := c.v3.PullRequests.Edit(context.Background(), pr.Base.Repo.Owner.GetLogin(), pr.Base.Repo.GetName(), pr.GetNumber(), pr) + return err +} + func (c *Client) GetFile(owner, repo, path, ref string) (*github.RepositoryContent, error) { log.WithFields(log.Fields{ "owner": owner, @@ -746,3 +757,36 @@ func (c *Client) GetTag(owner, repo, tag string) (*github.Tag, error) { return t, err } + +func (c *Client) Compare(owner, repo, base, head string) ([]*github.RepositoryCommit, error) { + log.WithFields(log.Fields{ + "owner": owner, + "repo": repo, + "base": base, + "head": head, + }).Debug("Comparing...") + + opts := &github.ListOptions{PerPage: 100} + var commits []*github.RepositoryCommit + for { + cs, r, err := c.v3.Repositories.CompareCommits(context.Background(), owner, repo, base, head, opts) + if err != nil { + return nil, err + } + commits = append(commits, cs.Commits...) + if r.NextPage == 0 { + break + } + opts.Page = r.NextPage + } + + if len(commits) > 0 { + log.WithFields(log.Fields{ + "commits": len(commits), + }).Debug("Found commits") + } else { + log.Debug("Commits not found") + } + + return commits, nil +} diff --git a/repos/boxo.go b/repos/boxo.go new file mode 100644 index 0000000..48ff662 --- /dev/null +++ b/repos/boxo.go @@ -0,0 +1,13 @@ +package repos + +type boxo struct { + Owner string + Repo string + DefaultBranch string +} + +var Boxo = boxo{ + Owner: "ipfs", + Repo: "boxo", + DefaultBranch: "main", +}