Repository: google/go-github
Pull request #2119 (2021-10-06 19:44:18)

Add RenameBranch support
Add support for rename a branch: https://docs.github.com/en/rest/reference/repos#rename-a-branch
Fixes: https://github.com/google/go-github/issues/2118

google-cla[bot]: 
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

:memo: **Please visit <https://cla.developers.google.com/> to sign.**

Once you've signed (or fixed any issues), please reply here with `@googlebot I signed it!` and we'll verify it.

----

#### What to do if you already signed the CLA

##### Individual signers

*   It's possible we don't have your GitHub username or you're using a different email address on your commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).

##### Corporate signers

*   Your company has a Point of Contact who decides which employees are authorized to participate. Ask your POC to be added to the group of authorized contributors. If you don't know who your Point of Contact is, direct the Google project maintainer to [go/cla#troubleshoot](http://go/cla#troubleshoot) ([Public version](https://opensource.google/docs/cla/#troubleshoot)).
*   The email used to register you as an authorized contributor must be the email used for the Git commit. Check [your existing CLA data](https://cla.developers.google.com/clas) and verify that your [email is set on your git commits](https://help.github.com/articles/setting-your-email-in-git/).
*   The email used to register you as an authorized contributor must also be [attached to your GitHub account](https://github.com/settings/emails).
		

ℹ️ **Googlers: [Go here](https://goto.google.com/prinfo/https%3A%2F%2Fgithub.com%2Fgoogle%2Fgo-github%2Fpull%2F2119) for more info**.

<!-- need_sender_cla -->
codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#2119](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (50d7fb2) into [master](https://codecov.io/gh/google/go-github/commit/f6640949b0de67474e3987b3e014b2e818386c52?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (f664094) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/2119/graphs/tree.svg?width=650&height=150&src=pr&token=EgYjGjZlI0&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google)](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google)

```diff
@@           Coverage Diff           @@
##           master    #2119   +/-   ##
=======================================
  Coverage   97.78%   97.78%           
=======================================
  Files         112      112           
  Lines        9956     9968   +12     
=======================================
+ Hits         9735     9747   +12     
  Misses        154      154           
  Partials       67       67           
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Coverage Δ | |
|---|---|---|
| [github/repos.go](https://codecov.io/gh/google/go-github/pull/2119/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL3JlcG9zLmdv) | `98.67% <100.00%> (+0.02%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google). Last update [f664094...50d7fb2](https://codecov.io/gh/google/go-github/pull/2119?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).


Patch:
diff --git a/github/actions_artifacts.go b/github/actions_artifacts.go
index 016ce7a1..4aa7dc44 100644
--- a/github/actions_artifacts.go
+++ b/github/actions_artifacts.go
@@ -16,7 +16,7 @@ import (
 // data between jobs in a workflow and provide storage for data
 // once a workflow is complete.
 //
-// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/artifacts/
+// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/#artifacts
 type Artifact struct {
 	ID                 *int64     `json:"id,omitempty"`
 	NodeID             *string    `json:"node_id,omitempty"`
@@ -30,7 +30,7 @@ type Artifact struct {
 
 // ArtifactList represents a list of GitHub artifacts.
 //
-// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/artifacts/
+// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/#artifacts
 type ArtifactList struct {
 	TotalCount *int64      `json:"total_count,omitempty"`
 	Artifacts  []*Artifact `json:"artifacts,omitempty"`
@@ -106,7 +106,7 @@ func (s *ActionsService) GetArtifact(ctx context.Context, owner, repo string, ar
 
 // DownloadArtifact gets a redirect URL to download an archive for a repository.
 //
-// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/artifacts/#download-an-artifact
+// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/actions/#download-an-artifact
 func (s *ActionsService) DownloadArtifact(ctx context.Context, owner, repo string, artifactID int64, followRedirects bool) (*url.URL, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/actions/artifacts/%v/zip", owner, repo, artifactID)
 
diff --git a/github/actions_workflow_jobs.go b/github/actions_workflow_jobs.go
index 86921bae..66b8ff6e 100644
--- a/github/actions_workflow_jobs.go
+++ b/github/actions_workflow_jobs.go
@@ -39,7 +39,11 @@ type WorkflowJob struct {
 	Steps       []*TaskStep `json:"steps,omitempty"`
 	CheckRunURL *string     `json:"check_run_url,omitempty"`
 	// Labels represents runner labels from the `runs-on:` key from a GitHub Actions workflow.
-	Labels []string `json:"labels,omitempty"`
+	Labels          []string `json:"labels,omitempty"`
+	RunnerID        *int64   `json:"runner_id,omitempty"`
+	RunnerName      *string  `json:"runner_name,omitempty"`
+	RunnerGroupID   *int64   `json:"runner_group_id,omitempty"`
+	RunnerGroupName *string  `json:"runner_group_name,omitempty"`
 }
 
 // Jobs represents a slice of repository action workflow job.
diff --git a/github/apps.go b/github/apps.go
index 8b850d9e..3823a121 100644
--- a/github/apps.go
+++ b/github/apps.go
@@ -47,6 +47,10 @@ type InstallationTokenOptions struct {
 	// Providing repository IDs restricts the access of an installation token to specific repositories.
 	RepositoryIDs []int64 `json:"repository_ids,omitempty"`
 
+	// The names of the repositories that the installation token can access.
+	// Providing repository names restricts the access of an installation token to specific repositories.
+	Repositories []string `json:"repositories,omitempty"`
+
 	// The permissions granted to the access token.
 	// The permissions object includes the permission names and their access type.
 	Permissions *InstallationPermissions `json:"permissions,omitempty"`
diff --git a/github/github-accessors.go b/github/github-accessors.go
index dc48328b..1d2db4ec 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -148,6 +148,14 @@ func (a *AdminStats) GetUsers() *UserStats {
 	return a.Users
 }
 
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (a *AdvancedSecurity) GetStatus() string {
+	if a == nil || a.Status == nil {
+		return ""
+	}
+	return *a.Status
+}
+
 // GetClosedAt returns the ClosedAt field if it's non-nil, zero value otherwise.
 func (a *Alert) GetClosedAt() Timestamp {
 	if a == nil || a.ClosedAt == nil {
@@ -869,9 +877,9 @@ func (a *AuditEntry) GetRepositoryPublic() bool {
 }
 
 // GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise.
-func (a *AuditEntry) GetRunnerGroupID() string {
+func (a *AuditEntry) GetRunnerGroupID() int64 {
 	if a == nil || a.RunnerGroupID == nil {
-		return ""
+		return 0
 	}
 	return *a.RunnerGroupID
 }
@@ -885,9 +893,9 @@ func (a *AuditEntry) GetRunnerGroupName() string {
 }
 
 // GetRunnerID returns the RunnerID field if it's non-nil, zero value otherwise.
-func (a *AuditEntry) GetRunnerID() string {
+func (a *AuditEntry) GetRunnerID() int64 {
 	if a == nil || a.RunnerID == nil {
-		return ""
+		return 0
 	}
 	return *a.RunnerID
 }
@@ -4516,6 +4524,22 @@ func (f *ForkEvent) GetSender() *User {
 	return f.Sender
 }
 
+// GetPreviousTagName returns the PreviousTagName field if it's non-nil, zero value otherwise.
+func (g *GenerateNotesOptions) GetPreviousTagName() string {
+	if g == nil || g.PreviousTagName == nil {
+		return ""
+	}
+	return *g.PreviousTagName
+}
+
+// GetTargetCommitish returns the TargetCommitish field if it's non-nil, zero value otherwise.
+func (g *GenerateNotesOptions) GetTargetCommitish() string {
+	if g == nil || g.TargetCommitish == nil {
+		return ""
+	}
+	return *g.TargetCommitish
+}
+
 // GetInclude returns the Include field if it's non-nil, zero value otherwise.
 func (g *GetAuditLogOptions) GetInclude() string {
 	if g == nil || g.Include == nil {
@@ -13660,6 +13684,14 @@ func (r *Repository) GetReleasesURL() string {
 	return *r.ReleasesURL
 }
 
+// GetSecurityAndAnalysis returns the SecurityAndAnalysis field.
+func (r *Repository) GetSecurityAndAnalysis() *SecurityAndAnalysis {
+	if r == nil {
+		return nil
+	}
+	return r.SecurityAndAnalysis
+}
+
 // GetSize returns the Size field if it's non-nil, zero value otherwise.
 func (r *Repository) GetSize() int {
 	if r == nil || r.Size == nil {
@@ -14460,6 +14492,14 @@ func (r *RepositoryRelease) GetDraft() bool {
 	return *r.Draft
 }
 
+// GetGenerateReleaseNotes returns the GenerateReleaseNotes field if it's non-nil, zero value otherwise.
+func (r *RepositoryRelease) GetGenerateReleaseNotes() bool {
+	if r == nil || r.GenerateReleaseNotes == nil {
+		return false
+	}
+	return *r.GenerateReleaseNotes
+}
+
 // GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
 func (r *RepositoryRelease) GetHTMLURL() string {
 	if r == nil || r.HTMLURL == nil {
@@ -15156,6 +15196,30 @@ func (s *SCIMUserName) GetFormatted() string {
 	return *s.Formatted
 }
 
+// GetStatus returns the Status field if it's non-nil, zero value otherwise.
+func (s *SecretScanning) GetStatus() string {
+	if s == nil || s.Status == nil {
+		return ""
+	}
+	return *s.Status
+}
+
+// GetAdvancedSecurity returns the AdvancedSecurity field.
+func (s *SecurityAndAnalysis) GetAdvancedSecurity() *AdvancedSecurity {
+	if s == nil {
+		return nil
+	}
+	return s.AdvancedSecurity
+}
+
+// GetSecretScanning returns the SecretScanning field.
+func (s *SecurityAndAnalysis) GetSecretScanning() *SecretScanning {
+	if s == nil {
+		return nil
+	}
+	return s.SecretScanning
+}
+
 // GetTotalCount returns the TotalCount field if it's non-nil, zero value otherwise.
 func (s *SelectedReposList) GetTotalCount() int {
 	if s == nil || s.TotalCount == nil {
@@ -18044,6 +18108,38 @@ func (w *WorkflowJob) GetRunID() int64 {
 	return *w.RunID
 }
 
+// GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise.
+func (w *WorkflowJob) GetRunnerGroupID() int64 {
+	if w == nil || w.RunnerGroupID == nil {
+		return 0
+	}
+	return *w.RunnerGroupID
+}
+
+// GetRunnerGroupName returns the RunnerGroupName field if it's non-nil, zero value otherwise.
+func (w *WorkflowJob) GetRunnerGroupName() string {
+	if w == nil || w.RunnerGroupName == nil {
+		return ""
+	}
+	return *w.RunnerGroupName
+}
+
+// GetRunnerID returns the RunnerID field if it's non-nil, zero value otherwise.
+func (w *WorkflowJob) GetRunnerID() int64 {
+	if w == nil || w.RunnerID == nil {
+		return 0
+	}
+	return *w.RunnerID
+}
+
+// GetRunnerName returns the RunnerName field if it's non-nil, zero value otherwise.
+func (w *WorkflowJob) GetRunnerName() string {
+	if w == nil || w.RunnerName == nil {
+		return ""
+	}
+	return *w.RunnerName
+}
+
 // GetRunURL returns the RunURL field if it's non-nil, zero value otherwise.
 func (w *WorkflowJob) GetRunURL() string {
 	if w == nil || w.RunURL == nil {
diff --git a/github/github.go b/github/github.go
index d4d7a54a..02cdabd5 100644
--- a/github/github.go
+++ b/github/github.go
@@ -48,6 +48,21 @@ const (
 	mediaTypeIssueImportAPI    = "application/vnd.github.golden-comet-preview+json"
 
 	// Media Type values to access preview APIs
+	// These media types will be added to the API request as headers
+	// and used to enable particular features on GitHub API that are still in preview.
+	// After some time, specific media types will be promoted (to a "stable" state).
+	// From then on, the preview headers are not required anymore to activate the additional
+	// feature on GitHub.com's API. However, this API header might still be needed for users
+	// to run a GitHub Enterprise Server on-premise.
+	// It's not uncommon for GitHub Enterprise Server customers to run older versions which
+	// would probably rely on the preview headers for some time.
+	// While the header promotion is going out for GitHub.com, it may be some time before it
+	// even arrives in GitHub Enterprise Server.
+	// We keep those preview headers around to avoid breaking older GitHub Enterprise Server
+	// versions. Additionally, non-functional (preview) headers don't create any side effects
+	// on GitHub Cloud version.
+	//
+	// See https://github.com/google/go-github/pull/2125 for full context.
 
 	// https://developer.github.com/changes/2014-12-09-new-attributes-for-stars-api/
 	mediaTypeStarringPreview = "application/vnd.github.v3.star+json"
diff --git a/github/issues.go b/github/issues.go
index 46aff295..f35f2b56 100644
--- a/github/issues.go
+++ b/github/issues.go
@@ -299,6 +299,29 @@ func (s *IssuesService) Edit(ctx context.Context, owner string, repo string, num
 	return i, resp, nil
 }
 
+// Remove a milestone from an issue.
+//
+// This is a helper method to explicitly update an issue with a `null` milestone, thereby removing it.
+//
+// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/issues/#update-an-issue
+func (s *IssuesService) RemoveMilestone(ctx context.Context, owner, repo string, issueNumber int) (*Issue, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/issues/%v", owner, repo, issueNumber)
+	req, err := s.client.NewRequest("PATCH", u, &struct {
+		Milestone *Milestone `json:"milestone"`
+	}{})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	i := new(Issue)
+	resp, err := s.client.Do(ctx, req, i)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return i, resp, nil
+}
+
 // LockIssueOptions specifies the optional parameters to the
 // IssuesService.Lock method.
 type LockIssueOptions struct {
diff --git a/github/orgs_audit_log.go b/github/orgs_audit_log.go
index 4b98ba69..ade57f54 100644
--- a/github/orgs_audit_log.go
+++ b/github/orgs_audit_log.go
@@ -12,9 +12,9 @@ import (
 
 // GetAuditLogOptions sets up optional parameters to query audit-log endpoint.
 type GetAuditLogOptions struct {
-	Phrase  *string `json:"phrase,omitempty"`  // A search phrase. (Optional.)
-	Include *string `json:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.)
-	Order   *string `json:"order,omitempty"`   // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.)
+	Phrase  *string `url:"phrase,omitempty"`  // A search phrase. (Optional.)
+	Include *string `url:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.)
+	Order   *string `url:"order,omitempty"`   // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.)
 
 	ListCursorOptions
 }
@@ -70,9 +70,9 @@ type AuditEntry struct {
 	Repo                  *string     `json:"repo,omitempty"`
 	Repository            *string     `json:"repository,omitempty"`
 	RepositoryPublic      *bool       `json:"repository_public,omitempty"`
-	RunnerGroupID         *string     `json:"runner_group_id,omitempty"`
+	RunnerGroupID         *int64      `json:"runner_group_id,omitempty"`
 	RunnerGroupName       *string     `json:"runner_group_name,omitempty"`
-	RunnerID              *string     `json:"runner_id,omitempty"`
+	RunnerID              *int64      `json:"runner_id,omitempty"`
 	RunnerLabels          []string    `json:"runner_labels,omitempty"`
 	RunnerName            *string     `json:"runner_name,omitempty"`
 	SecretsPassed         []string    `json:"secrets_passed,omitempty"`
diff --git a/github/repos.go b/github/repos.go
index f6236b43..45c46180 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -80,6 +80,9 @@ type Repository struct {
 	LicenseTemplate   *string `json:"license_template,omitempty"`
 	GitignoreTemplate *string `json:"gitignore_template,omitempty"`
 
+	// Options for configuring Advanced Security and Secret Scanning
+	SecurityAndAnalysis *SecurityAndAnalysis `json:"security_and_analysis,omitempty"`
+
 	// Creating an organization repository. Required for non-owners.
 	TeamID *int64 `json:"team_id,omitempty"`
 
@@ -183,6 +186,39 @@ type RepositoryListOptions struct {
 	ListOptions
 }
 
+// SecurityAndAnalysis specifies the optional advanced security features
+// that are enabled on a given repository.
+type SecurityAndAnalysis struct {
+	AdvancedSecurity *AdvancedSecurity `json:"advanced_security,omitempty"`
+	SecretScanning   *SecretScanning   `json:"secret_scanning,omitempty"`
+}
+
+func (s SecurityAndAnalysis) String() string {
+	return Stringify(s)
+}
+
+// AdvancedSecurity specifies the state of advanced security on a repository.
+//
+// GitHub API docs: https://docs.github.com/en/github/getting-started-with-github/learning-about-github/about-github-advanced-security
+type AdvancedSecurity struct {
+	Status *string `json:"status,omitempty"`
+}
+
+func (a AdvancedSecurity) String() string {
+	return Stringify(a)
+}
+
+// SecretScanning specifies the state of secret scanning on a repository.
+//
+// GitHub API docs: https://docs.github.com/en/code-security/secret-security/about-secret-scanning
+type SecretScanning struct {
+	Status *string `json:"status,omitempty"`
+}
+
+func (s SecretScanning) String() string {
+	return Stringify(s)
+}
+
 // List the repositories for a user. Passing the empty string will list
 // repositories for the authenticated user.
 //
@@ -1037,6 +1073,34 @@ func (s *RepositoriesService) getBranchFromURL(ctx context.Context, u string, fo
 	return resp, err
 }
 
+// renameBranchRequest represents a request to rename a branch.
+type renameBranchRequest struct {
+	NewName string `json:"new_name"`
+}
+
+// RenameBranch renames a branch in a repository.
+//
+// To rename a non-default branch: Users must have push access. GitHub Apps must have the `contents:write` repository permission.
+// To rename the default branch: Users must have admin or owner permissions. GitHub Apps must have the `administration:write` repository permission.
+//
+// GitHub API docs: https://docs.github.com/en/rest/reference/repos#rename-a-branch
+func (s *RepositoriesService) RenameBranch(ctx context.Context, owner, repo, branch, newName string) (*Branch, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/branches/%v/rename", owner, repo, branch)
+	r := &renameBranchRequest{NewName: newName}
+	req, err := s.client.NewRequest("POST", u, r)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	b := new(Branch)
+	resp, err := s.client.Do(ctx, req, b)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return b, resp, nil
+}
+
 // GetBranchProtection gets the protection of a given branch.
 //
 // GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/repos/#get-branch-protection
diff --git a/github/repos_releases.go b/github/repos_releases.go
index f7b03f2e..1cd2fae6 100644
--- a/github/repos_releases.go
+++ b/github/repos_releases.go
@@ -26,6 +26,7 @@ type RepositoryRelease struct {
 	Draft                  *bool   `json:"draft,omitempty"`
 	Prerelease             *bool   `json:"prerelease,omitempty"`
 	DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
+	GenerateReleaseNotes   *bool   `json:"generate_release_notes,omitempty"`
 
 	// The following fields are not used in CreateRelease or EditRelease:
 	ID          *int64          `json:"id,omitempty"`
@@ -46,6 +47,19 @@ func (r RepositoryRelease) String() string {
 	return Stringify(r)
 }
 
+// RepositoryReleaseNotes represents a GitHub-generated release notes.
+type RepositoryReleaseNotes struct {
+	Name string `json:"name"`
+	Body string `json:"body"`
+}
+
+// GenerateNotesOptions represents the options to generate release notes.
+type GenerateNotesOptions struct {
+	TagName         string  `json:"tag_name"`
+	PreviousTagName *string `json:"previous_tag_name,omitempty"`
+	TargetCommitish *string `json:"target_commitish,omitempty"`
+}
+
 // ReleaseAsset represents a GitHub release asset in a repository.
 type ReleaseAsset struct {
 	ID                 *int64     `json:"id,omitempty"`
@@ -114,6 +128,25 @@ func (s *RepositoriesService) GetReleaseByTag(ctx context.Context, owner, repo,
 	return s.getSingleRelease(ctx, u)
 }
 
+// GenerateReleaseNotes generates the release notes for the given tag.
+// TODO: api docs
+// GitHub API docs:
+func (s *RepositoriesService) GenerateReleaseNotes(ctx context.Context, owner, repo string, opts *GenerateNotesOptions) (*RepositoryReleaseNotes, *Response, error) {
+	u := fmt.Sprintf("repos/%s/%s/releases/generate-notes", owner, repo)
+	req, err := s.client.NewRequest("POST", u, opts)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	r := new(RepositoryReleaseNotes)
+	resp, err := s.client.Do(ctx, req, r)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return r, resp, nil
+}
+
 func (s *RepositoriesService) getSingleRelease(ctx context.Context, url string) (*RepositoryRelease, *Response, error) {
 	req, err := s.client.NewRequest("GET", url, nil)
 	if err != nil {
@@ -141,6 +174,7 @@ type repositoryReleaseRequest struct {
 	Body                   *string `json:"body,omitempty"`
 	Draft                  *bool   `json:"draft,omitempty"`
 	Prerelease             *bool   `json:"prerelease,omitempty"`
+	GenerateReleaseNotes   *bool   `json:"generate_release_notes,omitempty"`
 	DiscussionCategoryName *string `json:"discussion_category_name,omitempty"`
 }
 
@@ -161,6 +195,7 @@ func (s *RepositoriesService) CreateRelease(ctx context.Context, owner, repo str
 		Draft:                  release.Draft,
 		Prerelease:             release.Prerelease,
 		DiscussionCategoryName: release.DiscussionCategoryName,
+		GenerateReleaseNotes:   release.GenerateReleaseNotes,
 	}
 
 	req, err := s.client.NewRequest("POST", u, releaseReq)
@@ -193,6 +228,7 @@ func (s *RepositoriesService) EditRelease(ctx context.Context, owner, repo strin
 		Draft:                  release.Draft,
 		Prerelease:             release.Prerelease,
 		DiscussionCategoryName: release.DiscussionCategoryName,
+		GenerateReleaseNotes:   release.GenerateReleaseNotes,
 	}
 
 	req, err := s.client.NewRequest("PATCH", u, releaseReq)
diff --git a/github/users_packages.go b/github/users_packages.go
index d0684406..4308b16e 100644
--- a/github/users_packages.go
+++ b/github/users_packages.go
@@ -18,7 +18,7 @@ import (
 func (s *UsersService) ListPackages(ctx context.Context, user string, opts *PackageListOptions) ([]*Package, *Response, error) {
 	var u string
 	if user != "" {
-		u = fmt.Sprintf("user/%v/packages", user)
+		u = fmt.Sprintf("users/%v/packages", user)
 	} else {
 		u = "user/packages"
 	}
diff --git a/scrape/apps.go b/scrape/apps.go
index 9063bbc2..c9ba358b 100644
--- a/scrape/apps.go
+++ b/scrape/apps.go
@@ -17,7 +17,7 @@ import (
 	"strings"
 
 	"github.com/PuerkitoBio/goquery"
-	"github.com/google/go-github/v32/github"
+	"github.com/google/go-github/v39/github"
 )
 
 // AppRestrictionsEnabled returns whether the specified organization has
diff --git a/scrape/go.mod b/scrape/go.mod
index ee95c062..16e3e3df 100644
--- a/scrape/go.mod
+++ b/scrape/go.mod
@@ -3,9 +3,9 @@ module github.com/google/go-github/scrape
 go 1.13
 
 require (
-	github.com/PuerkitoBio/goquery v1.7.1
+	github.com/PuerkitoBio/goquery v1.8.0
 	github.com/google/go-cmp v0.5.6
-	github.com/google/go-github/v32 v32.1.0
+	github.com/google/go-github/v39 v39.2.0
 	github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
-	golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d
+	golang.org/x/net v0.0.0-20210916014120-12bc252f5db8
 )
diff --git a/scrape/go.sum b/scrape/go.sum
index f20e765a..c156c104 100644
--- a/scrape/go.sum
+++ b/scrape/go.sum
@@ -1,31 +1,36 @@
-github.com/PuerkitoBio/goquery v1.7.1 h1:oE+T06D+1T7LNrn91B4aERsRIeCLJ/oPSa6xB9FPnz4=
-github.com/PuerkitoBio/goquery v1.7.1/go.mod h1:XY0pP4kfraEmmV1O7Uf6XyjoslwsneBbgeDjLYuN8xY=
-github.com/andybalholm/cascadia v1.2.0 h1:vuRCkM5Ozh/BfmsaTm26kbjm0mIOM3yS5Ek/F5h18aE=
-github.com/andybalholm/cascadia v1.2.0/go.mod h1:YCyR8vOZT9aZ1CHEd8ap0gMVm2aFgxBp0T0eFw1RUQY=
+github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U=
+github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI=
+github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
+github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
-github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
-github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
-github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
+github.com/google/go-github/v39 v39.2.0 h1:rNNM311XtPOz5rDdsJXAp2o8F67X9FnROXTvto3aSnQ=
+github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
+github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
+github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
 github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4=
 github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
-golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
+golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210916014120-12bc252f5db8 h1:/6y1LfuqNuQdHAm0jjtPtgRcxIxjVZgm5OTu8/QhZvk=
+golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=


Test patch:
diff --git a/github/apps_test.go b/github/apps_test.go
index 5079d416..e003e278 100644
--- a/github/apps_test.go
+++ b/github/apps_test.go
@@ -387,6 +387,7 @@ func TestAppsService_CreateInstallationTokenWithOptions(t *testing.T) {
 
 	installationTokenOptions := &InstallationTokenOptions{
 		RepositoryIDs: []int64{1234},
+		Repositories:  []string{"foo"},
 		Permissions: &InstallationPermissions{
 			Contents: String("write"),
 			Issues:   String("read"),
diff --git a/github/code-scanning_test.go b/github/code-scanning_test.go
index 6ef8d84a..1b1033ee 100644
--- a/github/code-scanning_test.go
+++ b/github/code-scanning_test.go
@@ -413,6 +413,56 @@ func TestAlert_Marshal(t *testing.T) {
 	testJSONMarshal(t, u, want)
 }
 
+func TestLocation_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Location{}, "{}")
+
+	u := &Location{
+		Path:        String("path"),
+		StartLine:   Int(1),
+		EndLine:     Int(2),
+		StartColumn: Int(3),
+		EndColumn:   Int(4),
+	}
+
+	want := `{
+		"path": "path",
+		"start_line": 1,
+		"end_line": 2,
+		"start_column": 3,
+		"end_column": 4
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRule_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Rule{}, "{}")
+
+	u := &Rule{
+		ID:                    String("1"),
+		Severity:              String("3"),
+		Description:           String("description"),
+		Name:                  String("first"),
+		SecuritySeverityLevel: String("2"),
+		FullDescription:       String("summary"),
+		Tags:                  []string{"tag1", "tag2"},
+		Help:                  String("Help Text"),
+	}
+
+	want := `{
+		"id":                      "1",
+		"severity":                "3",
+		"description":             "description",
+		"name":                    "first",
+		"security_severity_level": "2",
+		"full_description":        "summary",
+		"tags":                    ["tag1", "tag2"],
+		"help":                    "Help Text"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestTool_Marshal(t *testing.T) {
 	testJSONMarshal(t, &Tool{}, "{}")
 
@@ -430,3 +480,17 @@ func TestTool_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestMessage_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Message{}, "{}")
+
+	u := &Message{
+		Text: String("text"),
+	}
+
+	want := `{
+		"text": "text"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 6a0a1398..f6af9991 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -153,6 +153,16 @@ func TestAdminStats_GetUsers(tt *testing.T) {
 	a.GetUsers()
 }
 
+func TestAdvancedSecurity_GetStatus(tt *testing.T) {
+	var zeroValue string
+	a := &AdvancedSecurity{Status: &zeroValue}
+	a.GetStatus()
+	a = &AdvancedSecurity{}
+	a.GetStatus()
+	a = nil
+	a.GetStatus()
+}
+
 func TestAlert_GetClosedAt(tt *testing.T) {
 	var zeroValue Timestamp
 	a := &Alert{ClosedAt: &zeroValue}
@@ -1024,7 +1034,7 @@ func TestAuditEntry_GetRepositoryPublic(tt *testing.T) {
 }
 
 func TestAuditEntry_GetRunnerGroupID(tt *testing.T) {
-	var zeroValue string
+	var zeroValue int64
 	a := &AuditEntry{RunnerGroupID: &zeroValue}
 	a.GetRunnerGroupID()
 	a = &AuditEntry{}
@@ -1044,7 +1054,7 @@ func TestAuditEntry_GetRunnerGroupName(tt *testing.T) {
 }
 
 func TestAuditEntry_GetRunnerID(tt *testing.T) {
-	var zeroValue string
+	var zeroValue int64
 	a := &AuditEntry{RunnerID: &zeroValue}
 	a.GetRunnerID()
 	a = &AuditEntry{}
@@ -5268,6 +5278,26 @@ func TestForkEvent_GetSender(tt *testing.T) {
 	f.GetSender()
 }
 
+func TestGenerateNotesOptions_GetPreviousTagName(tt *testing.T) {
+	var zeroValue string
+	g := &GenerateNotesOptions{PreviousTagName: &zeroValue}
+	g.GetPreviousTagName()
+	g = &GenerateNotesOptions{}
+	g.GetPreviousTagName()
+	g = nil
+	g.GetPreviousTagName()
+}
+
+func TestGenerateNotesOptions_GetTargetCommitish(tt *testing.T) {
+	var zeroValue string
+	g := &GenerateNotesOptions{TargetCommitish: &zeroValue}
+	g.GetTargetCommitish()
+	g = &GenerateNotesOptions{}
+	g.GetTargetCommitish()
+	g = nil
+	g.GetTargetCommitish()
+}
+
 func TestGetAuditLogOptions_GetInclude(tt *testing.T) {
 	var zeroValue string
 	g := &GetAuditLogOptions{Include: &zeroValue}
@@ -15945,6 +15975,13 @@ func TestRepository_GetReleasesURL(tt *testing.T) {
 	r.GetReleasesURL()
 }
 
+func TestRepository_GetSecurityAndAnalysis(tt *testing.T) {
+	r := &Repository{}
+	r.GetSecurityAndAnalysis()
+	r = nil
+	r.GetSecurityAndAnalysis()
+}
+
 func TestRepository_GetSize(tt *testing.T) {
 	var zeroValue int
 	r := &Repository{Size: &zeroValue}
@@ -16870,6 +16907,16 @@ func TestRepositoryRelease_GetDraft(tt *testing.T) {
 	r.GetDraft()
 }
 
+func TestRepositoryRelease_GetGenerateReleaseNotes(tt *testing.T) {
+	var zeroValue bool
+	r := &RepositoryRelease{GenerateReleaseNotes: &zeroValue}
+	r.GetGenerateReleaseNotes()
+	r = &RepositoryRelease{}
+	r.GetGenerateReleaseNotes()
+	r = nil
+	r.GetGenerateReleaseNotes()
+}
+
 func TestRepositoryRelease_GetHTMLURL(tt *testing.T) {
 	var zeroValue string
 	r := &RepositoryRelease{HTMLURL: &zeroValue}
@@ -17722,6 +17769,30 @@ func TestSCIMUserName_GetFormatted(tt *testing.T) {
 	s.GetFormatted()
 }
 
+func TestSecretScanning_GetStatus(tt *testing.T) {
+	var zeroValue string
+	s := &SecretScanning{Status: &zeroValue}
+	s.GetStatus()
+	s = &SecretScanning{}
+	s.GetStatus()
+	s = nil
+	s.GetStatus()
+}
+
+func TestSecurityAndAnalysis_GetAdvancedSecurity(tt *testing.T) {
+	s := &SecurityAndAnalysis{}
+	s.GetAdvancedSecurity()
+	s = nil
+	s.GetAdvancedSecurity()
+}
+
+func TestSecurityAndAnalysis_GetSecretScanning(tt *testing.T) {
+	s := &SecurityAndAnalysis{}
+	s.GetSecretScanning()
+	s = nil
+	s.GetSecretScanning()
+}
+
 func TestSelectedReposList_GetTotalCount(tt *testing.T) {
 	var zeroValue int
 	s := &SelectedReposList{TotalCount: &zeroValue}
@@ -21125,6 +21196,46 @@ func TestWorkflowJob_GetRunID(tt *testing.T) {
 	w.GetRunID()
 }
 
+func TestWorkflowJob_GetRunnerGroupID(tt *testing.T) {
+	var zeroValue int64
+	w := &WorkflowJob{RunnerGroupID: &zeroValue}
+	w.GetRunnerGroupID()
+	w = &WorkflowJob{}
+	w.GetRunnerGroupID()
+	w = nil
+	w.GetRunnerGroupID()
+}
+
+func TestWorkflowJob_GetRunnerGroupName(tt *testing.T) {
+	var zeroValue string
+	w := &WorkflowJob{RunnerGroupName: &zeroValue}
+	w.GetRunnerGroupName()
+	w = &WorkflowJob{}
+	w.GetRunnerGroupName()
+	w = nil
+	w.GetRunnerGroupName()
+}
+
+func TestWorkflowJob_GetRunnerID(tt *testing.T) {
+	var zeroValue int64
+	w := &WorkflowJob{RunnerID: &zeroValue}
+	w.GetRunnerID()
+	w = &WorkflowJob{}
+	w.GetRunnerID()
+	w = nil
+	w.GetRunnerID()
+}
+
+func TestWorkflowJob_GetRunnerName(tt *testing.T) {
+	var zeroValue string
+	w := &WorkflowJob{RunnerName: &zeroValue}
+	w.GetRunnerName()
+	w = &WorkflowJob{}
+	w.GetRunnerName()
+	w = nil
+	w.GetRunnerName()
+}
+
 func TestWorkflowJob_GetRunURL(tt *testing.T) {
 	var zeroValue string
 	w := &WorkflowJob{RunURL: &zeroValue}
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index 9820f1a3..2db35cd6 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -55,6 +55,16 @@ func TestAdminStats_String(t *testing.T) {
 	}
 }
 
+func TestAdvancedSecurity_String(t *testing.T) {
+	v := AdvancedSecurity{
+		Status: String(""),
+	}
+	want := `github.AdvancedSecurity{Status:""}`
+	if got := v.String(); got != want {
+		t.Errorf("AdvancedSecurity.String = %v, want %v", got, want)
+	}
+}
+
 func TestAuthorization_String(t *testing.T) {
 	v := Authorization{
 		ID:             Int64(0),
@@ -1456,6 +1466,7 @@ func TestRepository_String(t *testing.T) {
 		IsTemplate:          Bool(false),
 		LicenseTemplate:     String(""),
 		GitignoreTemplate:   String(""),
+		SecurityAndAnalysis: &SecurityAndAnalysis{},
 		TeamID:              Int64(0),
 		URL:                 String(""),
 		ArchiveURL:          String(""),
@@ -1496,7 +1507,7 @@ func TestRepository_String(t *testing.T) {
 		TeamsURL:            String(""),
 		Visibility:          String(""),
 	}
-	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, OpenIssues:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Watchers:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, AllowAutoMerge:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}`
+	want := `github.Repository{ID:0, NodeID:"", Owner:github.User{}, Name:"", FullName:"", Description:"", Homepage:"", CodeOfConduct:github.CodeOfConduct{}, DefaultBranch:"", MasterBranch:"", CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PushedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, HTMLURL:"", CloneURL:"", GitURL:"", MirrorURL:"", SSHURL:"", SVNURL:"", Language:"", Fork:false, ForksCount:0, NetworkCount:0, OpenIssuesCount:0, OpenIssues:0, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Watchers:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit:false, AllowAutoMerge:false, DeleteBranchOnMerge:false, Archived:false, Disabled:false, License:github.License{}, Private:false, HasIssues:false, HasWiki:false, HasPages:false, HasProjects:false, HasDownloads:false, IsTemplate:false, LicenseTemplate:"", GitignoreTemplate:"", SecurityAndAnalysis:github.SecurityAndAnalysis{}, TeamID:0, URL:"", ArchiveURL:"", AssigneesURL:"", BlobsURL:"", BranchesURL:"", CollaboratorsURL:"", CommentsURL:"", CommitsURL:"", CompareURL:"", ContentsURL:"", ContributorsURL:"", DeploymentsURL:"", DownloadsURL:"", EventsURL:"", ForksURL:"", GitCommitsURL:"", GitRefsURL:"", GitTagsURL:"", HooksURL:"", IssueCommentURL:"", IssueEventsURL:"", IssuesURL:"", KeysURL:"", LabelsURL:"", LanguagesURL:"", MergesURL:"", MilestonesURL:"", NotificationsURL:"", PullsURL:"", ReleasesURL:"", StargazersURL:"", StatusesURL:"", SubscribersURL:"", SubscriptionURL:"", TagsURL:"", TreesURL:"", TeamsURL:"", Visibility:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Repository.String = %v, want %v", got, want)
 	}
@@ -1590,6 +1601,7 @@ func TestRepositoryRelease_String(t *testing.T) {
 		Draft:                  Bool(false),
 		Prerelease:             Bool(false),
 		DiscussionCategoryName: String(""),
+		GenerateReleaseNotes:   Bool(false),
 		ID:                     Int64(0),
 		CreatedAt:              &Timestamp{},
 		PublishedAt:            &Timestamp{},
@@ -1602,12 +1614,33 @@ func TestRepositoryRelease_String(t *testing.T) {
 		Author:                 &User{},
 		NodeID:                 String(""),
 	}
-	want := `github.RepositoryRelease{TagName:"", TargetCommitish:"", Name:"", Body:"", Draft:false, Prerelease:false, DiscussionCategoryName:"", ID:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PublishedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, URL:"", HTMLURL:"", AssetsURL:"", UploadURL:"", ZipballURL:"", TarballURL:"", Author:github.User{}, NodeID:""}`
+	want := `github.RepositoryRelease{TagName:"", TargetCommitish:"", Name:"", Body:"", Draft:false, Prerelease:false, DiscussionCategoryName:"", GenerateReleaseNotes:false, ID:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, PublishedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, URL:"", HTMLURL:"", AssetsURL:"", UploadURL:"", ZipballURL:"", TarballURL:"", Author:github.User{}, NodeID:""}`
 	if got := v.String(); got != want {
 		t.Errorf("RepositoryRelease.String = %v, want %v", got, want)
 	}
 }
 
+func TestSecretScanning_String(t *testing.T) {
+	v := SecretScanning{
+		Status: String(""),
+	}
+	want := `github.SecretScanning{Status:""}`
+	if got := v.String(); got != want {
+		t.Errorf("SecretScanning.String = %v, want %v", got, want)
+	}
+}
+
+func TestSecurityAndAnalysis_String(t *testing.T) {
+	v := SecurityAndAnalysis{
+		AdvancedSecurity: &AdvancedSecurity{},
+		SecretScanning:   &SecretScanning{},
+	}
+	want := `github.SecurityAndAnalysis{AdvancedSecurity:github.AdvancedSecurity{}, SecretScanning:github.SecretScanning{}}`
+	if got := v.String(); got != want {
+		t.Errorf("SecurityAndAnalysis.String = %v, want %v", got, want)
+	}
+}
+
 func TestSourceImportAuthor_String(t *testing.T) {
 	v := SourceImportAuthor{
 		ID:         Int64(0),
diff --git a/github/issues_test.go b/github/issues_test.go
index 80bfb3ff..3ed7390f 100644
--- a/github/issues_test.go
+++ b/github/issues_test.go
@@ -345,6 +345,40 @@ func TestIssuesService_Edit(t *testing.T) {
 	})
 }
 
+func TestIssuesService_RemoveMilestone(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+	mux.HandleFunc("/repos/o/r/issues/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "PATCH")
+		fmt.Fprint(w, `{"number":1}`)
+	})
+
+	ctx := context.Background()
+	issue, _, err := client.Issues.RemoveMilestone(ctx, "o", "r", 1)
+	if err != nil {
+		t.Errorf("Issues.RemoveMilestone returned error: %v", err)
+	}
+
+	want := &Issue{Number: Int(1)}
+	if !cmp.Equal(issue, want) {
+		t.Errorf("Issues.RemoveMilestone returned %+v, want %+v", issue, want)
+	}
+
+	const methodName = "RemoveMilestone"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Issues.RemoveMilestone(ctx, "\n", "\n", -1)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Issues.RemoveMilestone(ctx, "o", "r", 1)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestIssuesService_Edit_invalidOwner(t *testing.T) {
 	client, _, _, teardown := setup()
 	defer teardown()
diff --git a/github/orgs_audit_log_test.go b/github/orgs_audit_log_test.go
index 95b0a0cf..c2beca2b 100644
--- a/github/orgs_audit_log_test.go
+++ b/github/orgs_audit_log_test.go
@@ -9,6 +9,7 @@ import (
 	"context"
 	"fmt"
 	"net/http"
+	"strings"
 	"testing"
 	"time"
 
@@ -57,7 +58,7 @@ func TestOrganizationService_GetAuditLog(t *testing.T) {
 		Order:   String("asc"),
 	}
 
-	auditEntries, _, err := client.Organizations.GetAuditLog(ctx, "o", &getOpts)
+	auditEntries, resp, err := client.Organizations.GetAuditLog(ctx, "o", &getOpts)
 	if err != nil {
 		t.Errorf("Organizations.GetAuditLog returned error: %v", err)
 	}
@@ -97,6 +98,12 @@ func TestOrganizationService_GetAuditLog(t *testing.T) {
 		t.Errorf("Organizations.GetAuditLog return \ngot: %+v,\nwant:%+v", auditEntries, want)
 	}
 
+	// assert query string has lower case params
+	requestedQuery := resp.Request.URL.RawQuery
+	if !strings.Contains(requestedQuery, "phrase") {
+		t.Errorf("Organizations.GetAuditLog query string \ngot: %+v,\nwant:%+v", requestedQuery, "phrase")
+	}
+
 	const methodName = "GetAuditLog"
 	testBadOptions(t, methodName, func() (err error) {
 		_, _, err = client.Organizations.GetAuditLog(ctx, "\n", &getOpts)
@@ -200,9 +207,9 @@ func TestAuditEntry_Marshal(t *testing.T) {
 		Repo:                  String("r"),
 		Repository:            String("repo"),
 		RepositoryPublic:      Bool(false),
-		RunnerGroupID:         String("rgid"),
+		RunnerGroupID:         Int64(1),
 		RunnerGroupName:       String("rgn"),
-		RunnerID:              String("rid"),
+		RunnerID:              Int64(1),
 		RunnerLabels:          []string{"s"},
 		RunnerName:            String("rn"),
 		SecretsPassed:         []string{"s"},
@@ -268,9 +275,9 @@ func TestAuditEntry_Marshal(t *testing.T) {
 		"repo": "r",
 		"repository": "repo",
 		"repository_public": false,
-		"runner_group_id": "rgid",
+		"runner_group_id": 1,
 		"runner_group_name": "rgn",
-		"runner_id": "rid",
+		"runner_id": 1,
 		"runner_labels": [
 			"s"
 		],
diff --git a/github/repos_autolinks_test.go b/github/repos_autolinks_test.go
index b6121d2c..930be7f5 100644
--- a/github/repos_autolinks_test.go
+++ b/github/repos_autolinks_test.go
@@ -152,3 +152,37 @@ func TestRepositoriesService_DeleteAutolink(t *testing.T) {
 		return client.Repositories.DeleteAutolink(ctx, "o", "r", 2)
 	})
 }
+
+func TestAutolinkOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AutolinkOptions{}, "{}")
+
+	r := &AutolinkOptions{
+		KeyPrefix:   String("kp"),
+		URLTemplate: String("URLT"),
+	}
+
+	want := `{
+		"key_prefix": "kp",
+		"url_template": "URLT"
+	}`
+
+	testJSONMarshal(t, r, want)
+}
+
+func TestAutolink_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Autolink{}, "{}")
+
+	r := &Autolink{
+		ID:          Int64(1),
+		KeyPrefix:   String("kp"),
+		URLTemplate: String("URLT"),
+	}
+
+	want := `{
+		"id": 1,
+		"key_prefix": "kp",
+		"url_template": "URLT"
+	}`
+
+	testJSONMarshal(t, r, want)
+}
diff --git a/github/repos_environments_test.go b/github/repos_environments_test.go
index 4165ad75..18a30ad6 100644
--- a/github/repos_environments_test.go
+++ b/github/repos_environments_test.go
@@ -326,3 +326,97 @@ func TestRepoEnvironment_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, repoEnv, want)
 }
+
+func TestEnvReviewers_Marshal(t *testing.T) {
+	testJSONMarshal(t, &EnvReviewers{}, "{}")
+
+	repoEnv := &EnvReviewers{
+		Type: String("main"),
+		ID:   Int64(1),
+	}
+
+	want := `{
+		"type":"main",
+		"id":1
+	}`
+
+	testJSONMarshal(t, repoEnv, want)
+}
+
+func TestEnvironment_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Environment{}, "{}")
+
+	repoEnv := &Environment{
+		Owner:           String("o"),
+		Repo:            String("r"),
+		EnvironmentName: String("e"),
+		WaitTimer:       Int(123),
+		Reviewers: []*EnvReviewers{
+			{
+				Type: String("main"),
+				ID:   Int64(1),
+			},
+			{
+				Type: String("rev"),
+				ID:   Int64(2),
+			},
+		},
+		DeploymentBranchPolicy: &BranchPolicy{
+			ProtectedBranches:    Bool(false),
+			CustomBranchPolicies: Bool(false),
+		},
+		ID:        Int64(2),
+		NodeID:    String("star"),
+		Name:      String("eg"),
+		URL:       String("https://hey.in"),
+		HTMLURL:   String("htmlurl"),
+		CreatedAt: &Timestamp{referenceTime},
+		UpdatedAt: &Timestamp{referenceTime},
+		ProtectionRules: []*ProtectionRule{
+			{
+				ID:        Int64(21),
+				NodeID:    String("mnb"),
+				Type:      String("ewq"),
+				WaitTimer: Int(9090),
+			},
+		},
+	}
+
+	want := `{
+		"owner":"o",
+		"repo":"r",
+		"environment_name":"e",
+		"wait_timer":123,
+		"reviewers":[
+			{
+				"type":"main",
+				"id":1
+			},
+			{
+				"type":"rev",
+				"id":2
+			}
+		],
+		"deployment_branch_policy":{
+			"protected_branches":false,
+			"custom_branch_policies":false
+		},
+		"id":2,
+		"node_id":"star",
+		"name":"eg",
+		"url":"https://hey.in",
+		"html_url":"htmlurl",
+		"created_at":` + referenceTimeStr + `,
+		"updated_at":` + referenceTimeStr + `,
+		"protection_rules":[
+			{
+				"id":21,
+				"node_id":"mnb",
+				"type":"ewq",
+				"wait_timer":9090
+			}
+		]
+	}`
+
+	testJSONMarshal(t, repoEnv, want)
+}
diff --git a/github/repos_hooks_deliveries_test.go b/github/repos_hooks_deliveries_test.go
index b970eb49..8724e863 100644
--- a/github/repos_hooks_deliveries_test.go
+++ b/github/repos_hooks_deliveries_test.go
@@ -219,3 +219,116 @@ func TestHookDelivery_ParsePayload_invalidPayload(t *testing.T) {
 		t.Errorf("unexpected error: %v", err)
 	}
 }
+
+func TestHookRequest_Marshal(t *testing.T) {
+	testJSONMarshal(t, &HookRequest{}, "{}")
+
+	header := make(map[string]string)
+	header["key"] = "value"
+
+	jsonMsg, _ := json.Marshal(&header)
+
+	r := &HookRequest{
+		Headers:    header,
+		RawPayload: (*json.RawMessage)(&jsonMsg),
+	}
+
+	want := `{
+		"headers": {
+			"key": "value"
+		},
+		"payload": {
+			"key": "value"
+		}
+	}`
+
+	testJSONMarshal(t, r, want)
+}
+
+func TestHookResponse_Marshal(t *testing.T) {
+	testJSONMarshal(t, &HookResponse{}, "{}")
+
+	header := make(map[string]string)
+	header["key"] = "value"
+
+	jsonMsg, _ := json.Marshal(&header)
+
+	r := &HookResponse{
+		Headers:    header,
+		RawPayload: (*json.RawMessage)(&jsonMsg),
+	}
+
+	want := `{
+		"headers": {
+			"key": "value"
+		},
+		"payload": {
+			"key": "value"
+		}
+	}`
+
+	testJSONMarshal(t, r, want)
+}
+
+func TestHookDelivery_Marshal(t *testing.T) {
+	testJSONMarshal(t, &HookDelivery{}, "{}")
+
+	header := make(map[string]string)
+	header["key"] = "value"
+
+	jsonMsg, _ := json.Marshal(&header)
+
+	r := &HookDelivery{
+		ID:             Int64(1),
+		GUID:           String("guid"),
+		DeliveredAt:    &Timestamp{referenceTime},
+		Redelivery:     Bool(true),
+		Duration:       Float64(1),
+		Status:         String("guid"),
+		StatusCode:     Int(1),
+		Event:          String("guid"),
+		Action:         String("guid"),
+		InstallationID: String("guid"),
+		RepositoryID:   Int64(1),
+		Request: &HookRequest{
+			Headers:    header,
+			RawPayload: (*json.RawMessage)(&jsonMsg),
+		},
+		Response: &HookResponse{
+			Headers:    header,
+			RawPayload: (*json.RawMessage)(&jsonMsg),
+		},
+	}
+
+	want := `{
+		"id": 1,
+		"guid": "guid",
+		"delivered_at": ` + referenceTimeStr + `,
+		"redelivery": true,
+		"duration": 1,
+		"status": "guid",
+		"status_code": 1,
+		"event": "guid",
+		"action": "guid",
+		"installation_id": "guid",
+		"repository_id": 1,
+		"request": {
+			"headers": {
+				"key": "value"
+			},
+			"payload": {
+				"key": "value"
+			}
+		},
+		"response": {
+			"headers": {
+				"key": "value"
+			},
+			"payload": {
+				"key": "value"
+			}
+		}
+	}`
+
+	testJSONMarshal(t, r, want)
+}
diff --git a/github/repos_releases_test.go b/github/repos_releases_test.go
index 69041c0c..bebbc0ed 100644
--- a/github/repos_releases_test.go
+++ b/github/repos_releases_test.go
@@ -55,6 +55,47 @@ func TestRepositoriesService_ListReleases(t *testing.T) {
 	})
 }
 
+func TestRepositoriesService_GenerateReleaseNotes(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/releases/generate-notes", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "POST")
+		testBody(t, r, `{"tag_name":"v1.0.0"}`+"\n")
+		fmt.Fprint(w, `{"name":"v1.0.0","body":"**Full Changelog**: https://github.com/o/r/compare/v0.9.0...v1.0.0"}`)
+	})
+
+	opt := &GenerateNotesOptions{
+		TagName: "v1.0.0",
+	}
+	ctx := context.Background()
+	releases, _, err := client.Repositories.GenerateReleaseNotes(ctx, "o", "r", opt)
+	if err != nil {
+		t.Errorf("Repositories.GenerateReleaseNotes returned error: %v", err)
+	}
+	want := &RepositoryReleaseNotes{
+		Name: "v1.0.0",
+		Body: "**Full Changelog**: https://github.com/o/r/compare/v0.9.0...v1.0.0",
+	}
+	if !cmp.Equal(releases, want) {
+		t.Errorf("Repositories.GenerateReleaseNotes returned %+v, want %+v", releases, want)
+	}
+
+	const methodName = "GenerateReleaseNotes"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.GenerateReleaseNotes(ctx, "\n", "\n", opt)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Repositories.GenerateReleaseNotes(ctx, "o", "r", opt)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestRepositoriesService_GetRelease(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -167,6 +208,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) {
 	input := &RepositoryRelease{
 		Name:                   String("v1.0"),
 		DiscussionCategoryName: String("General"),
+		GenerateReleaseNotes:   Bool(true),
 		// Fields to be removed:
 		ID:          Int64(2),
 		CreatedAt:   &Timestamp{referenceTime},
@@ -190,6 +232,7 @@ func TestRepositoriesService_CreateRelease(t *testing.T) {
 		want := &repositoryReleaseRequest{
 			Name:                   String("v1.0"),
 			DiscussionCategoryName: String("General"),
+			GenerateReleaseNotes:   Bool(true),
 		}
 		if !cmp.Equal(v, want) {
 			t.Errorf("Request body = %+v, want %+v", v, want)
@@ -230,6 +273,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) {
 	input := &RepositoryRelease{
 		Name:                   String("n"),
 		DiscussionCategoryName: String("General"),
+		GenerateReleaseNotes:   Bool(true),
 		// Fields to be removed:
 		ID:          Int64(2),
 		CreatedAt:   &Timestamp{referenceTime},
@@ -253,6 +297,7 @@ func TestRepositoriesService_EditRelease(t *testing.T) {
 		want := &repositoryReleaseRequest{
 			Name:                   String("n"),
 			DiscussionCategoryName: String("General"),
+			GenerateReleaseNotes:   Bool(true),
 		}
 		if !cmp.Equal(v, want) {
 			t.Errorf("Request body = %+v, want %+v", v, want)
@@ -775,3 +820,21 @@ func TestRepositoryRelease_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestGenerateNotesOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &GenerateNotesOptions{}, "{}")
+
+	u := &GenerateNotesOptions{
+		TagName:         "tag_name",
+		PreviousTagName: String("previous_tag_name"),
+		TargetCommitish: String("target_commitish"),
+	}
+
+	want := `{
+		"tag_name":          "tag_name",
+		"previous_tag_name": "previous_tag_name",
+		"target_commitish":  "target_commitish"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/repos_test.go b/github/repos_test.go
index 4c799048..dae6d221 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -360,7 +360,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 	mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", "))
-		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"}}`)
+		fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"}}}`)
 	})
 
 	ctx := context.Background()
@@ -369,7 +369,7 @@ func TestRepositoriesService_Get(t *testing.T) {
 		t.Errorf("Repositories.Get returned error: %v", err)
 	}
 
-	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}}
+	want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}}}
 	if !cmp.Equal(got, want) {
 		t.Errorf("Repositories.Get returned %+v, want %+v", got, want)
 	}
@@ -981,6 +981,51 @@ func TestRepositoriesService_GetBranch_notFound(t *testing.T) {
 	})
 }
 
+func TestRepositoriesService_RenameBranch(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	renameBranchReq := "nn"
+
+	mux.HandleFunc("/repos/o/r/branches/b/rename", func(w http.ResponseWriter, r *http.Request) {
+		v := new(renameBranchRequest)
+		json.NewDecoder(r.Body).Decode(v)
+
+		testMethod(t, r, "POST")
+		want := &renameBranchRequest{NewName: "nn"}
+		if !cmp.Equal(v, want) {
+			t.Errorf("Request body = %+v, want %+v", v, want)
+		}
+
+		fmt.Fprint(w, `{"protected":true,"name":"nn"}`)
+	})
+
+	ctx := context.Background()
+	got, _, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
+	if err != nil {
+		t.Errorf("Repositories.RenameBranch returned error: %v", err)
+	}
+
+	want := &Branch{Name: String("nn"), Protected: Bool(true)}
+	if !cmp.Equal(got, want) {
+		t.Errorf("Repositories.RenameBranch returned %+v, want %+v", got, want)
+	}
+
+	const methodName = "RenameBranch"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.RenameBranch(ctx, "\n", "\n", "\n", renameBranchReq)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Repositories.RenameBranch(ctx, "o", "r", "b", renameBranchReq)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestRepositoriesService_GetBranchProtection(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
@@ -2353,3 +2398,17 @@ func TestRepositoriesService_Dispatch(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestAdvancedSecurity_Marshal(t *testing.T) {
+	testJSONMarshal(t, &AdvancedSecurity{}, "{}")
+
+	u := &AdvancedSecurity{
+		Status: String("status"),
+	}
+
+	want := `{
+		"status": "status"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/repos_traffic_test.go b/github/repos_traffic_test.go
index c47ac922..88046b7b 100644
--- a/github/repos_traffic_test.go
+++ b/github/repos_traffic_test.go
@@ -200,3 +200,111 @@ func TestRepositoriesService_ListTrafficClones(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestTrafficReferrer_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TrafficReferrer{}, "{}")
+
+	u := &TrafficReferrer{
+		Referrer: String("referrer"),
+		Count:    Int(0),
+		Uniques:  Int(0),
+	}
+
+	want := `{
+		"referrer" : "referrer",
+		"count" : 0,
+		"uniques" : 0
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTrafficViews_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TrafficViews{}, "{}")
+
+	u := &TrafficViews{
+		Views: []*TrafficData{{
+			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
+			Count:     Int(7),
+			Uniques:   Int(6),
+		}},
+		Count:   Int(0),
+		Uniques: Int(0),
+	}
+
+	want := `{
+		"views": [{
+			"timestamp": "2016-05-31T16:00:00.000Z",
+			"count": 7,
+			"uniques": 6
+		}],
+		"count" : 0,
+		"uniques" : 0
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTrafficClones_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TrafficClones{}, "{}")
+
+	u := &TrafficClones{
+		Clones: []*TrafficData{{
+			Timestamp: &Timestamp{time.Date(2021, time.October, 29, 16, 0, 0, 0, time.UTC)},
+			Count:     Int(1),
+			Uniques:   Int(1),
+		}},
+		Count:   Int(0),
+		Uniques: Int(0),
+	}
+
+	want := `{
+		"clones": [{
+			"timestamp": "2021-10-29T16:00:00.000Z",
+			"count": 1,
+			"uniques": 1
+		}],
+		"count" : 0,
+		"uniques" : 0
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTrafficPath_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TrafficPath{}, "{}")
+
+	u := &TrafficPath{
+		Path:    String("test/path"),
+		Title:   String("test"),
+		Count:   Int(2),
+		Uniques: Int(3),
+	}
+
+	want := `{
+		"path" : "test/path",
+		"title": "test",
+		"count": 2,
+		"uniques": 3
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTrafficData_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TrafficData{}, "{}")
+
+	u := &TrafficData{
+		Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
+		Count:     Int(7),
+		Uniques:   Int(6),
+	}
+
+	want := `{	
+			"timestamp": "2016-05-31T16:00:00.000Z",
+			"count": 7,
+			"uniques": 6
+      }`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/scim_test.go b/github/scim_test.go
index 3338a28a..328bc209 100644
--- a/github/scim_test.go
+++ b/github/scim_test.go
@@ -192,3 +192,51 @@ func TestSCIMService_DeleteSCIMUserFromOrg(t *testing.T) {
 		return client.SCIM.DeleteSCIMUserFromOrg(ctx, "o", "123")
 	})
 }
+
+func TestSCIMUserAttributes_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SCIMUserAttributes{}, `{
+		"userName":"","name":{"givenName":"","familyName":""},"emails":null
+	}`)
+
+	u := &SCIMUserAttributes{
+		UserName: "userName1",
+		Name: SCIMUserName{
+			GivenName:  "Name1",
+			FamilyName: "Fname",
+			Formatted:  String("formatted name"),
+		},
+		DisplayName: String("Name"),
+		Emails: []*SCIMUserEmail{
+			{
+				Value:   "value",
+				Primary: Bool(false),
+				Type:    String("type"),
+			},
+		},
+		Schemas:    []string{"schema1"},
+		ExternalID: String("id"),
+		Groups:     []string{"group1"},
+		Active:     Bool(true),
+	}
+
+	want := `{
+		"userName": "userName1",
+		"name": {
+			"givenName": "Name1",
+			"familyName": "Fname",
+			"formatted": "formatted name"
+		},
+		"displayName": "Name",
+		"emails": [{
+			"value": "value",
+			"primary": false,
+			"type": "type"
+		}],
+		"schemas": ["schema1"],
+		"externalId": "id",
+		"groups": ["group1"],
+		"active": true
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/search_test.go b/github/search_test.go
index 0fc57962..4562fcf5 100644
--- a/github/search_test.go
+++ b/github/search_test.go
@@ -481,3 +481,318 @@ func TestSearchService_Labels_coverage(t *testing.T) {
 		return err
 	})
 }
+
+func TestMatch_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Match{}, "{}")
+
+	u := &Match{
+		Text:    String("txt"),
+		Indices: []int{1},
+	}
+
+	want := `{
+		"text": "txt",
+		"indices": [1]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTextMatch_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TextMatch{}, "{}")
+
+	u := &TextMatch{
+		ObjectURL:  String("ourl"),
+		ObjectType: String("otype"),
+		Property:   String("prop"),
+		Fragment:   String("fragment"),
+		Matches: []*Match{
+			{
+				Text:    String("txt"),
+				Indices: []int{1},
+			},
+		},
+	}
+
+	want := `{
+		"object_url": "ourl",
+		"object_type": "otype",
+		"property": "prop",
+		"fragment": "fragment",
+		"matches": [{
+			"text": "txt",
+			"indices": [1]
+		}]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestTopicResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TopicResult{}, "{}")
+
+	u := &TopicResult{
+		Name:             String("name"),
+		DisplayName:      String("displayName"),
+		ShortDescription: String("shortDescription"),
+		Description:      String("description"),
+		CreatedBy:        String("createdBy"),
+		UpdatedAt:        String("2021-10-26"),
+		Featured:         Bool(false),
+		Curated:          Bool(true),
+		Score:            Float64(99.9),
+	}
+
+	want := `{
+		"name": "name",
+		"display_name": "displayName",
+		"short_description": "shortDescription",
+		"description": "description",
+		"created_by": "createdBy",
+		"updated_at": "2021-10-26",
+		"featured": false,
+		"curated": true,
+		"score": 99.9
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestRepositoriesSearchResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &RepositoriesSearchResult{}, "{}")
+
+	u := &RepositoriesSearchResult{
+		Total:             Int(0),
+		IncompleteResults: Bool(true),
+		Repositories:      []*Repository{{ID: Int64(1)}},
+	}
+
+	want := `{
+		"total_count" : 0,
+		"incomplete_results" : true,
+		"items" : [{"id":1}]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestCommitsSearchResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &CommitsSearchResult{}, "{}")
+
+	c := &CommitsSearchResult{
+		Total:             Int(0),
+		IncompleteResults: Bool(true),
+		Commits: []*CommitResult{{
+			SHA: String("s"),
+		}},
+	}
+
+	want := `{
+		"total_count" : 0,
+		"incomplete_results" : true,
+		"items" : [{"sha" : "s"}]
+	}`
+
+	testJSONMarshal(t, c, want)
+}
+
+func TestTopicsSearchResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TopicsSearchResult{}, "{}")
+
+	u := &TopicsSearchResult{
+		Total:             Int(2),
+		IncompleteResults: Bool(false),
+		Topics: []*TopicResult{
+			{
+				Name:             String("t1"),
+				DisplayName:      String("tt"),
+				ShortDescription: String("t desc"),
+				Description:      String("desc"),
+				CreatedBy:        String("mi"),
+				CreatedAt:        &Timestamp{referenceTime},
+				UpdatedAt:        String("2006-01-02T15:04:05Z"),
+				Featured:         Bool(true),
+				Curated:          Bool(true),
+				Score:            Float64(123),
+			},
+		},
+	}
+
+	want := `{
+		"total_count" : 2,
+		"incomplete_results" : false,
+		"items" : [
+			{
+				"name" : "t1",
+				"display_name":"tt",
+				"short_description":"t desc",
+				"description":"desc",
+				"created_by":"mi",
+				"created_at":` + referenceTimeStr + `,
+				"updated_at":"2006-01-02T15:04:05Z",
+				"featured":true,
+				"curated":true,
+				"score":123
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestLabelResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &LabelResult{}, "{}")
+
+	u := &LabelResult{
+		ID:          Int64(11),
+		URL:         String("url"),
+		Name:        String("label"),
+		Color:       String("green"),
+		Default:     Bool(true),
+		Description: String("desc"),
+		Score:       Float64(123),
+	}
+
+	want := `{
+		"id":11,
+		"url":"url",
+		"name":"label",
+		"color":"green",
+		"default":true,
+		"description":"desc",
+		"score":123
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestSearchOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &SearchOptions{}, "{}")
+
+	u := &SearchOptions{
+		Sort:      "author-date",
+		Order:     "asc",
+		TextMatch: false,
+		ListOptions: ListOptions{
+			Page:    int(1),
+			PerPage: int(10),
+		},
+	}
+
+	want := `{	
+		"sort": "author-date",
+		"order": "asc",
+		"page": 1,
+		"perPage": 10
+      }`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestIssuesSearchResult_Marshal(t *testing.T) {
+	testJSONMarshal(t, &IssuesSearchResult{}, "{}")
+
+	u := &IssuesSearchResult{
+		Total:             Int(48),
+		IncompleteResults: Bool(false),
+		Issues: []*Issue{
+			{
+				ID:                Int64(1),
+				Number:            Int(1),
+				State:             String("s"),
+				Locked:            Bool(false),
+				Title:             String("title"),
+				Body:              String("body"),
+				AuthorAssociation: String("aa"),
+				User:              &User{ID: Int64(1)},
+				Labels:            []*Label{{ID: Int64(1)}},
+				Assignee:          &User{ID: Int64(1)},
+				Comments:          Int(1),
+				ClosedAt:          &referenceTime,
+				CreatedAt:         &referenceTime,
+				UpdatedAt:         &referenceTime,
+				ClosedBy:          &User{ID: Int64(1)},
+				URL:               String("url"),
+				HTMLURL:           String("hurl"),
+				CommentsURL:       String("curl"),
+				EventsURL:         String("eurl"),
+				LabelsURL:         String("lurl"),
+				RepositoryURL:     String("rurl"),
+				Milestone:         &Milestone{ID: Int64(1)},
+				PullRequestLinks:  &PullRequestLinks{URL: String("url")},
+				Repository:        &Repository{ID: Int64(1)},
+				Reactions:         &Reactions{TotalCount: Int(1)},
+				Assignees:         []*User{{ID: Int64(1)}},
+				NodeID:            String("nid"),
+				TextMatches:       []*TextMatch{{ObjectURL: String("ourl")}},
+				ActiveLockReason:  String("alr"),
+			},
+		},
+	}
+
+	want := `{
+		"total_count": 48,
+		"incomplete_results": false,
+		"items": [
+			{
+				"id": 1,
+				"number": 1,
+				"state": "s",
+				"locked": false,
+				"title": "title",
+				"body": "body",
+				"author_association": "aa",
+				"user": {
+					"id": 1
+				},
+				"labels": [
+					{
+						"id": 1
+					}
+				],
+				"assignee": {
+					"id": 1
+				},
+				"comments": 1,
+				"closed_at": ` + referenceTimeStr + `,
+				"created_at": ` + referenceTimeStr + `,
+				"updated_at": ` + referenceTimeStr + `,
+				"closed_by": {
+					"id": 1
+				},
+				"url": "url",
+				"html_url": "hurl",
+				"comments_url": "curl",
+				"events_url": "eurl",
+				"labels_url": "lurl",
+				"repository_url": "rurl",
+				"milestone": {
+					"id": 1
+				},
+				"pull_request": {
+					"url": "url"
+				},
+				"repository": {
+					"id": 1
+				},
+				"reactions": {
+					"total_count": 1
+				},
+				"assignees": [
+					{
+						"id": 1
+					}
+				],
+				"node_id": "nid",
+				"text_matches": [
+					{
+						"object_url": "ourl"
+					}
+				],
+				"active_lock_reason": "alr"
+			}
+		]
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/teams_discussion_comments_test.go b/github/teams_discussion_comments_test.go
index 3f911650..f6b5433b 100644
--- a/github/teams_discussion_comments_test.go
+++ b/github/teams_discussion_comments_test.go
@@ -431,3 +431,63 @@ func TestTeamsService_DeleteComment(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestDiscussionComment_Marshal(t *testing.T) {
+	testJSONMarshal(t, &DiscussionComment{}, "{}")
+
+	u := &DiscussionComment{
+		Author:        &User{},
+		Body:          String("body"),
+		BodyHTML:      String("body html"),
+		BodyVersion:   String("body version"),
+		CreatedAt:     &Timestamp{referenceTime},
+		LastEditedAt:  &Timestamp{referenceTime},
+		DiscussionURL: String("url"),
+		HTMLURL:       String("html url"),
+		NodeID:        String("node"),
+		Number:        Int(1),
+		UpdatedAt:     &Timestamp{referenceTime},
+		URL:           String("url"),
+		Reactions: &Reactions{
+			TotalCount: Int(10),
+			PlusOne:    Int(1),
+			MinusOne:   Int(1),
+			Laugh:      Int(1),
+			Confused:   Int(1),
+			Heart:      Int(2),
+			Hooray:     Int(5),
+			Rocket:     Int(3),
+			Eyes:       Int(9),
+			URL:        String("url"),
+		},
+	}
+
+	want := `{
+		"author":{},
+		"body":"body",
+		"body_html":"body html",
+		"body_version":"body version",
+		"created_at":` + referenceTimeStr + `,
+		"last_edited_at":` + referenceTimeStr + `,
+		"discussion_url":"url",
+		"html_url":"html url",
+		"node_id":"node",
+		"number":1,
+		"updated_at":` + referenceTimeStr + `,
+		"url":"url",
+		"reactions":{
+			"total_count": 10,
+			"+1": 1,
+			"-1": 1,
+			"laugh": 1,
+			"confused": 1,
+			"heart": 2,
+			"hooray": 5,
+			"rocket": 3,
+			"eyes": 9,
+			"url":"url"
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/teams_discussions_test.go b/github/teams_discussions_test.go
index 3c94f566..06328acb 100644
--- a/github/teams_discussions_test.go
+++ b/github/teams_discussions_test.go
@@ -541,3 +541,47 @@ func TestTeamsService_DeleteDiscussionBySlug(t *testing.T) {
 		return client.Teams.DeleteDiscussionBySlug(ctx, "o", "s", 3)
 	})
 }
+
+func TestTeamDiscussion_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TeamDiscussion{}, "{}")
+
+	u := &TeamDiscussion{
+		Author: &User{
+			Login:       String("author"),
+			ID:          Int64(0),
+			URL:         String("https://api.github.com/users/author"),
+			AvatarURL:   String("https://avatars1.githubusercontent.com/u/0?v=4"),
+			GravatarID:  String(""),
+			CreatedAt:   &Timestamp{referenceTime},
+			SuspendedAt: &Timestamp{referenceTime},
+		},
+		Body:          String("test"),
+		BodyHTML:      String("<p>test</p>"),
+		BodyVersion:   String("version"),
+		CommentsCount: Int(1),
+		CommentsURL:   String("https://api.github.com/teams/2/discussions/3/comments"),
+		CreatedAt:     &Timestamp{referenceTime},
+		LastEditedAt:  &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"author": {
+			"login": "author",
+			"id": 0,
+			"avatar_url": "https://avatars1.githubusercontent.com/u/0?v=4",
+			"gravatar_id": "",
+			"url": "https://api.github.com/users/author",
+			"created_at": ` + referenceTimeStr + `,
+			"suspended_at": ` + referenceTimeStr + `	
+		},
+		"body": "test",
+		"body_html": "<p>test</p>",
+		"body_version": "version",
+		"comments_count": 1,
+		"comments_url": "https://api.github.com/teams/2/discussions/3/comments",
+		"created_at": ` + referenceTimeStr + `,
+		"last_edited_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/teams_members_test.go b/github/teams_members_test.go
index 8b3c4a9c..61944567 100644
--- a/github/teams_members_test.go
+++ b/github/teams_members_test.go
@@ -789,3 +789,17 @@ func TestTeamsService__ListPendingTeamInvitationsBySlug_invalidOrg(t *testing.T)
 	_, _, err := client.Teams.ListPendingTeamInvitationsBySlug(ctx, "%", "s", nil)
 	testURLParseError(t, err)
 }
+
+func TestTeamAddTeamMembershipOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &TeamAddTeamMembershipOptions{}, "{}")
+
+	u := &TeamAddTeamMembershipOptions{
+		Role: "role",
+	}
+
+	want := `{
+		"role": "role"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/teams_test.go b/github/teams_test.go
index 748721c3..26cf2c03 100644
--- a/github/teams_test.go
+++ b/github/teams_test.go
@@ -1586,6 +1586,34 @@ func TestTeamsService_CreateOrUpdateIDPGroupConnectionsBySlug_empty(t *testing.T
 	}
 }
 
+func TestNewTeam_Marshal(t *testing.T) {
+	testJSONMarshal(t, &NewTeam{}, "{}")
+
+	u := &NewTeam{
+		Name:         "n",
+		Description:  String("d"),
+		Maintainers:  []string{"m1", "m2"},
+		RepoNames:    []string{"repo1", "repo2"},
+		ParentTeamID: Int64(1),
+		Permission:   String("perm"),
+		Privacy:      String("p"),
+		LDAPDN:       String("l"),
+	}
+
+	want := `{
+		"name":           "n",
+		"description":    "d",
+		"maintainers":    ["m1", "m2"],
+		"repo_names":     ["repo1", "repo2"],
+		"parent_team_id": 1,
+		"permission":     "perm",
+		"privacy":        "p",
+		"ldap_dn":        "l"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestTeams_Marshal(t *testing.T) {
 	testJSONMarshal(t, &Team{}, "{}")
 
@@ -1671,3 +1699,49 @@ func TestTeams_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestInvitation_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Invitation{}, "{}")
+
+	u := &Invitation{
+		ID:                Int64(1),
+		NodeID:            String("test node"),
+		Login:             String("login123"),
+		Email:             String("go@github.com"),
+		Role:              String("developer"),
+		CreatedAt:         &referenceTime,
+		TeamCount:         Int(99),
+		InvitationTeamURL: String("url"),
+	}
+
+	want := `{
+		"id": 1,
+		"node_id": "test node",
+		"login":"login123",
+		"email":"go@github.com",
+		"role":"developer",
+		"created_at":` + referenceTimeStr + `,
+		"team_count":99,
+		"invitation_team_url":"url"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestIDPGroup_Marshal(t *testing.T) {
+	testJSONMarshal(t, &IDPGroup{}, "{}")
+
+	u := &IDPGroup{
+		GroupID:          String("abc1"),
+		GroupName:        String("test group"),
+		GroupDescription: String("test group descripation"),
+	}
+
+	want := `{
+		"group_id": "abc1",
+		"group_name": "test group",
+		"group_description":"test group descripation"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/users_administration_test.go b/github/users_administration_test.go
index fdd6fe94..ff8f9358 100644
--- a/github/users_administration_test.go
+++ b/github/users_administration_test.go
@@ -142,3 +142,17 @@ func TestUsersService_Unsuspend(t *testing.T) {
 		return client.Users.Unsuspend(ctx, "u")
 	})
 }
+
+func TestUserSuspendOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserSuspendOptions{}, "{}")
+
+	u := &UserSuspendOptions{
+		Reason: String("reason"),
+	}
+
+	want := `{
+		"reason": "reason"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/users_emails_test.go b/github/users_emails_test.go
index 392bd2a1..d40356d8 100644
--- a/github/users_emails_test.go
+++ b/github/users_emails_test.go
@@ -120,3 +120,23 @@ func TestUsersService_DeleteEmails(t *testing.T) {
 		return client.Users.DeleteEmails(ctx, input)
 	})
 }
+
+func TestUserEmail_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserEmail{}, "{}")
+
+	u := &UserEmail{
+		Email:      String("qwe@qwe.qwe"),
+		Primary:    Bool(false),
+		Verified:   Bool(true),
+		Visibility: String("yes"),
+	}
+
+	want := `{
+		"email": "qwe@qwe.qwe",
+		"primary": false,
+		"verified": true,
+		"visibility": "yes"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/users_gpg_keys_test.go b/github/users_gpg_keys_test.go
index a6b24414..2cef7522 100644
--- a/github/users_gpg_keys_test.go
+++ b/github/users_gpg_keys_test.go
@@ -11,6 +11,7 @@ import (
 	"fmt"
 	"net/http"
 	"testing"
+	"time"
 
 	"github.com/google/go-cmp/cmp"
 )
@@ -189,3 +190,73 @@ func TestUsersService_DeleteGPGKey(t *testing.T) {
 		return client.Users.DeleteGPGKey(ctx, 1)
 	})
 }
+
+func TestGPGEmail_Marshal(t *testing.T) {
+	testJSONMarshal(t, &GPGEmail{}, "{}")
+
+	u := &GPGEmail{
+		Email:    String("email@abc.com"),
+		Verified: Bool(false),
+	}
+
+	want := `{
+		"email" : "email@abc.com",
+		"verified" : false
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestGPGKey_Marshal(t *testing.T) {
+	testJSONMarshal(t, &GPGKey{}, "{}")
+
+	ti := &time.Time{}
+
+	g := &GPGKey{
+		ID:           Int64(1),
+		PrimaryKeyID: Int64(1),
+		KeyID:        String("someKeyID"),
+		RawKey:       String("someRawKeyID"),
+		PublicKey:    String("somePublicKey"),
+		Emails: []*GPGEmail{
+			{
+				Email:    String("someEmail"),
+				Verified: Bool(true),
+			},
+		},
+		Subkeys: []*GPGKey{
+			{},
+		},
+		CanSign:           Bool(true),
+		CanEncryptComms:   Bool(true),
+		CanEncryptStorage: Bool(true),
+		CanCertify:        Bool(true),
+		CreatedAt:         ti,
+		ExpiresAt:         ti,
+	}
+
+	want := `{
+			"id":1,
+			"primary_key_id":1,
+			"key_id":"someKeyID",
+			"raw_key":"someRawKeyID",
+			"public_key":"somePublicKey",
+			"emails":[
+				{
+					"email":"someEmail",
+					"verified":true
+				}
+			],
+			"subkeys":[
+				{}
+			],
+			"can_sign":true,
+			"can_encrypt_comms":true,
+			"can_encrypt_storage":true,
+			"can_certify":true,
+			"created_at":"0001-01-01T00:00:00Z",
+			"expires_at":"0001-01-01T00:00:00Z"
+		}`
+
+	testJSONMarshal(t, g, want)
+}
diff --git a/github/users_keys_test.go b/github/users_keys_test.go
index 14effc1b..b3e5fc9e 100644
--- a/github/users_keys_test.go
+++ b/github/users_keys_test.go
@@ -180,3 +180,29 @@ func TestUsersService_DeleteKey(t *testing.T) {
 		return client.Users.DeleteKey(ctx, 1)
 	})
 }
+
+func TestKey_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Key{}, "{}")
+
+	u := &Key{
+		ID:        Int64(1),
+		Key:       String("abc"),
+		URL:       String("url"),
+		Title:     String("title"),
+		ReadOnly:  Bool(true),
+		Verified:  Bool(true),
+		CreatedAt: &Timestamp{referenceTime},
+	}
+
+	want := `{
+		"id": 1,
+		"key": "abc",
+		"url": "url",
+		"title": "title",
+		"read_only": true,
+		"verified": true,
+		"created_at": ` + referenceTimeStr + `
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/github/users_packages_test.go b/github/users_packages_test.go
index 5be7def1..41e7698a 100644
--- a/github/users_packages_test.go
+++ b/github/users_packages_test.go
@@ -74,7 +74,7 @@ func TestUsersService_specifiedUser_ListPackages(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
 
-	mux.HandleFunc("/user/u/packages", func(w http.ResponseWriter, r *http.Request) {
+	mux.HandleFunc("/users/u/packages", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, "GET")
 		testFormValues(t, r, values{"package_type": "container", "visibility": "public"})
 		fmt.Fprint(w, `[{
diff --git a/github/users_projects_test.go b/github/users_projects_test.go
index 4f4b5e26..28c46107 100644
--- a/github/users_projects_test.go
+++ b/github/users_projects_test.go
@@ -92,3 +92,19 @@ func TestUsersService_CreateProject(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestCreateUserProjectOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &CreateUserProjectOptions{}, `{}`)
+
+	c := CreateUserProjectOptions{
+		Name: "SomeProject",
+		Body: String("SomeProjectBody"),
+	}
+
+	want := `{
+			"name": "SomeProject",
+			"body": "SomeProjectBody"
+		}`
+
+	testJSONMarshal(t, c, want)
+}
diff --git a/github/users_test.go b/github/users_test.go
index 4d7b6fad..8acd529c 100644
--- a/github/users_test.go
+++ b/github/users_test.go
@@ -367,3 +367,63 @@ func TestUsersService_DeclineInvitation(t *testing.T) {
 		return client.Users.DeclineInvitation(ctx, 1)
 	})
 }
+
+func TestUserContext_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserContext{}, "{}")
+
+	u := &UserContext{
+		Message: String("message"),
+		Octicon: String("message"),
+	}
+
+	want := `{
+		"message" : "message",
+		"octicon" : "message"
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
+func TestHovercard_Marshal(t *testing.T) {
+	testJSONMarshal(t, &Hovercard{}, "{}")
+
+	h := &Hovercard{
+		Contexts: []*UserContext{
+			{
+				Message: String("someMessage"),
+				Octicon: String("someOcticon"),
+			},
+		},
+	}
+
+	want := `{
+		"contexts" : [
+			{
+				"message" : "someMessage",
+				"octicon" : "someOcticon"
+			}
+		]
+	}`
+
+	testJSONMarshal(t, h, want)
+}
+
+func TestUserListOptions_Marshal(t *testing.T) {
+	testJSONMarshal(t, &UserListOptions{}, "{}")
+
+	u := &UserListOptions{
+		Since: int64(1900),
+		ListOptions: ListOptions{
+			Page:    int(1),
+			PerPage: int(10),
+		},
+	}
+
+	want := `{
+		"since" : 1900,
+		"page": 1,
+		"perPage": 10
+	}`
+
+	testJSONMarshal(t, u, want)
+}
diff --git a/scrape/apps_test.go b/scrape/apps_test.go
index 7987c8f5..88640879 100644
--- a/scrape/apps_test.go
+++ b/scrape/apps_test.go
@@ -5,7 +5,7 @@ import (
 	"testing"
 
 	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-github/v32/github"
+	"github.com/google/go-github/v39/github"
 )
 
 func Test_AppRestrictionsEnabled(t *testing.T) {