From 69e7c77e6aee062c4bd812cde1ffca2bf10c7661 Mon Sep 17 00:00:00 2001 From: Derek McGowan Date: Tue, 28 Aug 2018 17:49:35 -0700 Subject: [PATCH] Add option to add links to changelog Allows creating links in changelog, similar to what Github does for markdown but works for dependencies as well. Signed-off-by: Derek McGowan --- cmd/containerd-release/main.go | 20 +++++++++++++ cmd/containerd-release/util.go | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/cmd/containerd-release/main.go b/cmd/containerd-release/main.go index 7130677d6..c190d0e27 100644 --- a/cmd/containerd-release/main.go +++ b/cmd/containerd-release/main.go @@ -116,11 +116,16 @@ This tool should be ran from the root of the project repository for a new releas Usage: "template filepath to use in place of the default", Value: defaultTemplateFile, }, + cli.BoolFlag{ + Name: "linkify,l", + Usage: "add links to changelog", + }, } app.Action = func(context *cli.Context) error { var ( releasePath = context.Args().First() tag = context.String("tag") + linkify = context.Bool("linkify") ) if tag == "" { tag = parseTag(releasePath) @@ -150,6 +155,11 @@ This tool should be ran from the root of the project repository for a new releas if err != nil { return err } + if linkify { + if err := linkifyChanges(changes, githubCommitLink(r.GithubRepo), githubPRLink(r.GithubRepo)); err != nil { + return err + } + } if err := addContributors(r.Previous, r.Commit, contributors); err != nil { return err } @@ -221,6 +231,16 @@ This tool should be ran from the root of the project repository for a new releas if err := addContributors(dep.Previous, dep.Commit, contributors); err != nil { return errors.Wrapf(err, "failed to get authors for %s", name) } + if linkify { + if !strings.HasPrefix(dep.Name, "github.com/") { + logrus.Debugf("linkify only supported for Github, skipping %s", dep.Name) + } else { + ghname := dep.Name[11:] + if err := linkifyChanges(changes, githubCommitLink(ghname), githubPRLink(ghname)); err != nil { + return err + } + } + } projectChanges = append(projectChanges, projectChange{ Name: name, diff --git a/cmd/containerd-release/util.go b/cmd/containerd-release/util.go index ec526bbda..552338490 100644 --- a/cmd/containerd-release/util.go +++ b/cmd/containerd-release/util.go @@ -25,6 +25,7 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "sort" "strings" @@ -113,6 +114,26 @@ func getChangelog(previous, commit string) ([]byte, error) { return git("log", "--oneline", gitChangeDiff(previous, commit)) } +func linkifyChanges(c []change, commit, msg func(change) (string, error)) error { + for i := range c { + commitLink, err := commit(c[i]) + if err != nil { + return err + } + + description, err := msg(c[i]) + if err != nil { + return err + } + + c[i].Commit = fmt.Sprintf("[`%s`](%s)", c[i].Commit, commitLink) + c[i].Description = description + + } + + return nil +} + func parseChangelog(changelog []byte) ([]change, error) { var ( changes []change @@ -282,3 +303,36 @@ func getTemplate(context *cli.Context) (string, error) { } return string(data), nil } + +func githubCommitLink(repo string) func(change) (string, error) { + return func(c change) (string, error) { + full, err := git("rev-parse", c.Commit) + if err != nil { + return "", err + } + commit := strings.TrimSpace(string(full)) + + return fmt.Sprintf("https://github.com/%s/commit/%s", repo, commit), nil + } +} + +func githubPRLink(repo string) func(change) (string, error) { + r := regexp.MustCompile("^Merge pull request #[0-9]+") + return func(c change) (string, error) { + var err error + message := r.ReplaceAllStringFunc(c.Description, func(m string) string { + idx := strings.Index(m, "#") + pr := m[idx+1:] + + // TODO: Validate links using github API + // TODO: Validate PR merged as commit hash + link := fmt.Sprintf("https://github.com/%s/pull/%s", repo, pr) + + return fmt.Sprintf("%s [#%s](%s)", m[:idx], pr, link) + }) + if err != nil { + return "", err + } + return message, nil + } +}