Skip to content

Commit d1858a3

Browse files
authored
Add generate release notes support (#2114)
1 parent e87b9aa commit d1858a3

File tree

5 files changed

+137
-1
lines changed

5 files changed

+137
-1
lines changed

github/github-accessors.go

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-stringify_test.go

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/repos_releases.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type RepositoryRelease struct {
2626
Draft *bool `json:"draft,omitempty"`
2727
Prerelease *bool `json:"prerelease,omitempty"`
2828
DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
29+
GenerateReleaseNotes *bool `json:"generate_release_notes,omitempty"`
2930

3031
// The following fields are not used in CreateRelease or EditRelease:
3132
ID *int64 `json:"id,omitempty"`
@@ -46,6 +47,19 @@ func (r RepositoryRelease) String() string {
4647
return Stringify(r)
4748
}
4849

50+
// RepositoryReleaseNotes represents a GitHub-generated release notes.
51+
type RepositoryReleaseNotes struct {
52+
Name string `json:"name"`
53+
Body string `json:"body"`
54+
}
55+
56+
// GenerateNotesOptions represents the options to generate release notes.
57+
type GenerateNotesOptions struct {
58+
TagName string `json:"tag_name"`
59+
PreviousTagName *string `json:"previous_tag_name,omitempty"`
60+
TargetCommitish *string `json:"target_commitish,omitempty"`
61+
}
62+
4963
// ReleaseAsset represents a GitHub release asset in a repository.
5064
type ReleaseAsset struct {
5165
ID *int64 `json:"id,omitempty"`
@@ -114,6 +128,25 @@ func (s *RepositoriesService) GetReleaseByTag(ctx context.Context, owner, repo,
114128
return s.getSingleRelease(ctx, u)
115129
}
116130

131+
// GenerateReleaseNotes generates the release notes for the given tag.
132+
// TODO: api docs
133+
// GitHub API docs:
134+
func (s *RepositoriesService) GenerateReleaseNotes(ctx context.Context, owner, repo string, opts *GenerateNotesOptions) (*RepositoryReleaseNotes, *Response, error) {
135+
u := fmt.Sprintf("repos/%s/%s/releases/generate-notes", owner, repo)
136+
req, err := s.client.NewRequest("POST", u, opts)
137+
if err != nil {
138+
return nil, nil, err
139+
}
140+
141+
r := new(RepositoryReleaseNotes)
142+
resp, err := s.client.Do(ctx, req, r)
143+
if err != nil {
144+
return nil, resp, err
145+
}
146+
147+
return r, resp, nil
148+
}
149+
117150
func (s *RepositoriesService) getSingleRelease(ctx context.Context, url string) (*RepositoryRelease, *Response, error) {
118151
req, err := s.client.NewRequest("GET", url, nil)
119152
if err != nil {
@@ -141,6 +174,7 @@ type repositoryReleaseRequest struct {
141174
Body *string `json:"body,omitempty"`
142175
Draft *bool `json:"draft,omitempty"`
143176
Prerelease *bool `json:"prerelease,omitempty"`
177+
GenerateReleaseNotes *bool `json:"generate_release_notes,omitempty"`
144178
DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
145179
}
146180

@@ -161,6 +195,7 @@ func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo str
161195
Draft: release.Draft,
162196
Prerelease: release.Prerelease,
163197
DiscussionCategoryName: release.DiscussionCategoryName,
198+
GenerateReleaseNotes: release.GenerateReleaseNotes,
164199
}
165200

166201
req, err := s.client.NewRequest("POST", u, releaseReq)
@@ -193,6 +228,7 @@ func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo strin
193228
Draft: release.Draft,
194229
Prerelease: release.Prerelease,
195230
DiscussionCategoryName: release.DiscussionCategoryName,
231+
GenerateReleaseNotes: release.GenerateReleaseNotes,
196232
}
197233

198234
req, err := s.client.NewRequest("PATCH", u, releaseReq)

github/repos_releases_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,47 @@ func TestRepositoriesService_ListReleases(t *testing.T) {
5555
})
5656
}
5757

58+
func TestRepositoriesService_GenerateReleaseNotes(t *testing.T) {
59+
client, mux, _, teardown := setup()
60+
defer teardown()
61+
62+
mux.HandleFunc("/repos/o/r/releases/generate-notes", func(w http.ResponseWriter, r *http.Request) {
63+
testMethod(t, r, "POST")
64+
testBody(t, r, `{"tag_name":"v1.0.0"}`+"\n")
65+
fmt.Fprint(w, `{"name":"v1.0.0","body":"**Full Changelog**: https://github.com/o/r/compare/v0.9.0...v1.0.0"}`)
66+
})
67+
68+
opt := &GenerateNotesOptions{
69+
TagName: "v1.0.0",
70+
}
71+
ctx := context.Background()
72+
releases, _, err := client.Repositories.GenerateReleaseNotes(ctx, "o", "r", opt)
73+
if err != nil {
74+
t.Errorf("Repositories.GenerateReleaseNotes returned error: %v", err)
75+
}
76+
want := &RepositoryReleaseNotes{
77+
Name: "v1.0.0",
78+
Body: "**Full Changelog**: https://github.com/o/r/compare/v0.9.0...v1.0.0",
79+
}
80+
if !cmp.Equal(releases, want) {
81+
t.Errorf("Repositories.GenerateReleaseNotes returned %+v, want %+v", releases, want)
82+
}
83+
84+
const methodName = "GenerateReleaseNotes"
85+
testBadOptions(t, methodName, func() (err error) {
86+
_, _, err = client.Repositories.GenerateReleaseNotes(ctx, "\n", "\n", opt)
87+
return err
88+
})
89+
90+
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
91+
got, resp, err := client.Repositories.GenerateReleaseNotes(ctx, "o", "r", opt)
92+
if got != nil {
93+
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
94+
}
95+
return resp, err
96+
})
97+
}
98+
5899
func TestRepositoriesService_GetRelease(t *testing.T) {
59100
client, mux, _, teardown := setup()
60101
defer teardown()
@@ -167,6 +208,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) {
167208
input := &RepositoryRelease{
168209
Name: String("v1.0"),
169210
DiscussionCategoryName: String("General"),
211+
GenerateReleaseNotes: Bool(true),
170212
// Fields to be removed:
171213
ID: Int64(2),
172214
CreatedAt: &Timestamp{referenceTime},
@@ -190,6 +232,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) {
190232
want := &repositoryReleaseRequest{
191233
Name: String("v1.0"),
192234
DiscussionCategoryName: String("General"),
235+
GenerateReleaseNotes: Bool(true),
193236
}
194237
if !cmp.Equal(v, want) {
195238
t.Errorf("Request body = %+v, want %+v", v, want)
@@ -230,6 +273,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) {
230273
input := &RepositoryRelease{
231274
Name: String("n"),
232275
DiscussionCategoryName: String("General"),
276+
GenerateReleaseNotes: Bool(true),
233277
// Fields to be removed:
234278
ID: Int64(2),
235279
CreatedAt: &Timestamp{referenceTime},
@@ -253,6 +297,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) {
253297
want := &repositoryReleaseRequest{
254298
Name: String("n"),
255299
DiscussionCategoryName: String("General"),
300+
GenerateReleaseNotes: Bool(true),
256301
}
257302
if !cmp.Equal(v, want) {
258303
t.Errorf("Request body = %+v, want %+v", v, want)

0 commit comments

Comments
 (0)