Repository: google/go-github
Pull request #3051 (2024-01-16 14:06:10)

Fix leaked client transport on copy
Fixes: #3043.

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
Attention: `3 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`9231a0f`)](https://app.codecov.io/gh/google/go-github/commit/9231a0f0bc205f0535a29361d773a77da5e39294?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) 97.71% compared to head [(`9424530`)](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) 97.69%.
> Report is 2 commits behind head on master.

| [Files](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Patch % | Lines |
|---|---|---|
| [github/code-scanning.go](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL2NvZGUtc2Nhbm5pbmcuZ28=) | 75.00% | [2 Missing and 1 partial :warning: ](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3051      +/-   ##
==========================================
- Coverage   97.71%   97.69%   -0.03%     
==========================================
  Files         152      152              
  Lines       13241    13253      +12     
==========================================
+ Hits        12939    12948       +9     
- Misses        213      215       +2     
- Partials       89       90       +1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/google/go-github/pull/3051?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google).

gmlewis: Awaiting LGTM+Approval before merging.

Patch:
diff --git a/github/actions_permissions_enterprise.go b/github/actions_permissions_enterprise.go
index 7e10444a..a6a85aa3 100644
--- a/github/actions_permissions_enterprise.go
+++ b/github/actions_permissions_enterprise.go
@@ -29,6 +29,14 @@ func (a ActionsPermissionsEnterprise) String() string {
 	return Stringify(a)
 }
 
+// DefaultWorkflowPermissionEnterprise represents the default permissions for GitHub Actions workflows for an enterprise.
+//
+// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/permissions
+type DefaultWorkflowPermissionEnterprise struct {
+	DefaultWorkflowPermissions   *string `json:"default_workflow_permissions,omitempty"`
+	CanApprovePullRequestReviews *bool   `json:"can_approve_pull_request_reviews,omitempty"`
+}
+
 // GetActionsPermissionsInEnterprise gets the GitHub Actions permissions policy for an enterprise.
 //
 // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/permissions#get-github-actions-permissions-for-an-enterprise
@@ -205,3 +213,46 @@ func (s *ActionsService) EditActionsAllowedInEnterprise(ctx context.Context, ent
 
 	return p, resp, nil
 }
+
+// GetDefaultWorkflowPermissionsInEnterprise gets the GitHub Actions default workflow permissions for an enterprise.
+//
+// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/permissions#get-default-workflow-permissions-for-an-enterprise
+//
+//meta:operation GET /enterprises/{enterprise}/actions/permissions/workflow
+func (s *ActionsService) GetDefaultWorkflowPermissionsInEnterprise(ctx context.Context, enterprise string) (*DefaultWorkflowPermissionEnterprise, *Response, error) {
+	u := fmt.Sprintf("enterprises/%v/actions/permissions/workflow", enterprise)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	permissions := new(DefaultWorkflowPermissionEnterprise)
+	resp, err := s.client.Do(ctx, req, permissions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return permissions, resp, nil
+}
+
+// EditDefaultWorkflowPermissionsInEnterprise sets the GitHub Actions default workflow permissions for an enterprise.
+//
+// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/actions/permissions#set-default-workflow-permissions-for-an-enterprise
+//
+//meta:operation PUT /enterprises/{enterprise}/actions/permissions/workflow
+func (s *ActionsService) EditDefaultWorkflowPermissionsInEnterprise(ctx context.Context, enterprise string, permissions DefaultWorkflowPermissionEnterprise) (*DefaultWorkflowPermissionEnterprise, *Response, error) {
+	u := fmt.Sprintf("enterprises/%v/actions/permissions/workflow", enterprise)
+	req, err := s.client.NewRequest("PUT", u, permissions)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	p := new(DefaultWorkflowPermissionEnterprise)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
diff --git a/github/actions_permissions_orgs.go b/github/actions_permissions_orgs.go
index 1a31e4c6..2f555f24 100644
--- a/github/actions_permissions_orgs.go
+++ b/github/actions_permissions_orgs.go
@@ -42,6 +42,14 @@ func (a ActionsAllowed) String() string {
 	return Stringify(a)
 }
 
+// DefaultWorkflowPermissionOrganization represents the default permissions for GitHub Actions workflows for an organization.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions
+type DefaultWorkflowPermissionOrganization struct {
+	DefaultWorkflowPermissions   *string `json:"default_workflow_permissions,omitempty"`
+	CanApprovePullRequestReviews *bool   `json:"can_approve_pull_request_reviews,omitempty"`
+}
+
 // GetActionsPermissions gets the GitHub Actions permissions policy for repositories and allowed actions in an organization.
 //
 // GitHub API docs: https://docs.github.com/rest/actions/permissions#get-github-actions-permissions-for-an-organization
@@ -218,3 +226,46 @@ func (s *ActionsService) EditActionsAllowed(ctx context.Context, org string, act
 
 	return p, resp, nil
 }
+
+// GetDefaultWorkflowPermissionsInOrganization gets the GitHub Actions default workflow permissions for an organization.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions#get-default-workflow-permissions-for-an-organization
+//
+//meta:operation GET /orgs/{org}/actions/permissions/workflow
+func (s *ActionsService) GetDefaultWorkflowPermissionsInOrganization(ctx context.Context, org string) (*DefaultWorkflowPermissionOrganization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/actions/permissions/workflow", org)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	permissions := new(DefaultWorkflowPermissionOrganization)
+	resp, err := s.client.Do(ctx, req, permissions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return permissions, resp, nil
+}
+
+// EditDefaultWorkflowPermissionsInOrganization sets the GitHub Actions default workflow permissions for an organization.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions#set-default-workflow-permissions-for-an-organization
+//
+//meta:operation PUT /orgs/{org}/actions/permissions/workflow
+func (s *ActionsService) EditDefaultWorkflowPermissionsInOrganization(ctx context.Context, org string, permissions DefaultWorkflowPermissionOrganization) (*DefaultWorkflowPermissionOrganization, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/actions/permissions/workflow", org)
+	req, err := s.client.NewRequest("PUT", u, permissions)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	p := new(DefaultWorkflowPermissionOrganization)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}
diff --git a/github/actions_secrets.go b/github/actions_secrets.go
index 2d4ba98d..d8d405c0 100644
--- a/github/actions_secrets.go
+++ b/github/actions_secrets.go
@@ -138,6 +138,17 @@ func (s *ActionsService) ListRepoSecrets(ctx context.Context, owner, repo string
 	return s.listSecrets(ctx, url, opts)
 }
 
+// ListRepoOrgSecrets lists all organization secrets available in a repository
+// without revealing their encrypted values.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/secrets#list-repository-organization-secrets
+//
+//meta:operation GET /repos/{owner}/{repo}/actions/organization-secrets
+func (s *ActionsService) ListRepoOrgSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) {
+	url := fmt.Sprintf("repos/%v/%v/actions/organization-secrets", owner, repo)
+	return s.listSecrets(ctx, url, opts)
+}
+
 // ListOrgSecrets lists all secrets available in an organization
 // without revealing their encrypted values.
 //
diff --git a/github/actions_variables.go b/github/actions_variables.go
index 244d1590..aa0f23ca 100644
--- a/github/actions_variables.go
+++ b/github/actions_variables.go
@@ -59,6 +59,16 @@ func (s *ActionsService) ListRepoVariables(ctx context.Context, owner, repo stri
 	return s.listVariables(ctx, url, opts)
 }
 
+// ListRepoOrgVariables lists all organization variables available in a repository.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/variables#list-repository-organization-variables
+//
+//meta:operation GET /repos/{owner}/{repo}/actions/organization-variables
+func (s *ActionsService) ListRepoOrgVariables(ctx context.Context, owner, repo string, opts *ListOptions) (*ActionsVariables, *Response, error) {
+	url := fmt.Sprintf("repos/%v/%v/actions/organization-variables", owner, repo)
+	return s.listVariables(ctx, url, opts)
+}
+
 // ListOrgVariables lists all variables available in an organization.
 //
 // GitHub API docs: https://docs.github.com/rest/actions/variables#list-organization-variables
diff --git a/github/event_types.go b/github/event_types.go
index db7c7c69..56db9f5b 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -394,6 +394,7 @@ type EditChange struct {
 	Repo          *EditRepo          `json:"repository,omitempty"`
 	Owner         *EditOwner         `json:"owner,omitempty"`
 	DefaultBranch *EditDefaultBranch `json:"default_branch,omitempty"`
+	Topics        *EditTopics        `json:"topics,omitempty"`
 }
 
 // EditTitle represents a pull-request title change.
@@ -438,6 +439,11 @@ type RepoName struct {
 	From *string `json:"from,omitempty"`
 }
 
+// EditTopics represents a change of repository topics.
+type EditTopics struct {
+	From []string `json:"from,omitempty"`
+}
+
 // EditSHA represents a sha change of a pull-request.
 type EditSHA struct {
 	From *string `json:"from,omitempty"`
diff --git a/github/github-accessors.go b/github/github-accessors.go
index 256bfacf..6d32908c 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -4686,6 +4686,54 @@ func (d *DefaultSetupConfiguration) GetUpdatedAt() Timestamp {
 	return *d.UpdatedAt
 }
 
+// GetCanApprovePullRequestReviews returns the CanApprovePullRequestReviews field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionEnterprise) GetCanApprovePullRequestReviews() bool {
+	if d == nil || d.CanApprovePullRequestReviews == nil {
+		return false
+	}
+	return *d.CanApprovePullRequestReviews
+}
+
+// GetDefaultWorkflowPermissions returns the DefaultWorkflowPermissions field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionEnterprise) GetDefaultWorkflowPermissions() string {
+	if d == nil || d.DefaultWorkflowPermissions == nil {
+		return ""
+	}
+	return *d.DefaultWorkflowPermissions
+}
+
+// GetCanApprovePullRequestReviews returns the CanApprovePullRequestReviews field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionOrganization) GetCanApprovePullRequestReviews() bool {
+	if d == nil || d.CanApprovePullRequestReviews == nil {
+		return false
+	}
+	return *d.CanApprovePullRequestReviews
+}
+
+// GetDefaultWorkflowPermissions returns the DefaultWorkflowPermissions field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionOrganization) GetDefaultWorkflowPermissions() string {
+	if d == nil || d.DefaultWorkflowPermissions == nil {
+		return ""
+	}
+	return *d.DefaultWorkflowPermissions
+}
+
+// GetCanApprovePullRequestReviews returns the CanApprovePullRequestReviews field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionRepository) GetCanApprovePullRequestReviews() bool {
+	if d == nil || d.CanApprovePullRequestReviews == nil {
+		return false
+	}
+	return *d.CanApprovePullRequestReviews
+}
+
+// GetDefaultWorkflowPermissions returns the DefaultWorkflowPermissions field if it's non-nil, zero value otherwise.
+func (d *DefaultWorkflowPermissionRepository) GetDefaultWorkflowPermissions() string {
+	if d == nil || d.DefaultWorkflowPermissions == nil {
+		return ""
+	}
+	return *d.DefaultWorkflowPermissions
+}
+
 // GetConfirmDeleteURL returns the ConfirmDeleteURL field if it's non-nil, zero value otherwise.
 func (d *DeleteAnalysis) GetConfirmDeleteURL() string {
 	if d == nil || d.ConfirmDeleteURL == nil {
@@ -6310,6 +6358,14 @@ func (e *EditChange) GetTitle() *EditTitle {
 	return e.Title
 }
 
+// GetTopics returns the Topics field.
+func (e *EditChange) GetTopics() *EditTopics {
+	if e == nil {
+		return nil
+	}
+	return e.Topics
+}
+
 // GetFrom returns the From field if it's non-nil, zero value otherwise.
 func (e *EditDefaultBranch) GetFrom() string {
 	if e == nil || e.From == nil {
@@ -16262,6 +16318,14 @@ func (p *PullRequestLinks) GetHTMLURL() string {
 	return *p.HTMLURL
 }
 
+// GetMergedAt returns the MergedAt field if it's non-nil, zero value otherwise.
+func (p *PullRequestLinks) GetMergedAt() Timestamp {
+	if p == nil || p.MergedAt == nil {
+		return Timestamp{}
+	}
+	return *p.MergedAt
+}
+
 // GetPatchURL returns the PatchURL field if it's non-nil, zero value otherwise.
 func (p *PullRequestLinks) GetPatchURL() string {
 	if p == nil || p.PatchURL == nil {
diff --git a/github/github.go b/github/github.go
index 8bc35e5e..a7326a7b 100644
--- a/github/github.go
+++ b/github/github.go
@@ -450,15 +450,18 @@ func (c *Client) copy() *Client {
 	c.clientMu.Lock()
 	// can't use *c here because that would copy mutexes by value.
 	clone := Client{
-		client:                  c.client,
+		client:                  &http.Client{},
 		UserAgent:               c.UserAgent,
 		BaseURL:                 c.BaseURL,
 		UploadURL:               c.UploadURL,
 		secondaryRateLimitReset: c.secondaryRateLimitReset,
 	}
 	c.clientMu.Unlock()
-	if clone.client == nil {
-		clone.client = &http.Client{}
+	if c.client != nil {
+		clone.client.Transport = c.client.Transport
+		clone.client.CheckRedirect = c.client.CheckRedirect
+		clone.client.Jar = c.client.Jar
+		clone.client.Timeout = c.client.Timeout
 	}
 	c.rateMu.Lock()
 	copy(clone.rateLimits[:], c.rateLimits[:])
diff --git a/github/issues.go b/github/issues.go
index 1c07fef8..a2652b34 100644
--- a/github/issues.go
+++ b/github/issues.go
@@ -122,10 +122,11 @@ type IssueListOptions struct {
 // PullRequestLinks object is added to the Issue object when it's an issue included
 // in the IssueCommentEvent webhook payload, if the webhook is fired by a comment on a PR.
 type PullRequestLinks struct {
-	URL      *string `json:"url,omitempty"`
-	HTMLURL  *string `json:"html_url,omitempty"`
-	DiffURL  *string `json:"diff_url,omitempty"`
-	PatchURL *string `json:"patch_url,omitempty"`
+	URL      *string    `json:"url,omitempty"`
+	HTMLURL  *string    `json:"html_url,omitempty"`
+	DiffURL  *string    `json:"diff_url,omitempty"`
+	PatchURL *string    `json:"patch_url,omitempty"`
+	MergedAt *Timestamp `json:"merged_at,omitempty"`
 }
 
 // List the issues for the authenticated user. If all is true, list issues
diff --git a/github/repos_actions_permissions.go b/github/repos_actions_permissions.go
index 2dcc367d..9abd32a7 100644
--- a/github/repos_actions_permissions.go
+++ b/github/repos_actions_permissions.go
@@ -23,6 +23,14 @@ func (a ActionsPermissionsRepository) String() string {
 	return Stringify(a)
 }
 
+// DefaultWorkflowPermissionRepository represents the default permissions for GitHub Actions workflows for a repository.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions
+type DefaultWorkflowPermissionRepository struct {
+	DefaultWorkflowPermissions   *string `json:"default_workflow_permissions,omitempty"`
+	CanApprovePullRequestReviews *bool   `json:"can_approve_pull_request_reviews,omitempty"`
+}
+
 // GetActionsPermissions gets the GitHub Actions permissions policy for repositories and allowed actions in a repository.
 //
 // GitHub API docs: https://docs.github.com/rest/actions/permissions#get-github-actions-permissions-for-a-repository
@@ -30,6 +38,7 @@ func (a ActionsPermissionsRepository) String() string {
 //meta:operation GET /repos/{owner}/{repo}/actions/permissions
 func (s *RepositoriesService) GetActionsPermissions(ctx context.Context, owner, repo string) (*ActionsPermissionsRepository, *Response, error) {
 	u := fmt.Sprintf("repos/%v/%v/actions/permissions", owner, repo)
+
 	req, err := s.client.NewRequest("GET", u, nil)
 	if err != nil {
 		return nil, nil, err
@@ -64,3 +73,46 @@ func (s *RepositoriesService) EditActionsPermissions(ctx context.Context, owner,
 
 	return permissions, resp, nil
 }
+
+// GetDefaultWorkflowPermissions gets the GitHub Actions default workflow permissions in a repository.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions#get-default-workflow-permissions-for-a-repository
+//
+//meta:operation GET /repos/{owner}/{repo}/actions/permissions/workflow
+func (s *RepositoriesService) GetDefaultWorkflowPermissions(ctx context.Context, owner, repo string) (*DefaultWorkflowPermissionRepository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/actions/permissions/workflow", owner, repo)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	permissions := new(DefaultWorkflowPermissionRepository)
+	resp, err := s.client.Do(ctx, req, permissions)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return permissions, resp, nil
+}
+
+// EditDefaultWorkflowPermissions sets the GitHub Actions default workflow permissions in a repository.
+//
+// GitHub API docs: https://docs.github.com/rest/actions/permissions#set-default-workflow-permissions-for-a-repository
+//
+//meta:operation PUT /repos/{owner}/{repo}/actions/permissions/workflow
+func (s *RepositoriesService) EditDefaultWorkflowPermissions(ctx context.Context, owner, repo string, permissions DefaultWorkflowPermissionRepository) (*DefaultWorkflowPermissionRepository, *Response, error) {
+	u := fmt.Sprintf("repos/%v/%v/actions/permissions/workflow", owner, repo)
+	req, err := s.client.NewRequest("PUT", u, permissions)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	p := new(DefaultWorkflowPermissionRepository)
+	resp, err := s.client.Do(ctx, req, p)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return p, resp, nil
+}


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 3067b1b0..78305423 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -51,7 +51,7 @@ jobs:
         echo "go-mod-cache=$(go env GOMODCACHE)" >> $GITHUB_OUTPUT
 
     - name: Cache go modules
-      uses: actions/cache@v3
+      uses: actions/cache@v4
       with:
         path: |
           ${{ steps.cache-paths.outputs.go-cache }}
diff --git a/github/actions_permissions_enterprise_test.go b/github/actions_permissions_enterprise_test.go
index 14e8e3a6..70f7d2c0 100644
--- a/github/actions_permissions_enterprise_test.go
+++ b/github/actions_permissions_enterprise_test.go
@@ -296,3 +296,80 @@ func TestActionsService_EditActionsAllowedInEnterprise(t *testing.T) {
 		return resp, err
 	})
 }
+
+func TestActionsService_GetDefaultWorkflowPermissionsInEnterprise(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/enterprises/e/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	ent, _, err := client.Actions.GetDefaultWorkflowPermissionsInEnterprise(ctx, "e")
+	if err != nil {
+		t.Errorf("Actions.GetDefaultWorkflowPermissionsInEnterprise returned error: %v", err)
+	}
+	want := &DefaultWorkflowPermissionEnterprise{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(ent, want) {
+		t.Errorf("Actions.GetDefaultWorkflowPermissionsInEnterprise returned %+v, want %+v", ent, want)
+	}
+
+	const methodName = "GetDefaultWorkflowPermissionsInEnterprise"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.GetDefaultWorkflowPermissionsInEnterprise(ctx, "\n")
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.GetDefaultWorkflowPermissionsInEnterprise(ctx, "e")
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
+func TestActionsService_EditDefaultWorkflowPermissionsInEnterprise(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+	input := &DefaultWorkflowPermissionEnterprise{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+
+	mux.HandleFunc("/enterprises/e/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		v := new(DefaultWorkflowPermissionEnterprise)
+		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
+
+		testMethod(t, r, "PUT")
+		if !cmp.Equal(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	ent, _, err := client.Actions.EditDefaultWorkflowPermissionsInEnterprise(ctx, "e", *input)
+	if err != nil {
+		t.Errorf("Actions.EditDefaultWorkflowPermissionsInEnterprise returned error: %v", err)
+	}
+
+	want := &DefaultWorkflowPermissionEnterprise{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(ent, want) {
+		t.Errorf("Actions.EditDefaultWorkflowPermissionsInEnterprise returned %+v, want %+v", ent, want)
+	}
+
+	const methodName = "EditDefaultWorkflowPermissionsInEnterprise"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.EditDefaultWorkflowPermissionsInEnterprise(ctx, "\n", *input)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.EditDefaultWorkflowPermissionsInEnterprise(ctx, "e", *input)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
diff --git a/github/actions_permissions_orgs_test.go b/github/actions_permissions_orgs_test.go
index 36a241f6..fd35c519 100644
--- a/github/actions_permissions_orgs_test.go
+++ b/github/actions_permissions_orgs_test.go
@@ -334,3 +334,80 @@ func TestActionsPermissions_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestActionsService_GetDefaultWorkflowPermissionsInOrganization(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	org, _, err := client.Actions.GetDefaultWorkflowPermissionsInOrganization(ctx, "o")
+	if err != nil {
+		t.Errorf("Actions.GetDefaultWorkflowPermissionsInOrganization returned error: %v", err)
+	}
+	want := &DefaultWorkflowPermissionOrganization{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(org, want) {
+		t.Errorf("Actions.GetDefaultWorkflowPermissionsInOrganization returned %+v, want %+v", org, want)
+	}
+
+	const methodName = "GetDefaultWorkflowPermissionsInOrganization"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.GetDefaultWorkflowPermissionsInOrganization(ctx, "\n")
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.GetDefaultWorkflowPermissionsInOrganization(ctx, "o")
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
+func TestActionsService_EditDefaultWorkflowPermissionsInOrganization(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+	input := &DefaultWorkflowPermissionOrganization{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+
+	mux.HandleFunc("/orgs/o/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		v := new(DefaultWorkflowPermissionOrganization)
+		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
+
+		testMethod(t, r, "PUT")
+		if !cmp.Equal(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	org, _, err := client.Actions.EditDefaultWorkflowPermissionsInOrganization(ctx, "o", *input)
+	if err != nil {
+		t.Errorf("Actions.EditDefaultWorkflowPermissionsInOrganization returned error: %v", err)
+	}
+
+	want := &DefaultWorkflowPermissionOrganization{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(org, want) {
+		t.Errorf("Actions.EditDefaultWorkflowPermissionsInOrganization returned %+v, want %+v", org, want)
+	}
+
+	const methodName = "EditDefaultWorkflowPermissionsInOrganization"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.EditDefaultWorkflowPermissionsInOrganization(ctx, "\n", *input)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.EditDefaultWorkflowPermissionsInOrganization(ctx, "o", *input)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
diff --git a/github/actions_secrets_test.go b/github/actions_secrets_test.go
index a1266d6b..a2ac169c 100644
--- a/github/actions_secrets_test.go
+++ b/github/actions_secrets_test.go
@@ -205,6 +205,49 @@ func TestActionsService_ListRepoSecrets(t *testing.T) {
 	})
 }
 
+func TestActionsService_ListRepoOrgSecrets(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/actions/organization-secrets", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{"per_page": "2", "page": "2"})
+		fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`)
+	})
+
+	opts := &ListOptions{Page: 2, PerPage: 2}
+	ctx := context.Background()
+	secrets, _, err := client.Actions.ListRepoOrgSecrets(ctx, "o", "r", opts)
+	if err != nil {
+		t.Errorf("Actions.ListRepoOrgSecrets returned error: %v", err)
+	}
+
+	want := &Secrets{
+		TotalCount: 4,
+		Secrets: []*Secret{
+			{Name: "A", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
+			{Name: "B", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
+		},
+	}
+	if !cmp.Equal(secrets, want) {
+		t.Errorf("Actions.ListRepoOrgSecrets returned %+v, want %+v", secrets, want)
+	}
+
+	const methodName = "ListRepoOrgSecrets"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.ListRepoOrgSecrets(ctx, "\n", "\n", opts)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.ListRepoOrgSecrets(ctx, "o", "r", opts)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestActionsService_GetRepoSecret(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/actions_variables_test.go b/github/actions_variables_test.go
index a9f773c2..dcd648c2 100644
--- a/github/actions_variables_test.go
+++ b/github/actions_variables_test.go
@@ -58,6 +58,49 @@ func TestActionsService_ListRepoVariables(t *testing.T) {
 	})
 }
 
+func TestActionsService_ListRepoOrgVariables(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/actions/organization-variables", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		testFormValues(t, r, values{"per_page": "2", "page": "2"})
+		fmt.Fprint(w, `{"total_count":4,"variables":[{"name":"A","value":"AA","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","value":"BB","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`)
+	})
+
+	opts := &ListOptions{Page: 2, PerPage: 2}
+	ctx := context.Background()
+	variables, _, err := client.Actions.ListRepoOrgVariables(ctx, "o", "r", opts)
+	if err != nil {
+		t.Errorf("Actions.ListRepoOrgVariables returned error: %v", err)
+	}
+
+	want := &ActionsVariables{
+		TotalCount: 4,
+		Variables: []*ActionsVariable{
+			{Name: "A", Value: "AA", CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
+			{Name: "B", Value: "BB", CreatedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
+		},
+	}
+	if !cmp.Equal(variables, want) {
+		t.Errorf("Actions.ListRepoOrgVariables returned %+v, want %+v", variables, want)
+	}
+
+	const methodName = "ListRepoOrgVariables"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Actions.ListRepoOrgVariables(ctx, "\n", "\n", opts)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Actions.ListRepoOrgVariables(ctx, "o", "r", opts)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
 func TestActionsService_GetRepoVariable(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()
diff --git a/github/event_types_test.go b/github/event_types_test.go
index 80eca61d..8578b922 100644
--- a/github/event_types_test.go
+++ b/github/event_types_test.go
@@ -91,6 +91,9 @@ func TestEditChange_Marshal_Repo(t *testing.T) {
 				From: String("old-repo-name"),
 			},
 		},
+		Topics: &EditTopics{
+			From: []string{"topic1", "topic2"},
+		},
 	}
 
 	want := `{
@@ -98,6 +101,12 @@ func TestEditChange_Marshal_Repo(t *testing.T) {
 			"name": {
 				"from": "old-repo-name"
 			}
+		},
+		"topics": {
+			"from": [
+				"topic1",
+				"topic2"
+			]
 		}
 	}`
 
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 461ce8ed..5856cc7a 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -5519,6 +5519,66 @@ func TestDefaultSetupConfiguration_GetUpdatedAt(tt *testing.T) {
 	d.GetUpdatedAt()
 }
 
+func TestDefaultWorkflowPermissionEnterprise_GetCanApprovePullRequestReviews(tt *testing.T) {
+	var zeroValue bool
+	d := &DefaultWorkflowPermissionEnterprise{CanApprovePullRequestReviews: &zeroValue}
+	d.GetCanApprovePullRequestReviews()
+	d = &DefaultWorkflowPermissionEnterprise{}
+	d.GetCanApprovePullRequestReviews()
+	d = nil
+	d.GetCanApprovePullRequestReviews()
+}
+
+func TestDefaultWorkflowPermissionEnterprise_GetDefaultWorkflowPermissions(tt *testing.T) {
+	var zeroValue string
+	d := &DefaultWorkflowPermissionEnterprise{DefaultWorkflowPermissions: &zeroValue}
+	d.GetDefaultWorkflowPermissions()
+	d = &DefaultWorkflowPermissionEnterprise{}
+	d.GetDefaultWorkflowPermissions()
+	d = nil
+	d.GetDefaultWorkflowPermissions()
+}
+
+func TestDefaultWorkflowPermissionOrganization_GetCanApprovePullRequestReviews(tt *testing.T) {
+	var zeroValue bool
+	d := &DefaultWorkflowPermissionOrganization{CanApprovePullRequestReviews: &zeroValue}
+	d.GetCanApprovePullRequestReviews()
+	d = &DefaultWorkflowPermissionOrganization{}
+	d.GetCanApprovePullRequestReviews()
+	d = nil
+	d.GetCanApprovePullRequestReviews()
+}
+
+func TestDefaultWorkflowPermissionOrganization_GetDefaultWorkflowPermissions(tt *testing.T) {
+	var zeroValue string
+	d := &DefaultWorkflowPermissionOrganization{DefaultWorkflowPermissions: &zeroValue}
+	d.GetDefaultWorkflowPermissions()
+	d = &DefaultWorkflowPermissionOrganization{}
+	d.GetDefaultWorkflowPermissions()
+	d = nil
+	d.GetDefaultWorkflowPermissions()
+}
+
+func TestDefaultWorkflowPermissionRepository_GetCanApprovePullRequestReviews(tt *testing.T) {
+	var zeroValue bool
+	d := &DefaultWorkflowPermissionRepository{CanApprovePullRequestReviews: &zeroValue}
+	d.GetCanApprovePullRequestReviews()
+	d = &DefaultWorkflowPermissionRepository{}
+	d.GetCanApprovePullRequestReviews()
+	d = nil
+	d.GetCanApprovePullRequestReviews()
+}
+
+func TestDefaultWorkflowPermissionRepository_GetDefaultWorkflowPermissions(tt *testing.T) {
+	var zeroValue string
+	d := &DefaultWorkflowPermissionRepository{DefaultWorkflowPermissions: &zeroValue}
+	d.GetDefaultWorkflowPermissions()
+	d = &DefaultWorkflowPermissionRepository{}
+	d.GetDefaultWorkflowPermissions()
+	d = nil
+	d.GetDefaultWorkflowPermissions()
+}
+
 func TestDeleteAnalysis_GetConfirmDeleteURL(tt *testing.T) {
 	var zeroValue string
 	d := &DeleteAnalysis{ConfirmDeleteURL: &zeroValue}
@@ -7354,6 +7414,13 @@ func TestEditChange_GetTitle(tt *testing.T) {
 	e.GetTitle()
 }
 
+func TestEditChange_GetTopics(tt *testing.T) {
+	e := &EditChange{}
+	e.GetTopics()
+	e = nil
+	e.GetTopics()
+}
+
 func TestEditDefaultBranch_GetFrom(tt *testing.T) {
 	var zeroValue string
 	e := &EditDefaultBranch{From: &zeroValue}
@@ -18864,6 +18931,16 @@ func TestPullRequestLinks_GetHTMLURL(tt *testing.T) {
 	p.GetHTMLURL()
 }
 
+func TestPullRequestLinks_GetMergedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	p := &PullRequestLinks{MergedAt: &zeroValue}
+	p.GetMergedAt()
+	p = &PullRequestLinks{}
+	p.GetMergedAt()
+	p = nil
+	p.GetMergedAt()
+}
+
 func TestPullRequestLinks_GetPatchURL(tt *testing.T) {
 	var zeroValue string
 	p := &PullRequestLinks{PatchURL: &zeroValue}
diff --git a/github/github_test.go b/github/github_test.go
index 45ac57c0..9a369a25 100644
--- a/github/github_test.go
+++ b/github/github_test.go
@@ -2599,3 +2599,32 @@ func TestParseTokenExpiration(t *testing.T) {
 		}
 	}
 }
+
+func TestClientCopy_leak_transport(t *testing.T) {
+	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-Type", "application/json")
+		accessToken := r.Header.Get("Authorization")
+		_, _ = fmt.Fprintf(w, `{"login": "%s"}`, accessToken)
+	}))
+	clientPreconfiguredWithURLs, err := NewClient(nil).WithEnterpriseURLs(srv.URL, srv.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	aliceClient := clientPreconfiguredWithURLs.WithAuthToken("alice")
+	bobClient := clientPreconfiguredWithURLs.WithAuthToken("bob")
+
+	alice, _, err := aliceClient.Users.Get(context.Background(), "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	assertNoDiff(t, "Bearer alice", alice.GetLogin())
+
+	bob, _, err := bobClient.Users.Get(context.Background(), "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	assertNoDiff(t, "Bearer bob", bob.GetLogin())
+}
diff --git a/github/issues_test.go b/github/issues_test.go
index aa767d65..d64ef88d 100644
--- a/github/issues_test.go
+++ b/github/issues_test.go
@@ -499,13 +499,15 @@ func TestPullRequestLinks_Marshal(t *testing.T) {
 		HTMLURL:  String("hurl"),
 		DiffURL:  String("durl"),
 		PatchURL: String("purl"),
+		MergedAt: &Timestamp{referenceTime},
 	}
 
 	want := `{
 		"url": "url",
 		"html_url": "hurl",
 		"diff_url": "durl",
-		"patch_url": "purl"
+		"patch_url": "purl",
+		"merged_at": ` + referenceTimeStr + `
 		}`
 
 	testJSONMarshal(t, u, want)
diff --git a/github/repos_actions_permissions_test.go b/github/repos_actions_permissions_test.go
index ecff0d5f..9959a6e7 100644
--- a/github/repos_actions_permissions_test.go
+++ b/github/repos_actions_permissions_test.go
@@ -110,3 +110,81 @@ func TestActionsPermissionsRepository_Marshal(t *testing.T) {
 
 	testJSONMarshal(t, u, want)
 }
+
+func TestRepositoriesService_GetDefaultWorkflowPermissions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/repos/o/r/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	org, _, err := client.Repositories.GetDefaultWorkflowPermissions(ctx, "o", "r")
+	if err != nil {
+		t.Errorf("Repositories.GetDefaultWorkflowPermissions returned error: %v", err)
+	}
+	want := &DefaultWorkflowPermissionRepository{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(org, want) {
+		t.Errorf("Repositories.GetDefaultWorkflowPermissions returned %+v, want %+v", org, want)
+	}
+
+	const methodName = "GetDefaultWorkflowPermissions"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.GetDefaultWorkflowPermissions(ctx, "\n", "\n")
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Repositories.GetDefaultWorkflowPermissions(ctx, "o", "r")
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
+func TestRepositoriesService_EditDefaultWorkflowPermissions(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	input := &DefaultWorkflowPermissionRepository{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+
+	mux.HandleFunc("/repos/o/r/actions/permissions/workflow", func(w http.ResponseWriter, r *http.Request) {
+		v := new(DefaultWorkflowPermissionRepository)
+		assertNilError(t, json.NewDecoder(r.Body).Decode(v))
+
+		testMethod(t, r, "PUT")
+		if !cmp.Equal(v, input) {
+			t.Errorf("Request body = %+v, want %+v", v, input)
+		}
+
+		fmt.Fprint(w, `{ "default_workflow_permissions": "read", "can_approve_pull_request_reviews": true }`)
+	})
+
+	ctx := context.Background()
+	org, _, err := client.Repositories.EditDefaultWorkflowPermissions(ctx, "o", "r", *input)
+	if err != nil {
+		t.Errorf("Repositories.EditDefaultWorkflowPermissions returned error: %v", err)
+	}
+
+	want := &DefaultWorkflowPermissionRepository{DefaultWorkflowPermissions: String("read"), CanApprovePullRequestReviews: Bool(true)}
+	if !cmp.Equal(org, want) {
+		t.Errorf("Repositories.EditDefaultWorkflowPermissions returned %+v, want %+v", org, want)
+	}
+
+	const methodName = "EditDefaultWorkflowPermissions"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Repositories.EditDefaultWorkflowPermissions(ctx, "\n", "\n", *input)
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Repositories.EditDefaultWorkflowPermissions(ctx, "o", "r", *input)
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}