1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-07-17 01:42:37 +02:00

feat: support pull request templates (#4105)

check if there is a `.github/PULL_REQUEST_TEMPLATE.md` file, and use it
as body of the pull request if there is.

---------

Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
Carlos Alexandro Becker
2023-06-14 23:28:38 -03:00
committed by GitHub
parent 2519581221
commit bbcc45b677
2 changed files with 77 additions and 9 deletions

View File

@ -166,6 +166,22 @@ func headString(base, head Repo) string {
}, ":")
}
func (c *githubClient) getPRTemplate(ctx *context.Context, repo Repo) (string, error) {
content, _, _, err := c.client.Repositories.GetContents(
ctx, repo.Owner, repo.Name,
".github/PULL_REQUEST_TEMPLATE.md",
&github.RepositoryContentGetOptions{
Ref: repo.Branch,
},
)
if err != nil {
return "", err
}
return content.GetContent()
}
const prFooter = "###### Automated with [GoReleaser](https://goreleaser.com)"
func (c *githubClient) OpenPullRequest(
ctx *context.Context,
base, head Repo,
@ -180,26 +196,38 @@ func (c *githubClient) OpenPullRequest(
}
base.Branch = def
}
tpl, err := c.getPRTemplate(ctx, base)
if err != nil {
log.WithError(err).Debug("no pull request template found...")
}
if len(tpl) > 0 {
log.Info("got a pr template")
}
log := log.
WithField("base", headString(base, Repo{})).
WithField("head", headString(base, head)).
WithField("draft", draft)
log.Info("opening pull request")
pr, res, err := c.client.PullRequests.Create(ctx, base.Owner, base.Name, &github.NewPullRequest{
pr, res, err := c.client.PullRequests.Create(
ctx,
firstNonEmpty(base.Owner, head.Owner),
firstNonEmpty(base.Name, head.Name),
&github.NewPullRequest{
Title: github.String(title),
Base: github.String(base.Branch),
Head: github.String(headString(base, head)),
Body: github.String("Automatically generated by [GoReleaser](https://goreleaser.com)"),
Body: github.String(strings.Join([]string{tpl, prFooter}, "\n")),
Draft: github.Bool(draft),
})
},
)
if err != nil {
if res.StatusCode == 422 {
log.Warn("PR already exists, doing nothing...")
log.WithError(err).Warn("pull request validation failed")
return nil
}
return fmt.Errorf("could not create pull request: %w", err)
}
log.WithField("url", pr.GetHTMLURL()).Info("opened")
log.WithField("url", pr.GetHTMLURL()).Info("pull request created")
return nil
}
@ -240,6 +268,7 @@ func (c *githubClient) CreateFile(
log.
WithField("repository", repo.String()).
WithField("branch", repo.Branch).
WithField("file", path).
Info("pushing")
if defBranch != branch && branch != "" {

View File

@ -1,6 +1,7 @@
package client
import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
@ -405,10 +406,22 @@ func TestCloseMilestone(t *testing.T) {
require.NoError(t, client.CloseMilestone(ctx, repo, "v1.13.0"))
}
const testPRTemplate = "fake template\n- [ ] mark this\n---"
func TestOpenPullRequestCrossRepo(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.URL.Path == "/repos/someone/something/contents/.github/PULL_REQUEST_TEMPLATE.md" {
content := github.RepositoryContent{
Encoding: github.String("base64"),
Content: github.String(base64.StdEncoding.EncodeToString([]byte(testPRTemplate))),
}
bts, _ := json.Marshal(content)
_, _ = w.Write(bts)
return
}
if r.URL.Path == "/repos/someone/something/pulls" {
got, err := io.ReadAll(r.Body)
require.NoError(t, err)
@ -416,6 +429,7 @@ func TestOpenPullRequestCrossRepo(t *testing.T) {
require.NoError(t, json.Unmarshal(got, &pr))
require.Equal(t, "main", pr.GetBase())
require.Equal(t, "someoneelse:something:foo", pr.GetHead())
require.Equal(t, testPRTemplate+"\n"+prFooter, pr.GetBody())
r, err := os.Open("testdata/github/pull.json")
require.NoError(t, err)
_, err = io.Copy(w, r)
@ -457,6 +471,16 @@ func TestOpenPullRequestHappyPath(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.URL.Path == "/repos/someone/something/contents/.github/PULL_REQUEST_TEMPLATE.md" {
content := github.RepositoryContent{
Encoding: github.String("base64"),
Content: github.String(base64.StdEncoding.EncodeToString([]byte(testPRTemplate))),
}
bts, _ := json.Marshal(content)
_, _ = w.Write(bts)
return
}
if r.URL.Path == "/repos/someone/something/pulls" {
r, err := os.Open("testdata/github/pull.json")
require.NoError(t, err)
@ -495,6 +519,11 @@ func TestOpenPullRequestNoBaseBranchDraft(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.URL.Path == "/repos/someone/something/contents/.github/PULL_REQUEST_TEMPLATE.md" {
w.WriteHeader(http.StatusNotFound)
return
}
if r.URL.Path == "/repos/someone/something/pulls" {
got, err := io.ReadAll(r.Body)
require.NoError(t, err)
@ -548,6 +577,11 @@ func TestOpenPullRequestPRExists(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.URL.Path == "/repos/someone/something/contents/.github/PULL_REQUEST_TEMPLATE.md" {
w.WriteHeader(http.StatusNotFound)
return
}
if r.URL.Path == "/repos/someone/something/pulls" {
w.WriteHeader(http.StatusUnprocessableEntity)
r, err := os.Open("testdata/github/pull.json")
@ -587,6 +621,11 @@ func TestOpenPullRequestBaseEmpty(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
if r.URL.Path == "/repos/someone/something/contents/.github/PULL_REQUEST_TEMPLATE.md" {
w.WriteHeader(http.StatusNotFound)
return
}
if r.URL.Path == "/repos/someone/something/pulls" {
r, err := os.Open("testdata/github/pull.json")
require.NoError(t, err)