Skip to content

Commit 436e1fd

Browse files
authored
feat!: Widen CustomProperties type to map[string]interface{} to align with GitHub API (#3230)
Fixes: #3229. BREAKING CHANGE: PushEventRepository.CustomProperties is changed from map[string]string to map[string]interface{}.
1 parent 474a48f commit 436e1fd

File tree

6 files changed

+139
-127
lines changed

6 files changed

+139
-127
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ Steve Teuber <[email protected]>
431431
Stian Eikeland <[email protected]>
432432
Suhaib Mujahid <[email protected]>
433433
sushmita wable <[email protected]>
434+
Sven Palberg <[email protected]>
434435
Szymon Kodrebski <[email protected]>
435436
Søren Hansen <[email protected]>
436437
T.J. Corrigan <[email protected]>

github/event_types.go

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,44 +1348,44 @@ func (h HeadCommit) String() string {
13481348

13491349
// PushEventRepository represents the repo object in a PushEvent payload.
13501350
type PushEventRepository struct {
1351-
ID *int64 `json:"id,omitempty"`
1352-
NodeID *string `json:"node_id,omitempty"`
1353-
Name *string `json:"name,omitempty"`
1354-
FullName *string `json:"full_name,omitempty"`
1355-
Owner *User `json:"owner,omitempty"`
1356-
Private *bool `json:"private,omitempty"`
1357-
Description *string `json:"description,omitempty"`
1358-
Fork *bool `json:"fork,omitempty"`
1359-
CreatedAt *Timestamp `json:"created_at,omitempty"`
1360-
PushedAt *Timestamp `json:"pushed_at,omitempty"`
1361-
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
1362-
Homepage *string `json:"homepage,omitempty"`
1363-
PullsURL *string `json:"pulls_url,omitempty"`
1364-
Size *int `json:"size,omitempty"`
1365-
StargazersCount *int `json:"stargazers_count,omitempty"`
1366-
WatchersCount *int `json:"watchers_count,omitempty"`
1367-
Language *string `json:"language,omitempty"`
1368-
HasIssues *bool `json:"has_issues,omitempty"`
1369-
HasDownloads *bool `json:"has_downloads,omitempty"`
1370-
HasWiki *bool `json:"has_wiki,omitempty"`
1371-
HasPages *bool `json:"has_pages,omitempty"`
1372-
ForksCount *int `json:"forks_count,omitempty"`
1373-
Archived *bool `json:"archived,omitempty"`
1374-
Disabled *bool `json:"disabled,omitempty"`
1375-
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
1376-
DefaultBranch *string `json:"default_branch,omitempty"`
1377-
MasterBranch *string `json:"master_branch,omitempty"`
1378-
Organization *string `json:"organization,omitempty"`
1379-
URL *string `json:"url,omitempty"`
1380-
ArchiveURL *string `json:"archive_url,omitempty"`
1381-
HTMLURL *string `json:"html_url,omitempty"`
1382-
StatusesURL *string `json:"statuses_url,omitempty"`
1383-
GitURL *string `json:"git_url,omitempty"`
1384-
SSHURL *string `json:"ssh_url,omitempty"`
1385-
CloneURL *string `json:"clone_url,omitempty"`
1386-
SVNURL *string `json:"svn_url,omitempty"`
1387-
Topics []string `json:"topics,omitempty"`
1388-
CustomProperties map[string]string `json:"custom_properties,omitempty"`
1351+
ID *int64 `json:"id,omitempty"`
1352+
NodeID *string `json:"node_id,omitempty"`
1353+
Name *string `json:"name,omitempty"`
1354+
FullName *string `json:"full_name,omitempty"`
1355+
Owner *User `json:"owner,omitempty"`
1356+
Private *bool `json:"private,omitempty"`
1357+
Description *string `json:"description,omitempty"`
1358+
Fork *bool `json:"fork,omitempty"`
1359+
CreatedAt *Timestamp `json:"created_at,omitempty"`
1360+
PushedAt *Timestamp `json:"pushed_at,omitempty"`
1361+
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
1362+
Homepage *string `json:"homepage,omitempty"`
1363+
PullsURL *string `json:"pulls_url,omitempty"`
1364+
Size *int `json:"size,omitempty"`
1365+
StargazersCount *int `json:"stargazers_count,omitempty"`
1366+
WatchersCount *int `json:"watchers_count,omitempty"`
1367+
Language *string `json:"language,omitempty"`
1368+
HasIssues *bool `json:"has_issues,omitempty"`
1369+
HasDownloads *bool `json:"has_downloads,omitempty"`
1370+
HasWiki *bool `json:"has_wiki,omitempty"`
1371+
HasPages *bool `json:"has_pages,omitempty"`
1372+
ForksCount *int `json:"forks_count,omitempty"`
1373+
Archived *bool `json:"archived,omitempty"`
1374+
Disabled *bool `json:"disabled,omitempty"`
1375+
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
1376+
DefaultBranch *string `json:"default_branch,omitempty"`
1377+
MasterBranch *string `json:"master_branch,omitempty"`
1378+
Organization *string `json:"organization,omitempty"`
1379+
URL *string `json:"url,omitempty"`
1380+
ArchiveURL *string `json:"archive_url,omitempty"`
1381+
HTMLURL *string `json:"html_url,omitempty"`
1382+
StatusesURL *string `json:"statuses_url,omitempty"`
1383+
GitURL *string `json:"git_url,omitempty"`
1384+
SSHURL *string `json:"ssh_url,omitempty"`
1385+
CloneURL *string `json:"clone_url,omitempty"`
1386+
SVNURL *string `json:"svn_url,omitempty"`
1387+
Topics []string `json:"topics,omitempty"`
1388+
CustomProperties map[string]interface{} `json:"custom_properties,omitempty"`
13891389
}
13901390

13911391
// PushEventRepoOwner is a basic representation of user/org in a PushEvent payload.

github/github-accessors.go

Lines changed: 0 additions & 16 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: 0 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/repos.go

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -27,59 +27,59 @@ type RepositoriesService service
2727

2828
// Repository represents a GitHub repository.
2929
type Repository struct {
30-
ID *int64 `json:"id,omitempty"`
31-
NodeID *string `json:"node_id,omitempty"`
32-
Owner *User `json:"owner,omitempty"`
33-
Name *string `json:"name,omitempty"`
34-
FullName *string `json:"full_name,omitempty"`
35-
Description *string `json:"description,omitempty"`
36-
Homepage *string `json:"homepage,omitempty"`
37-
CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"`
38-
DefaultBranch *string `json:"default_branch,omitempty"`
39-
MasterBranch *string `json:"master_branch,omitempty"`
40-
CreatedAt *Timestamp `json:"created_at,omitempty"`
41-
PushedAt *Timestamp `json:"pushed_at,omitempty"`
42-
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
43-
HTMLURL *string `json:"html_url,omitempty"`
44-
CloneURL *string `json:"clone_url,omitempty"`
45-
GitURL *string `json:"git_url,omitempty"`
46-
MirrorURL *string `json:"mirror_url,omitempty"`
47-
SSHURL *string `json:"ssh_url,omitempty"`
48-
SVNURL *string `json:"svn_url,omitempty"`
49-
Language *string `json:"language,omitempty"`
50-
Fork *bool `json:"fork,omitempty"`
51-
ForksCount *int `json:"forks_count,omitempty"`
52-
NetworkCount *int `json:"network_count,omitempty"`
53-
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
54-
OpenIssues *int `json:"open_issues,omitempty"` // Deprecated: Replaced by OpenIssuesCount. For backward compatibility OpenIssues is still populated.
55-
StargazersCount *int `json:"stargazers_count,omitempty"`
56-
SubscribersCount *int `json:"subscribers_count,omitempty"`
57-
WatchersCount *int `json:"watchers_count,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility WatchersCount is still populated.
58-
Watchers *int `json:"watchers,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility Watchers is still populated.
59-
Size *int `json:"size,omitempty"`
60-
AutoInit *bool `json:"auto_init,omitempty"`
61-
Parent *Repository `json:"parent,omitempty"`
62-
Source *Repository `json:"source,omitempty"`
63-
TemplateRepository *Repository `json:"template_repository,omitempty"`
64-
Organization *Organization `json:"organization,omitempty"`
65-
Permissions map[string]bool `json:"permissions,omitempty"`
66-
AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
67-
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
68-
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
69-
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
70-
AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"`
71-
AllowForking *bool `json:"allow_forking,omitempty"`
72-
WebCommitSignoffRequired *bool `json:"web_commit_signoff_required,omitempty"`
73-
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
74-
UseSquashPRTitleAsDefault *bool `json:"use_squash_pr_title_as_default,omitempty"`
75-
SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "COMMIT_OR_PR_TITLE"
76-
SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "COMMIT_MESSAGES", "BLANK"
77-
MergeCommitTitle *string `json:"merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "MERGE_MESSAGE"
78-
MergeCommitMessage *string `json:"merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "PR_TITLE", "BLANK"
79-
Topics []string `json:"topics,omitempty"`
80-
CustomProperties map[string]string `json:"custom_properties,omitempty"`
81-
Archived *bool `json:"archived,omitempty"`
82-
Disabled *bool `json:"disabled,omitempty"`
30+
ID *int64 `json:"id,omitempty"`
31+
NodeID *string `json:"node_id,omitempty"`
32+
Owner *User `json:"owner,omitempty"`
33+
Name *string `json:"name,omitempty"`
34+
FullName *string `json:"full_name,omitempty"`
35+
Description *string `json:"description,omitempty"`
36+
Homepage *string `json:"homepage,omitempty"`
37+
CodeOfConduct *CodeOfConduct `json:"code_of_conduct,omitempty"`
38+
DefaultBranch *string `json:"default_branch,omitempty"`
39+
MasterBranch *string `json:"master_branch,omitempty"`
40+
CreatedAt *Timestamp `json:"created_at,omitempty"`
41+
PushedAt *Timestamp `json:"pushed_at,omitempty"`
42+
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
43+
HTMLURL *string `json:"html_url,omitempty"`
44+
CloneURL *string `json:"clone_url,omitempty"`
45+
GitURL *string `json:"git_url,omitempty"`
46+
MirrorURL *string `json:"mirror_url,omitempty"`
47+
SSHURL *string `json:"ssh_url,omitempty"`
48+
SVNURL *string `json:"svn_url,omitempty"`
49+
Language *string `json:"language,omitempty"`
50+
Fork *bool `json:"fork,omitempty"`
51+
ForksCount *int `json:"forks_count,omitempty"`
52+
NetworkCount *int `json:"network_count,omitempty"`
53+
OpenIssuesCount *int `json:"open_issues_count,omitempty"`
54+
OpenIssues *int `json:"open_issues,omitempty"` // Deprecated: Replaced by OpenIssuesCount. For backward compatibility OpenIssues is still populated.
55+
StargazersCount *int `json:"stargazers_count,omitempty"`
56+
SubscribersCount *int `json:"subscribers_count,omitempty"`
57+
WatchersCount *int `json:"watchers_count,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility WatchersCount is still populated.
58+
Watchers *int `json:"watchers,omitempty"` // Deprecated: Replaced by StargazersCount. For backward compatibility Watchers is still populated.
59+
Size *int `json:"size,omitempty"`
60+
AutoInit *bool `json:"auto_init,omitempty"`
61+
Parent *Repository `json:"parent,omitempty"`
62+
Source *Repository `json:"source,omitempty"`
63+
TemplateRepository *Repository `json:"template_repository,omitempty"`
64+
Organization *Organization `json:"organization,omitempty"`
65+
Permissions map[string]bool `json:"permissions,omitempty"`
66+
AllowRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
67+
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
68+
AllowSquashMerge *bool `json:"allow_squash_merge,omitempty"`
69+
AllowMergeCommit *bool `json:"allow_merge_commit,omitempty"`
70+
AllowAutoMerge *bool `json:"allow_auto_merge,omitempty"`
71+
AllowForking *bool `json:"allow_forking,omitempty"`
72+
WebCommitSignoffRequired *bool `json:"web_commit_signoff_required,omitempty"`
73+
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
74+
UseSquashPRTitleAsDefault *bool `json:"use_squash_pr_title_as_default,omitempty"`
75+
SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "COMMIT_OR_PR_TITLE"
76+
SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "COMMIT_MESSAGES", "BLANK"
77+
MergeCommitTitle *string `json:"merge_commit_title,omitempty"` // Can be one of: "PR_TITLE", "MERGE_MESSAGE"
78+
MergeCommitMessage *string `json:"merge_commit_message,omitempty"` // Can be one of: "PR_BODY", "PR_TITLE", "BLANK"
79+
Topics []string `json:"topics,omitempty"`
80+
CustomProperties map[string]interface{} `json:"custom_properties,omitempty"`
81+
Archived *bool `json:"archived,omitempty"`
82+
Disabled *bool `json:"disabled,omitempty"`
8383

8484
// Only provided when using RepositoriesService.Get while in preview
8585
License *License `json:"license,omitempty"`

github/repos_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"net/url"
1515
"strings"
1616
"testing"
17+
"time"
1718

1819
"github.com/google/go-cmp/cmp"
1920
)
@@ -4463,3 +4464,49 @@ func TestRepositoriesService_IsPrivateReportingEnabled(t *testing.T) {
44634464
return resp, err
44644465
})
44654466
}
4467+
4468+
func TestRepository_UnmarshalJSON(t *testing.T) {
4469+
var testCases = map[string]struct {
4470+
data []byte
4471+
wantRepository Repository
4472+
wantErr bool
4473+
}{
4474+
"Empty": {
4475+
data: []byte("{}"),
4476+
wantRepository: Repository{},
4477+
wantErr: false,
4478+
},
4479+
"Invalid JSON": {
4480+
data: []byte("{"),
4481+
wantRepository: Repository{},
4482+
wantErr: true,
4483+
},
4484+
"Partial project": {
4485+
data: []byte(`{"id":10270722,"name":"go-github","private":false,"owner":{"login":"google"},"created_at":"2013-05-24T16:42:58Z","license":{},"topics":["github"],"permissions":{"pull":true},"custom_properties":{},"organization":{"login":"google"}}`),
4486+
wantRepository: Repository{ID: Int64(10270722), Name: String("go-github"), Private: Bool(false), Owner: &User{Login: String("google")}, CreatedAt: &Timestamp{time.Date(2013, 5, 24, 16, 42, 58, 0, time.UTC)}, License: &License{}, Topics: []string{"github"}, Permissions: map[string]bool{"pull": true}, CustomProperties: map[string]interface{}{}, Organization: &Organization{Login: String("google")}},
4487+
wantErr: false,
4488+
},
4489+
"With custom properties": {
4490+
data: []byte(`{"custom_properties":{"boolean":"false","text":"a","single-select":"a","multi-select":["a","b","c"]}}`),
4491+
wantRepository: Repository{CustomProperties: map[string]interface{}{"boolean": "false", "text": "a", "single-select": "a", "multi-select": []interface{}{"a", "b", "c"}}},
4492+
wantErr: false,
4493+
},
4494+
}
4495+
4496+
for name, tt := range testCases {
4497+
tt := tt
4498+
t.Run(name, func(t *testing.T) {
4499+
pk := Repository{}
4500+
err := json.Unmarshal(tt.data, &pk)
4501+
if err == nil && tt.wantErr {
4502+
t.Errorf("Repository.UnmarshalJSON returned nil instead of an error")
4503+
}
4504+
if err != nil && !tt.wantErr {
4505+
t.Errorf("Repository.UnmarshalJSON returned an unexpected error: %+v", err)
4506+
}
4507+
if !cmp.Equal(tt.wantRepository, pk) {
4508+
t.Errorf("Repository.UnmarshalJSON expected repository %+v, got %+v", tt.wantRepository, pk)
4509+
}
4510+
})
4511+
}
4512+
}

0 commit comments

Comments
 (0)