You've already forked goreleaser
							
							
				mirror of
				https://github.com/goreleaser/goreleaser.git
				synced 2025-10-30 23:58:09 +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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							2519581221
						
					
				
				
					commit
					bbcc45b677
				
			| @@ -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{ | ||||
| 		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)"), | ||||
| 		Draft: github.Bool(draft), | ||||
| 	}) | ||||
| 	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(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 != "" { | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user