Repository: google/go-github
Pull request #1394 (2020-01-23 21:18:31)

Adding Node ID to contributor struct

codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/1394?src=pr&el=h1) Report
> Merging [#1394](https://codecov.io/gh/google/go-github/pull/1394?src=pr&el=desc) into [master](https://codecov.io/gh/google/go-github/commit/e7361de8ed67054f389e38e2af044c534037d849?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/google/go-github/pull/1394/graphs/tree.svg?width=650&token=EgYjGjZlI0&height=150&src=pr)](https://codecov.io/gh/google/go-github/pull/1394?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1394   +/-   ##
=======================================
  Coverage   73.21%   73.21%           
=======================================
  Files          88       88           
  Lines        6242     6242           
=======================================
  Hits         4570     4570           
  Misses        875      875           
  Partials      797      797
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/1394?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [github/repos.go](https://codecov.io/gh/google/go-github/pull/1394/diff?src=pr&el=tree#diff-Z2l0aHViL3JlcG9zLmdv) | `74.45% <ø> (ø)` | :arrow_up: |

------

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

willnorris: see test failures... looks like you need to `go fmt`?

Patch:
diff --git a/README.md b/README.md
index 8a496fb0..326cfe38 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # go-github #
 
-[![GoDoc](https://godoc.org/github.com/google/go-github/github?status.svg)](https://godoc.org/github.com/google/go-github/github)
+[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/google/go-github/v29/github)
 [![Test Status](https://github.com/google/go-github/workflows/tests/badge.svg)](https://github.com/google/go-github/actions?query=workflow%3Atests)
 [![Test Coverage](https://codecov.io/gh/google/go-github/branch/master/graph/badge.svg)](https://codecov.io/gh/google/go-github)
 [![Discuss at go-github@googlegroups.com](https://img.shields.io/badge/discuss-go--github%40googlegroups.com-blue.svg)](https://groups.google.com/group/go-github)
diff --git a/github/event_types.go b/github/event_types.go
index 4211f54b..4f537c8d 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -723,6 +723,8 @@ type PushEventRepository struct {
 	HasWiki         *bool      `json:"has_wiki,omitempty"`
 	HasPages        *bool      `json:"has_pages,omitempty"`
 	ForksCount      *int       `json:"forks_count,omitempty"`
+	Archived        *bool      `json:"archived,omitempty"`
+	Disabled        *bool      `json:"disabled,omitempty"`
 	OpenIssuesCount *int       `json:"open_issues_count,omitempty"`
 	DefaultBranch   *string    `json:"default_branch,omitempty"`
 	MasterBranch    *string    `json:"master_branch,omitempty"`
diff --git a/github/github-accessors.go b/github/github-accessors.go
index d069076d..72d200be 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -1940,6 +1940,14 @@ func (c *Contributor) GetLogin() string {
 	return *c.Login
 }
 
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *Contributor) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
 // GetOrganizationsURL returns the OrganizationsURL field if it's non-nil, zero value otherwise.
 func (c *Contributor) GetOrganizationsURL() string {
 	if c == nil || c.OrganizationsURL == nil {
@@ -7796,6 +7804,22 @@ func (p *ProjectPermissionLevel) GetUser() *User {
 	return p.User
 }
 
+// GetAllowDeletions returns the AllowDeletions field.
+func (p *Protection) GetAllowDeletions() *AllowDeletions {
+	if p == nil {
+		return nil
+	}
+	return p.AllowDeletions
+}
+
+// GetAllowForcePushes returns the AllowForcePushes field.
+func (p *Protection) GetAllowForcePushes() *AllowForcePushes {
+	if p == nil {
+		return nil
+	}
+	return p.AllowForcePushes
+}
+
 // GetEnforceAdmins returns the EnforceAdmins field.
 func (p *Protection) GetEnforceAdmins() *AdminEnforcement {
 	if p == nil {
@@ -7820,6 +7844,14 @@ func (p *Protection) GetRequiredStatusChecks() *RequiredStatusChecks {
 	return p.RequiredStatusChecks
 }
 
+// GetRequireLinearHistory returns the RequireLinearHistory field.
+func (p *Protection) GetRequireLinearHistory() *RequireLinearHistory {
+	if p == nil {
+		return nil
+	}
+	return p.RequireLinearHistory
+}
+
 // GetRestrictions returns the Restrictions field.
 func (p *Protection) GetRestrictions() *BranchRestrictions {
 	if p == nil {
@@ -7828,6 +7860,22 @@ func (p *Protection) GetRestrictions() *BranchRestrictions {
 	return p.Restrictions
 }
 
+// GetAllowDeletions returns the AllowDeletions field if it's non-nil, zero value otherwise.
+func (p *ProtectionRequest) GetAllowDeletions() bool {
+	if p == nil || p.AllowDeletions == nil {
+		return false
+	}
+	return *p.AllowDeletions
+}
+
+// GetAllowForcePushes returns the AllowForcePushes field if it's non-nil, zero value otherwise.
+func (p *ProtectionRequest) GetAllowForcePushes() bool {
+	if p == nil || p.AllowForcePushes == nil {
+		return false
+	}
+	return *p.AllowForcePushes
+}
+
 // GetRequiredPullRequestReviews returns the RequiredPullRequestReviews field.
 func (p *ProtectionRequest) GetRequiredPullRequestReviews() *PullRequestReviewsEnforcementRequest {
 	if p == nil {
@@ -7844,6 +7892,14 @@ func (p *ProtectionRequest) GetRequiredStatusChecks() *RequiredStatusChecks {
 	return p.RequiredStatusChecks
 }
 
+// GetRequireLinearHistory returns the RequireLinearHistory field if it's non-nil, zero value otherwise.
+func (p *ProtectionRequest) GetRequireLinearHistory() bool {
+	if p == nil || p.RequireLinearHistory == nil {
+		return false
+	}
+	return *p.RequireLinearHistory
+}
+
 // GetRestrictions returns the Restrictions field.
 func (p *ProtectionRequest) GetRestrictions() *BranchRestrictionsRequest {
 	if p == nil {
@@ -9188,6 +9244,14 @@ func (p *PushEventRepoOwner) GetName() string {
 	return *p.Name
 }
 
+// GetArchived returns the Archived field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetArchived() bool {
+	if p == nil || p.Archived == nil {
+		return false
+	}
+	return *p.Archived
+}
+
 // GetArchiveURL returns the ArchiveURL field if it's non-nil, zero value otherwise.
 func (p *PushEventRepository) GetArchiveURL() string {
 	if p == nil || p.ArchiveURL == nil {
@@ -9228,6 +9292,14 @@ func (p *PushEventRepository) GetDescription() string {
 	return *p.Description
 }
 
+// GetDisabled returns the Disabled field if it's non-nil, zero value otherwise.
+func (p *PushEventRepository) GetDisabled() bool {
+	if p == nil || p.Disabled == nil {
+		return false
+	}
+	return *p.Disabled
+}
+
 // GetFork returns the Fork field if it's non-nil, zero value otherwise.
 func (p *PushEventRepository) GetFork() bool {
 	if p == nil || p.Fork == nil {
@@ -9932,6 +10004,14 @@ func (r *Repository) GetDefaultBranch() string {
 	return *r.DefaultBranch
 }
 
+// GetDeleteBranchOnMerge returns the DeleteBranchOnMerge field if it's non-nil, zero value otherwise.
+func (r *Repository) GetDeleteBranchOnMerge() bool {
+	if r == nil || r.DeleteBranchOnMerge == nil {
+		return false
+	}
+	return *r.DeleteBranchOnMerge
+}
+
 // GetDeploymentsURL returns the DeploymentsURL field if it's non-nil, zero value otherwise.
 func (r *Repository) GetDeploymentsURL() string {
 	if r == nil || r.DeploymentsURL == nil {
diff --git a/github/github.go b/github/github.go
index 589cda53..794ee9c1 100644
--- a/github/github.go
+++ b/github/github.go
@@ -135,9 +135,6 @@ const (
 
 	// https://developer.github.com/changes/2019-10-03-multi-line-comments/
 	mediaTypeMultiLineCommentsPreview = "application/vnd.github.comfort-fade-preview+json"
-
-	// https://developer.github.com/v3/repos/#create-a-repository-dispatch-event
-	mediaTypeRepositoryDispatchPreview = "application/vnd.github.everest-preview+json"
 )
 
 // A Client manages communication with the GitHub API.
@@ -347,7 +344,7 @@ func (c *Client) NewRequest(method, urlStr string, body interface{}) (*http.Requ
 
 	var buf io.ReadWriter
 	if body != nil {
-		buf = new(bytes.Buffer)
+		buf = &bytes.Buffer{}
 		enc := json.NewEncoder(buf)
 		enc.SetEscapeHTML(false)
 		err := enc.Encode(body)
diff --git a/github/repos.go b/github/repos.go
index c695d8c0..133a9ef9 100644
--- a/github/repos.go
+++ b/github/repos.go
@@ -20,46 +20,47 @@ type RepositoriesService service
 
 // Repository represents a GitHub repository.
 type Repository struct {
-	ID                 *int64           `json:"id,omitempty"`
-	NodeID             *string          `json:"node_id,omitempty"`
-	Owner              *User            `json:"owner,omitempty"`
-	Name               *string          `json:"name,omitempty"`
-	FullName           *string          `json:"full_name,omitempty"`
-	Description        *string          `json:"description,omitempty"`
-	Homepage           *string          `json:"homepage,omitempty"`
-	CodeOfConduct      *CodeOfConduct   `json:"code_of_conduct,omitempty"`
-	DefaultBranch      *string          `json:"default_branch,omitempty"`
-	MasterBranch       *string          `json:"master_branch,omitempty"`
-	CreatedAt          *Timestamp       `json:"created_at,omitempty"`
-	PushedAt           *Timestamp       `json:"pushed_at,omitempty"`
-	UpdatedAt          *Timestamp       `json:"updated_at,omitempty"`
-	HTMLURL            *string          `json:"html_url,omitempty"`
-	CloneURL           *string          `json:"clone_url,omitempty"`
-	GitURL             *string          `json:"git_url,omitempty"`
-	MirrorURL          *string          `json:"mirror_url,omitempty"`
-	SSHURL             *string          `json:"ssh_url,omitempty"`
-	SVNURL             *string          `json:"svn_url,omitempty"`
-	Language           *string          `json:"language,omitempty"`
-	Fork               *bool            `json:"fork,omitempty"`
-	ForksCount         *int             `json:"forks_count,omitempty"`
-	NetworkCount       *int             `json:"network_count,omitempty"`
-	OpenIssuesCount    *int             `json:"open_issues_count,omitempty"`
-	StargazersCount    *int             `json:"stargazers_count,omitempty"`
-	SubscribersCount   *int             `json:"subscribers_count,omitempty"`
-	WatchersCount      *int             `json:"watchers_count,omitempty"`
-	Size               *int             `json:"size,omitempty"`
-	AutoInit           *bool            `json:"auto_init,omitempty"`
-	Parent             *Repository      `json:"parent,omitempty"`
-	Source             *Repository      `json:"source,omitempty"`
-	TemplateRepository *Repository      `json:"template_repository,omitempty"`
-	Organization       *Organization    `json:"organization,omitempty"`
-	Permissions        *map[string]bool `json:"permissions,omitempty"`
-	AllowRebaseMerge   *bool            `json:"allow_rebase_merge,omitempty"`
-	AllowSquashMerge   *bool            `json:"allow_squash_merge,omitempty"`
-	AllowMergeCommit   *bool            `json:"allow_merge_commit,omitempty"`
-	Topics             []string         `json:"topics,omitempty"`
-	Archived           *bool            `json:"archived,omitempty"`
-	Disabled           *bool            `json:"disabled,omitempty"`
+	ID                  *int64           `json:"id,omitempty"`
+	NodeID              *string          `json:"node_id,omitempty"`
+	Owner               *User            `json:"owner,omitempty"`
+	Name                *string          `json:"name,omitempty"`
+	FullName            *string          `json:"full_name,omitempty"`
+	Description         *string          `json:"description,omitempty"`
+	Homepage            *string          `json:"homepage,omitempty"`
+	CodeOfConduct       *CodeOfConduct   `json:"code_of_conduct,omitempty"`
+	DefaultBranch       *string          `json:"default_branch,omitempty"`
+	MasterBranch        *string          `json:"master_branch,omitempty"`
+	CreatedAt           *Timestamp       `json:"created_at,omitempty"`
+	PushedAt            *Timestamp       `json:"pushed_at,omitempty"`
+	UpdatedAt           *Timestamp       `json:"updated_at,omitempty"`
+	HTMLURL             *string          `json:"html_url,omitempty"`
+	CloneURL            *string          `json:"clone_url,omitempty"`
+	GitURL              *string          `json:"git_url,omitempty"`
+	MirrorURL           *string          `json:"mirror_url,omitempty"`
+	SSHURL              *string          `json:"ssh_url,omitempty"`
+	SVNURL              *string          `json:"svn_url,omitempty"`
+	Language            *string          `json:"language,omitempty"`
+	Fork                *bool            `json:"fork,omitempty"`
+	ForksCount          *int             `json:"forks_count,omitempty"`
+	NetworkCount        *int             `json:"network_count,omitempty"`
+	OpenIssuesCount     *int             `json:"open_issues_count,omitempty"`
+	StargazersCount     *int             `json:"stargazers_count,omitempty"`
+	SubscribersCount    *int             `json:"subscribers_count,omitempty"`
+	WatchersCount       *int             `json:"watchers_count,omitempty"`
+	Size                *int             `json:"size,omitempty"`
+	AutoInit            *bool            `json:"auto_init,omitempty"`
+	Parent              *Repository      `json:"parent,omitempty"`
+	Source              *Repository      `json:"source,omitempty"`
+	TemplateRepository  *Repository      `json:"template_repository,omitempty"`
+	Organization        *Organization    `json:"organization,omitempty"`
+	Permissions         *map[string]bool `json:"permissions,omitempty"`
+	AllowRebaseMerge    *bool            `json:"allow_rebase_merge,omitempty"`
+	AllowSquashMerge    *bool            `json:"allow_squash_merge,omitempty"`
+	AllowMergeCommit    *bool            `json:"allow_merge_commit,omitempty"`
+	DeleteBranchOnMerge *bool            `json:"delete_branch_on_merge,omitempty"`
+	Topics              []string         `json:"topics,omitempty"`
+	Archived            *bool            `json:"archived,omitempty"`
+	Disabled            *bool            `json:"disabled,omitempty"`
 
 	// Only provided when using RepositoriesService.Get while in preview
 	License *License `json:"license,omitempty"`
@@ -303,12 +304,13 @@ type createRepoRequest struct {
 	// Creating an organization repository. Required for non-owners.
 	TeamID *int64 `json:"team_id,omitempty"`
 
-	AutoInit          *bool   `json:"auto_init,omitempty"`
-	GitignoreTemplate *string `json:"gitignore_template,omitempty"`
-	LicenseTemplate   *string `json:"license_template,omitempty"`
-	AllowSquashMerge  *bool   `json:"allow_squash_merge,omitempty"`
-	AllowMergeCommit  *bool   `json:"allow_merge_commit,omitempty"`
-	AllowRebaseMerge  *bool   `json:"allow_rebase_merge,omitempty"`
+	AutoInit            *bool   `json:"auto_init,omitempty"`
+	GitignoreTemplate   *string `json:"gitignore_template,omitempty"`
+	LicenseTemplate     *string `json:"license_template,omitempty"`
+	AllowSquashMerge    *bool   `json:"allow_squash_merge,omitempty"`
+	AllowMergeCommit    *bool   `json:"allow_merge_commit,omitempty"`
+	AllowRebaseMerge    *bool   `json:"allow_rebase_merge,omitempty"`
+	DeleteBranchOnMerge *bool   `json:"delete_branch_on_merge,omitempty"`
 }
 
 // Create a new repository. If an organization is specified, the new
@@ -328,21 +330,22 @@ func (s *RepositoriesService) Create(ctx context.Context, org string, repo *Repo
 	}
 
 	repoReq := &createRepoRequest{
-		Name:              repo.Name,
-		Description:       repo.Description,
-		Homepage:          repo.Homepage,
-		Private:           repo.Private,
-		HasIssues:         repo.HasIssues,
-		HasProjects:       repo.HasProjects,
-		HasWiki:           repo.HasWiki,
-		IsTemplate:        repo.IsTemplate,
-		TeamID:            repo.TeamID,
-		AutoInit:          repo.AutoInit,
-		GitignoreTemplate: repo.GitignoreTemplate,
-		LicenseTemplate:   repo.LicenseTemplate,
-		AllowSquashMerge:  repo.AllowSquashMerge,
-		AllowMergeCommit:  repo.AllowMergeCommit,
-		AllowRebaseMerge:  repo.AllowRebaseMerge,
+		Name:                repo.Name,
+		Description:         repo.Description,
+		Homepage:            repo.Homepage,
+		Private:             repo.Private,
+		HasIssues:           repo.HasIssues,
+		HasProjects:         repo.HasProjects,
+		HasWiki:             repo.HasWiki,
+		IsTemplate:          repo.IsTemplate,
+		TeamID:              repo.TeamID,
+		AutoInit:            repo.AutoInit,
+		GitignoreTemplate:   repo.GitignoreTemplate,
+		LicenseTemplate:     repo.LicenseTemplate,
+		AllowSquashMerge:    repo.AllowSquashMerge,
+		AllowMergeCommit:    repo.AllowMergeCommit,
+		AllowRebaseMerge:    repo.AllowRebaseMerge,
+		DeleteBranchOnMerge: repo.DeleteBranchOnMerge,
 	}
 
 	req, err := s.client.NewRequest("POST", u, repoReq)
@@ -493,6 +496,7 @@ func (s *RepositoriesService) Delete(ctx context.Context, owner, repo string) (*
 type Contributor struct {
 	Login             *string `json:"login,omitempty"`
 	ID                *int64  `json:"id,omitempty"`
+	NodeID            *string `json:"node_id,omitempty"`
 	AvatarURL         *string `json:"avatar_url,omitempty"`
 	GravatarID        *string `json:"gravatar_id,omitempty"`
 	URL               *string `json:"url,omitempty"`
@@ -727,6 +731,9 @@ type Protection struct {
 	RequiredPullRequestReviews *PullRequestReviewsEnforcement `json:"required_pull_request_reviews"`
 	EnforceAdmins              *AdminEnforcement              `json:"enforce_admins"`
 	Restrictions               *BranchRestrictions            `json:"restrictions"`
+	RequireLinearHistory       *RequireLinearHistory          `json:"required_linear_history"`
+	AllowForcePushes           *AllowForcePushes              `json:"allow_force_pushes"`
+	AllowDeletions             *AllowDeletions                `json:"allow_deletions"`
 }
 
 // ProtectionRequest represents a request to create/edit a branch's protection.
@@ -735,6 +742,12 @@ type ProtectionRequest struct {
 	RequiredPullRequestReviews *PullRequestReviewsEnforcementRequest `json:"required_pull_request_reviews"`
 	EnforceAdmins              bool                                  `json:"enforce_admins"`
 	Restrictions               *BranchRestrictionsRequest            `json:"restrictions"`
+	// Enforces a linear commit Git history, which prevents anyone from pushing merge commits to a branch.
+	RequireLinearHistory *bool `json:"required_linear_history,omitempty"`
+	// Permits force pushes to the protected branch by anyone with write access to the repository.
+	AllowForcePushes *bool `json:"allow_force_pushes,omitempty"`
+	// Allows deletion of the protected branch by anyone with write access to the repository.
+	AllowDeletions *bool `json:"allow_deletions,omitempty"`
 }
 
 // RequiredStatusChecks represents the protection status of a individual branch.
@@ -797,6 +810,21 @@ type PullRequestReviewsEnforcementUpdate struct {
 	RequiredApprovingReviewCount int `json:"required_approving_review_count"`
 }
 
+// RequireLinearHistory represents the configuration to enfore branches with no merge commit.
+type RequireLinearHistory struct {
+	Enabled bool `json:"enabled"`
+}
+
+// AllowDeletions represents the configuration to accept deletion of protected branches.
+type AllowDeletions struct {
+	Enabled bool `json:"enabled"`
+}
+
+// AllowForcePushes represents the configuration to accept forced pushes on protected branches.
+type AllowForcePushes struct {
+	Enabled bool `json:"enabled"`
+}
+
 // AdminEnforcement represents the configuration to enforce required status checks for repository administrators.
 type AdminEnforcement struct {
 	URL     *string `json:"url,omitempty"`
@@ -1449,9 +1477,6 @@ func (s *RepositoriesService) Dispatch(ctx context.Context, owner, repo string,
 		return nil, nil, err
 	}
 
-	// TODO: remove custom Accept header when this API fully launches.
-	req.Header.Set("Accept", mediaTypeRepositoryDispatchPreview)
-
 	r := new(Repository)
 	resp, err := s.client.Do(ctx, req, r)
 	if err != nil {
diff --git a/github/repos_contents.go b/github/repos_contents.go
index eed0420a..66b556d2 100644
--- a/github/repos_contents.go
+++ b/github/repos_contents.go
@@ -12,6 +12,7 @@ import (
 	"context"
 	"encoding/base64"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 	"net/http"
@@ -76,6 +77,9 @@ func (r *RepositoryContent) GetContent() (string, error) {
 
 	switch encoding {
 	case "base64":
+		if r.Content == nil {
+			return "", errors.New("malformed response: base64 encoding of null content")
+		}
 		c, err := base64.StdEncoding.DecodeString(*r.Content)
 		return string(c), err
 	case "":


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index d89f367e..928ca47a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -4,66 +4,50 @@ env:
   GO111MODULE: on
 
 jobs:
-  linux:
+  test:
     strategy:
       matrix:
         go-version: [1.x, 1.12.x]
-    runs-on: ubuntu-latest
+        platform: [ubuntu-latest, windows-latest]
+    runs-on: ${{ matrix.platform }}
 
     steps:
     - uses: actions/setup-go@v1
       with:
         go-version: ${{ matrix.go-version }}
-    - uses: actions/checkout@v1
+    - uses: actions/checkout@v2
 
     - name: Cache go modules
-      uses: actions/cache@preview
+      uses: actions/cache@v1
       with:
         path: ~/go/pkg/mod
         key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
         restore-keys: ${{ runner.os }}-go-
 
     - name: Run go fmt
+      if: runner.os != 'Windows'
       run: diff -u <(echo -n) <(gofmt -d -s .)
 
     - name: Ensure go generate produces a zero diff
+      shell: bash
       run:  go generate -x ./... && git diff --exit-code; code=$?; git checkout -- .; (exit $code)
 
     - name: Run go vet
       run: go vet ./...
 
     - name: Run go test
-      run: go test -v -race -coverprofile=coverage.txt -covermode=atomic ./...
+      run: go test -v -race -coverprofile coverage.txt -covermode atomic ./...
 
     - name: Ensure integration tests build
       # don't actually run tests since they hit live GitHub API
       run: go test -v -tags=integration -run=^$ ./test/integration
 
     - name: Run scrape tests
-      run: cd scrape && go test ./...
+      run: |
+        cd scrape
+        go test ./...
 
     - name: Upload coverage to Codecov
-      env:
-        CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
-      run: bash <(curl -s https://codecov.io/bash)
-
-  # On Windows, just run the local tests.  Don't bother with checking gofmt, go
-  # vet, or uploading results to Codecov
-  windows:
-    strategy:
-      matrix:
-        go-version: [1.x, 1.12.x]
-    runs-on: windows-latest
-
-    steps:
-    - uses: actions/setup-go@v1
+      uses: codecov/codecov-action@v1
       with:
-        go-version: ${{ matrix.go-version }}
-    - uses: actions/checkout@v1
-    - name: Cache go modules
-      uses: actions/cache@preview
-      with:
-        path: ~/go/pkg/mod
-        key: ${{ runner.os }}-go-${{ hashFiles('go.sum') }}
-        restore-keys: ${{ runner.os }}-go-
-    - run: go test ./...
+        token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go
index 97a13ee2..b156cc1d 100644
--- a/github/github-stringify_test.go
+++ b/github/github-stringify_test.go
@@ -1212,94 +1212,95 @@ func TestRepoStatus_String(t *testing.T) {
 
 func TestRepository_String(t *testing.T) {
 	v := Repository{
-		ID:                 Int64(0),
-		NodeID:             String(""),
-		Owner:              &User{},
-		Name:               String(""),
-		FullName:           String(""),
-		Description:        String(""),
-		Homepage:           String(""),
-		CodeOfConduct:      &CodeOfConduct{},
-		DefaultBranch:      String(""),
-		MasterBranch:       String(""),
-		CreatedAt:          &Timestamp{},
-		PushedAt:           &Timestamp{},
-		UpdatedAt:          &Timestamp{},
-		HTMLURL:            String(""),
-		CloneURL:           String(""),
-		GitURL:             String(""),
-		MirrorURL:          String(""),
-		SSHURL:             String(""),
-		SVNURL:             String(""),
-		Language:           String(""),
-		Fork:               Bool(false),
-		ForksCount:         Int(0),
-		NetworkCount:       Int(0),
-		OpenIssuesCount:    Int(0),
-		StargazersCount:    Int(0),
-		SubscribersCount:   Int(0),
-		WatchersCount:      Int(0),
-		Size:               Int(0),
-		AutoInit:           Bool(false),
-		Parent:             &Repository{},
-		Source:             &Repository{},
-		TemplateRepository: &Repository{},
-		Organization:       &Organization{},
-		AllowRebaseMerge:   Bool(false),
-		AllowSquashMerge:   Bool(false),
-		AllowMergeCommit:   Bool(false),
-		Archived:           Bool(false),
-		Disabled:           Bool(false),
-		License:            &License{},
-		Private:            Bool(false),
-		HasIssues:          Bool(false),
-		HasWiki:            Bool(false),
-		HasPages:           Bool(false),
-		HasProjects:        Bool(false),
-		HasDownloads:       Bool(false),
-		IsTemplate:         Bool(false),
-		LicenseTemplate:    String(""),
-		GitignoreTemplate:  String(""),
-		TeamID:             Int64(0),
-		URL:                String(""),
-		ArchiveURL:         String(""),
-		AssigneesURL:       String(""),
-		BlobsURL:           String(""),
-		BranchesURL:        String(""),
-		CollaboratorsURL:   String(""),
-		CommentsURL:        String(""),
-		CommitsURL:         String(""),
-		CompareURL:         String(""),
-		ContentsURL:        String(""),
-		ContributorsURL:    String(""),
-		DeploymentsURL:     String(""),
-		DownloadsURL:       String(""),
-		EventsURL:          String(""),
-		ForksURL:           String(""),
-		GitCommitsURL:      String(""),
-		GitRefsURL:         String(""),
-		GitTagsURL:         String(""),
-		HooksURL:           String(""),
-		IssueCommentURL:    String(""),
-		IssueEventsURL:     String(""),
-		IssuesURL:          String(""),
-		KeysURL:            String(""),
-		LabelsURL:          String(""),
-		LanguagesURL:       String(""),
-		MergesURL:          String(""),
-		MilestonesURL:      String(""),
-		NotificationsURL:   String(""),
-		PullsURL:           String(""),
-		ReleasesURL:        String(""),
-		StargazersURL:      String(""),
-		StatusesURL:        String(""),
-		SubscribersURL:     String(""),
-		SubscriptionURL:    String(""),
-		TagsURL:            String(""),
-		TreesURL:           String(""),
-		TeamsURL:           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, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit: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:""}`
+		ID:                  Int64(0),
+		NodeID:              String(""),
+		Owner:               &User{},
+		Name:                String(""),
+		FullName:            String(""),
+		Description:         String(""),
+		Homepage:            String(""),
+		CodeOfConduct:       &CodeOfConduct{},
+		DefaultBranch:       String(""),
+		MasterBranch:        String(""),
+		CreatedAt:           &Timestamp{},
+		PushedAt:            &Timestamp{},
+		UpdatedAt:           &Timestamp{},
+		HTMLURL:             String(""),
+		CloneURL:            String(""),
+		GitURL:              String(""),
+		MirrorURL:           String(""),
+		SSHURL:              String(""),
+		SVNURL:              String(""),
+		Language:            String(""),
+		Fork:                Bool(false),
+		ForksCount:          Int(0),
+		NetworkCount:        Int(0),
+		OpenIssuesCount:     Int(0),
+		StargazersCount:     Int(0),
+		SubscribersCount:    Int(0),
+		WatchersCount:       Int(0),
+		Size:                Int(0),
+		AutoInit:            Bool(false),
+		Parent:              &Repository{},
+		Source:              &Repository{},
+		TemplateRepository:  &Repository{},
+		Organization:        &Organization{},
+		AllowRebaseMerge:    Bool(false),
+		AllowSquashMerge:    Bool(false),
+		AllowMergeCommit:    Bool(false),
+		DeleteBranchOnMerge: Bool(false),
+		Archived:            Bool(false),
+		Disabled:            Bool(false),
+		License:             &License{},
+		Private:             Bool(false),
+		HasIssues:           Bool(false),
+		HasWiki:             Bool(false),
+		HasPages:            Bool(false),
+		HasProjects:         Bool(false),
+		HasDownloads:        Bool(false),
+		IsTemplate:          Bool(false),
+		LicenseTemplate:     String(""),
+		GitignoreTemplate:   String(""),
+		TeamID:              Int64(0),
+		URL:                 String(""),
+		ArchiveURL:          String(""),
+		AssigneesURL:        String(""),
+		BlobsURL:            String(""),
+		BranchesURL:         String(""),
+		CollaboratorsURL:    String(""),
+		CommentsURL:         String(""),
+		CommitsURL:          String(""),
+		CompareURL:          String(""),
+		ContentsURL:         String(""),
+		ContributorsURL:     String(""),
+		DeploymentsURL:      String(""),
+		DownloadsURL:        String(""),
+		EventsURL:           String(""),
+		ForksURL:            String(""),
+		GitCommitsURL:       String(""),
+		GitRefsURL:          String(""),
+		GitTagsURL:          String(""),
+		HooksURL:            String(""),
+		IssueCommentURL:     String(""),
+		IssueEventsURL:      String(""),
+		IssuesURL:           String(""),
+		KeysURL:             String(""),
+		LabelsURL:           String(""),
+		LanguagesURL:        String(""),
+		MergesURL:           String(""),
+		MilestonesURL:       String(""),
+		NotificationsURL:    String(""),
+		PullsURL:            String(""),
+		ReleasesURL:         String(""),
+		StargazersURL:       String(""),
+		StatusesURL:         String(""),
+		SubscribersURL:      String(""),
+		SubscriptionURL:     String(""),
+		TagsURL:             String(""),
+		TreesURL:            String(""),
+		TeamsURL:            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, StargazersCount:0, SubscribersCount:0, WatchersCount:0, Size:0, AutoInit:false, Parent:github.Repository{}, Source:github.Repository{}, TemplateRepository:github.Repository{}, Organization:github.Organization{}, AllowRebaseMerge:false, AllowSquashMerge:false, AllowMergeCommit: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:""}`
 	if got := v.String(); got != want {
 		t.Errorf("Repository.String = %v, want %v", got, want)
 	}
diff --git a/github/repos_stats_test.go b/github/repos_stats_test.go
index 055504d7..4668cf18 100644
--- a/github/repos_stats_test.go
+++ b/github/repos_stats_test.go
@@ -25,7 +25,8 @@ func TestRepositoriesService_ListContributorsStats(t *testing.T) {
 [
   {
     "author": {
-      "id": 1
+			"id": 1,
+			"node_id": "nodeid-1"
     },
     "total": 135,
     "weeks": [
@@ -49,7 +50,8 @@ func TestRepositoriesService_ListContributorsStats(t *testing.T) {
 	want := []*ContributorStats{
 		{
 			Author: &Contributor{
-				ID: Int64(1),
+				ID:     Int64(1),
+				NodeID: String("nodeid-1"),
 			},
 			Total: Int(135),
 			Weeks: []WeeklyStats{
diff --git a/github/repos_test.go b/github/repos_test.go
index 1e48b7e2..d1c60cb0 100644
--- a/github/repos_test.go
+++ b/github/repos_test.go
@@ -1808,7 +1808,6 @@ func TestRepositoriesService_Dispatch(t *testing.T) {
 		json.NewDecoder(r.Body).Decode(&v)
 
 		testMethod(t, r, "POST")
-		testHeader(t, r, "Accept", mediaTypeRepositoryDispatchPreview)
 		if !reflect.DeepEqual(v, input) {
 			t.Errorf("Request body = %+v, want %+v", v, input)
 		}